#include "NachrichtenListe.h" #include #include #include #include "../../Global/Initialisierung.h" #include #include "../../Global/Variablen.h" #include #include #include #include #include typedef GSL::GSLDateiV *( *GetGSLDatei )( ); // Inhalt der Nachricht Klasse aus NachrichtListe.h // Konstruktor Nachricht::Nachricht( Schrift *zSchrift, Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param ) { rahmen = new LRahmen(); rahmen->setRamenBreite( 1 ); rahmen->setFarbe( 0xFFFFFFFF ); this->titel = initTextFeld( 1, 1, 208, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, titel->getText() ); titel = titel->release(); close = initKnopf( 208, 1, 20, 20, 0, 0, "" ); close->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer ); Bild *closeBild = bilder->get( "chat.ltdb/entfernen.png" ); if( !closeBild ) { LTDBDatei *datei = new LTDBDatei(); datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) ); datei->leseDaten( 0 ); closeBild = datei->laden( 0, new Text( "entfernen.png" ) ); datei->release(); bilder->add( "chat.ltdb/entfernen.png", closeBild->getThis() ); } close->setHintergrundBildZ( closeBild ); initToolTip( close, "Nachricht ignorieren.", zSchrift->getThis(), hauptScreen ); Text *result = new Text( nachricht->getText() ); int län = nachricht->getLength(); char *txt = nachricht->getText(); int x = 0; int y = 0; zSchrift->lock(); zSchrift->setSchriftSize( 12 ); Alphabet *tmp = zSchrift->getAlphabet( 12 ); int zeilenHöhe = tmp->getZeilenHeight() + tmp->getZeilenAbstand(); int lastPos = -1; for( int i = 0; i < län; i++ ) { char c = txt[ i ]; if( c == ' ' ) { lastPos = i; x += 6; continue; } if( c == '\n' ) { x = 0; y += zeilenHöhe; lastPos = -1; continue; } Buchstabe *b = tmp->getBuchstabe( (unsigned)c ); if( b ) { x += b->getBreite(); if( x > 228 && lastPos > -1 ) { result->ersetzen( lastPos, lastPos + 1, "\n" ); x = 0; y += zeilenHöhe; i = lastPos; lastPos = -1; } b = b->release(); } } y += zeilenHöhe; tmp = tmp->release(); zSchrift->unlock(); nachricht = nachricht->release(); text = initTextFeld( 1, 22, 228, y, zSchrift, TextFeld::Style::Text, result->getText() ); result = result->release(); if( positiv ) { this->positiv = initKnopf( 10, 20 + y, 100, 20, zSchrift, Knopf::Style::Sichtbar, positiv->getText() ); positiv = positiv->release(); } else this->positiv = 0; if( negativ ) { this->negativ = initKnopf( 120, 20 + y, 100, 20, zSchrift, Knopf::Style::Sichtbar, negativ->getText() ); negativ = negativ->release(); } else this->negativ = 0; typ = type; this->param = param; maxHöhe = 50 + y; ref = 1; animation = 1; ausgewählt = 0; tickVal = 0; rend = 0; höhe = 0; } // Destruktor Nachricht::~Nachricht() { switch( typ ) { case 1: delete ( (int*)param ); break; case 2: delete ( (int*)param ); break; case 3: delete ( (SpielEinladungParam*)param ); break; case 4: delete ( (ChatroomEinladungParam*)param ); break; } titel = titel->release(); text = text->release(); close = close->release(); if( positiv ) positiv = positiv->release(); if( negativ ) negativ = negativ->release(); rahmen = rahmen->release(); } // nicht constant void Nachricht::entfernen() { animation = 3; } void Nachricht::setAusgewählt( bool ausw ) { if( animation != 3 ) { ausgewählt = ausw; if( ausw ) animation = 2; else animation = 1; } } void Nachricht::doMausEreignis( MausEreignis &me ) { if( animation != 3 ) { bool tmp = 0; if( me.my > höhe || !ausgewählt ) { tmp = me.verarbeitet; me.verarbeitet = 1; } char aktion = 0; if( positiv ) positiv->doMausEreignis( me ); aktion = me.verarbeitet ? 1 : 0; if( negativ ) negativ->doMausEreignis( me ); if( !aktion ) aktion = me.verarbeitet ? 2 : 0; close->doMausEreignis( me ); if( !aktion ) aktion = me.verarbeitet ? 3 : 0; if( me.my > höhe || !ausgewählt ) { me.verarbeitet = tmp; return; } if( me.id != ME_RLinks ) return; if( aktion ) animation = 3; switch( aktion ) { case 1: // positiv switch( typ ) { case 1: // freund entfernen chatKlient->freundschaftBeenden( *( (int*)param ) ); break; case 2: // freund einladung chatKlient->freundesAnfrageBeantworten( *( (int*)param ), 1 ); break; case 3: // spiel einladung if( 1 ) { int karteId = infoKlient->getGruppenKarteId( ( (SpielEinladungParam*)param )->gruppeId ); int spielArt = infoKlient->getSpielId( karteId ); KSGTDatei *dgt = new KSGTDatei( "data/dg.ksgt" ); dgt->laden(); bool sak = 0; int dgSId = infoKlient->getDateiGruppeIdVonSpiel( spielArt ); bool sgf = 0; for( int i = 0; i < dgt->getZeilenAnzahl(); i++ ) { if( dgt->zFeld( i, 0 ) && TextZuInt( dgt->zFeld( i, 0 )->getText(), 10 ) == dgSId ) { sgf = 1; int lv = dgt->zFeld( i, 2 ) ? TextZuInt( dgt->zFeld( i, 2 )->getText(), 10 ) : 0; int ov = infoKlient->getSpielVersion( spielArt ); if( lv == ov ) { sak = 1; break; } } } dgt->release(); if( !sak ) { anmeldungKlient->gruppeEinladungAblehnen( ( (SpielEinladungParam*)param )->gruppeId ); nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Deine Spiel Version ist nicht aktuell. Sie wird beim nächsten Spielstart aktualisiert." ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 ); if( !sgf ) { Text *pfad = infoKlient->getDateiGruppePfad( dgSId ); Text *idT = new Text(); idT->append( dgSId ); if( pfad ) { KSGTDatei *dg = new KSGTDatei( "data/dg.ksgt" ); dg->laden(); RCArray< Text > *zeile = new RCArray< Text >(); zeile->add( idT ); zeile->add( pfad ); zeile->add( new Text( "0" ) ); zeile->add( new Text( "0" ) ); dg->addZeile( 4, zeile ); zeile->release(); dg->speichern(); dg->release(); } else idT->release(); } } else { MausEreignis me; me.verarbeitet = 0; me.id = ME_RLinks; nachLogin->zTitelLeiste()->druckSpielen( me ); Array< int > *spieler = new Array< int >(); int anzahl = 0; if( anmeldungKlient->gruppeBetreten( ( (SpielEinladungParam*)param )->gruppeId, spieler, &anzahl ) ) { nachLogin->zSpielenFenster()->gruppeBetreten( ( (SpielEinladungParam*)param )->gruppeId ); for( int i = 0; i < anzahl; i++ ) nachLogin->zSpielenFenster()->spielerBetrittGruppe( ( (SpielEinladungParam*)param )->gruppeId, spieler->hat( i ) ? spieler->get( i ) : 0 ); } else nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 ); } } break; case 4: // chatroom einladung nachLogin->zChatLeiste()->addChat( 0, ( (ChatroomEinladungParam*)param )->chatroomId ); chatKlient->chatroomBetreten( ( (ChatroomEinladungParam*)param )->chatroomId ); break; case 5: // logout ::aktion = 3; break; case 6: // close nachLogin->zChatLeiste()->removeAll(); loginKlient->logout(); PostQuitMessage( 0 ); break; } break; case 2: // schließn case 3: // negativ switch( typ ) { case 2: chatKlient->freundesAnfrageBeantworten( *( (int*)param ), 0 ); break; case 3: // spiel einladung anmeldungKlient->gruppeEinladungAblehnen( ( (SpielEinladungParam*)param )->gruppeId ); break; case 4: chatKlient->chatroomEinladungAblehnen( ( (ChatroomEinladungParam*)param )->vonAccount, ( (ChatroomEinladungParam*)param )->chatroomId ); break; } break; } } } bool Nachricht::tick( double tickVal ) { rend |= close->tick( tickVal ); rend |= positiv ? positiv->tick( tickVal ) : 0; rend |= negativ ? negativ->tick( tickVal ) : 0; rend |= text->tick( tickVal ); if( !animation ) { bool ret = rend; rend = 0; return ret; } this->tickVal += tickVal * 100; int val = ( int )this->tickVal; if( val < 1 ) { bool ret = rend; rend = 0; return ret; } if( val > 4 ) val = 4; this->tickVal -= val; switch( animation ) { case 1: if( höhe != 20 ) { if( höhe > 20 ) { höhe -= val; if( höhe < 20 ) höhe = 20; } else { höhe += val; if( höhe > 20 ) höhe = 20; } rend = 1; } else animation = 0; break; case 2: if( höhe != maxHöhe ) { höhe += val; if( höhe > maxHöhe ) höhe = maxHöhe; rend = 1; } else animation = 0; break; case 3: höhe -= val; if( höhe <= 0 ) { nachLogin->zNachrichtenListe()->removeNachricht( this ); // delete this return 1; } rend = 1; break; } bool ret = rend; rend = 0; return ret; } void Nachricht::render( int yPos, Bild &zRObj ) { int y = yPos; int br = 228; int hö = höhe; if( !zRObj.setDrawOptions( 0, y, br, hö ) ) return; rahmen->setSize( br, hö ); rahmen->render( zRObj ); int rbr = rahmen->getRBreite(); if( !zRObj.setDrawOptions( rbr, rbr, br - rbr * 2, hö - rbr * 2 ) ) { zRObj.releaseDrawOptions(); return; } titel->render( zRObj ); text->render( zRObj ); close->render( zRObj ); if( positiv ) positiv->render( zRObj ); if( negativ ) negativ->render( zRObj ); zRObj.releaseDrawOptions(); zRObj.releaseDrawOptions(); } // contant bool Nachricht::istAusgewählt() const { return ausgewählt; } int Nachricht::getHeight() const { return höhe; } // Reference Counting Nachricht *Nachricht::getThis() { ref++; return this; } Nachricht *Nachricht::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der NachrichtenListeObj Klasse aus NachrichtListe.h // Konstruktor NachrichtenListeObj::NachrichtenListeObj( Schrift *zSchrift ) : Zeichnung() { members = new RCArray< Nachricht >(); schrift = zSchrift->getThis(); vsb = new VScrollBar(); vsb->setKlickScroll( 10 ); bildschirmGröße = BildschirmGröße(); vsb->update( 0, bildschirmGröße.y - 122 ); anzahl = 0; gr = Punkt( 250, bildschirmGröße.y - 122 ); ref = 1; } // Destruktor NachrichtenListeObj::~NachrichtenListeObj() { schrift = schrift->release(); vsb = (VScrollBar*)vsb->release(); members = members->release(); } // nicht constant void NachrichtenListeObj::addNachricht( Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param ) { Nachricht *tmp = new Nachricht( schrift, titel, nachricht, positiv, negativ, type, param ); members->add( tmp, anzahl ); anzahl++; rend = 1; } void NachrichtenListeObj::removeNachricht( Nachricht *zNachricht ) { for( int i = 0; i < anzahl; i++ ) { if( members->z( i ) == zNachricht ) { members->remove( i ); anzahl--; rend = 1; break; } } } void NachrichtenListeObj::removeAll() { lockZeichnung(); members->leeren(); anzahl = 0; rend = 1; unlockZeichnung(); } bool NachrichtenListeObj::tick( double tickVal ) { lockZeichnung(); rend |= vsb->getRend(); rend |= nachLogin->zNachrichtenListe()->tick( tickVal ); for( int i = 0; i < anzahl; i++ ) { Nachricht *tmp = members->z( i ); if( tmp ) rend |= tmp->tick( tickVal ); } unlockZeichnung(); bool ret = rend; rend = 0; return ret; } void NachrichtenListeObj::doMausEreignis( MausEreignis &me ) { lockZeichnung(); int my = me.my; me.my -= 20; if( me.mx <= 229 && me.mx > 0 && me.my >= 0 ) { me.my += vsb->getScroll(); for( int i = 0; i < anzahl; i++ ) { Nachricht *tmp = members->z( i ); if( tmp ) { if( me.my > 0 && me.my < tmp->getHeight() ) tmp->setAusgewählt( 1 ); else tmp->setAusgewählt( 0 ); tmp->doMausEreignis( me ); me.my -= tmp->getHeight(); } } me.my -= vsb->getScroll(); } else { me.my += vsb->getScroll(); for( int i = 0; i < anzahl; i++ ) { Nachricht *tmp = members->z( i ); if( tmp ) { tmp->setAusgewählt( 0 ); tmp->doMausEreignis( me ); me.my -= tmp->getHeight(); } } me.my -= vsb->getScroll(); } me.my = my; vsb->doMausMessage( 229, 20, 20, bildschirmGröße.y - 122, me ); unlockZeichnung(); } void NachrichtenListeObj::render( Bild &zrObj ) { lockZeichnung(); int x = pos.x; int y = pos.y; int br = gr.x; int hö = gr.y; if( !zrObj.setDrawOptions( x, y, br, hö ) ) { unlockZeichnung(); return; } int höhe = 0; for( int i = 0; i < anzahl; i++ ) { Nachricht *tmp = members->z( i ); tmp->render( höhe - ( vsb ? vsb->getScroll() : 0 ), zrObj ); höhe += tmp->getHeight(); } if( vsb ) { vsb->update( höhe, bildschirmGröße.y - 122 ); vsb->render( 229, 0, 20, bildschirmGröße.y - 122, zrObj ); } zrObj.releaseDrawOptions(); unlockZeichnung(); } // contant // Reference Counting NachrichtenListeObj *NachrichtenListeObj::getThis() { ref++; return this; } NachrichtenListeObj *NachrichtenListeObj::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der NachrichtenListe Klasse aus NachrichtListe.h // Konstruktor NachrichtenListe::NachrichtenListe( Schrift *zSchrift, Fenster *zNachLoginFenster ) { minimierenBild = bilder->get( "chat.ltdb/minimieren.png" ); if( !minimierenBild ) { LTDBDatei *datei = new LTDBDatei(); datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) ); datei->leseDaten( 0 ); minimierenBild = datei->laden( 0, new Text( "minimieren.png" ) ); datei->release(); bilder->add( "chat.ltdb/minimieren.png", minimierenBild->getThis() ); } maximierenBild = bilder->get( "chat.ltdb/maximieren.png" ); if( !maximierenBild ) { LTDBDatei *datei = new LTDBDatei(); datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) ); datei->leseDaten( 0 ); maximierenBild = datei->laden( 0, new Text( "maximieren.png" ) ); datei->release(); bilder->add( "chat.ltdb/maximieren.png", maximierenBild->getThis() ); } bildschirmGröße = BildschirmGröße(); fenster = initFenster( bildschirmGröße.x - 21, 100, 250, 22, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::BodyHintergrund, "" ); fenster->setKBgFarbe( 0xFF000000 ); überschrift = initTextFeld( 1, 1, 248, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center | TextFeld::Style::Sichtbar, "Nachrichten" ); überschrift->setSchriftSize( 15 ); fenster->addMember( überschrift ); minMax = initKnopf( 1, 1, 20, 20, 0, 0, "" ); minMax->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer ); minMax->setMausEreignisParameter( this ); minMax->setMausEreignis( NachrichtenListeMinMaxME ); minMax->setHintergrundBildZ( minimierenBild->getThis() ); initToolTip( minMax, "Nachrichten Leiste minimieren.", zSchrift->getThis(), hauptScreen ); fenster->addMember( minMax ); nachrichtenListe = new NachrichtenListeObj( zSchrift ); nachrichtenListe->setPosition( 1, 21 ); nachrichtenListe->setSize( 248, bildschirmGröße.y - 122 ); fenster->addMember( nachrichtenListe ); zNachLoginFenster->addMember( fenster ); tickVal = 0; animation = 1; rend = 0; msgSound = 0; errSound = 0; HMODULE dll = dllDateien->ladeDLL( "GSL.dll", "data/bin/GSL.dll" ); if( dll ) { GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( dll, "getGSLDatei" ); if( getGSLDatei ) { GSL::GSLDateiV *sDat = getGSLDatei(); sDat->setDatei( "data/sounds/popup.gsl" ); sDat->leseDaten(); msgSound = sDat->getSound( "info.wav" ); errSound = sDat->getSound( "error.wav" ); sDat->release(); if( msgSound ) msgSound->setVolume( 0xFFFF, 0xFFFF ); if( errSound ) errSound->setVolume( 0xFFFF, 0xFFFF ); } if( !msgSound && !errSound ) dllDateien->releaseDLL( "GSL.dll" ); } ref = 1; } // Destruktor NachrichtenListe::~NachrichtenListe() { if( msgSound || errSound ) { if( msgSound ) { msgSound->stopSound(); msgSound->release(); } if( errSound ) { errSound->stopSound(); errSound->release(); } dllDateien->releaseDLL( "GSL.dll" ); } überschrift = überschrift->release(); fenster = fenster->release(); minMax = minMax->release(); nachrichtenListe = nachrichtenListe->release(); minimierenBild = minimierenBild->release(); maximierenBild = maximierenBild->release(); } // nicht constant void NachrichtenListe::addNachricht( Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param ) { if( titel && titel->hat( "Fehler" ) && errSound ) errSound->playSound(); else if( msgSound ) msgSound->playSound(); nachrichtenListe->addNachricht( titel, nachricht, positiv, negativ, type, param ); } void NachrichtenListe::removeNachricht( Nachricht *zNachricht ) { nachrichtenListe->removeNachricht( zNachricht ); } void NachrichtenListe::removeAll() { nachrichtenListe->removeAll(); } bool NachrichtenListe::druckMinMax( MausEreignis &me ) { if( me.id == ME_RLinks ) { if( minMax->zHintergrundBild() == minimierenBild ) { animation = 2; minMax->setHintergrundBildZ( maximierenBild->getThis() ); minMax->zToolTip()->setText( "Nachrichten Leiste maximieren." ); } else { animation = 1; minMax->setHintergrundBildZ( minimierenBild->getThis() ); minMax->zToolTip()->setText( "Nachrichten Leiste minimieren." ); } } return 1; } bool NachrichtenListe::tick( double tickVal ) { if( !animation ) { bool ret = rend; rend = 0; return ret; } this->tickVal += tickVal * 400; int val = ( int )this->tickVal; if( val < 1 ) { bool ret = rend; rend = 0; return ret; } if( val > 14 ) val = 14; this->tickVal -= val; switch( animation ) { case 1: // maximieren if( fenster->getX() > bildschirmGröße.x - 250 ) { fenster->setPosition( fenster->getX() - val, fenster->getY() ); minMax->setPosition( minMax->getX() + val, minMax->getY() ); if( fenster->getX() < bildschirmGröße.x - 250 ) { fenster->setPosition( bildschirmGröße.x - 250, fenster->getY() ); minMax->setPosition( 229, minMax->getY() ); } rend = 1; } else if( fenster->getHeight() < bildschirmGröße.y - 100 ) { fenster->setSize( fenster->getBreite(), fenster->getHeight() + val ); if( fenster->getHeight() >= bildschirmGröße.y - 100 ) { fenster->setSize( fenster->getBreite(), bildschirmGröße.y - 100 ); animation = 0; } rend = 1; } break; case 2: // minimieren if( fenster->getHeight() > 22 ) { fenster->setSize( fenster->getBreite(), fenster->getHeight() - val ); if( fenster->getHeight() < 22 ) fenster->setSize( fenster->getBreite(), 22 ); rend = 1; } else if( fenster->getX() < bildschirmGröße.x - 21 ) { minMax->setPosition( minMax->getX() - val, minMax->getY() ); fenster->setPosition( fenster->getX() + val, fenster->getY() ); if( fenster->getX() >= bildschirmGröße.x - 21 ) { minMax->setPosition( 1, minMax->getY() ); fenster->setPosition( bildschirmGröße.x - 21, fenster->getY() ); animation = 0; } rend = 1; } break; } bool ret = rend; rend = 0; return ret; } // contant // Reference Counting NachrichtenListe *NachrichtenListe::getThis() { ref++; return this; } NachrichtenListe *NachrichtenListe::release() { ref--; if( !ref ) delete this; return 0; } // Nachrichten bool NachrichtenListeMinMaxME( void *p, void *obj, MausEreignis me ) { return ( (NachrichtenListe*)p )->druckMinMax( me ); }