#include "NachrichtenListe.h" #include #include #include #include "../../Global/Initialisierung.h" #include #include "../../Global/Variablen.h" #include #include #include #include #include #include typedef GSL::GSLDateiV *( *GetGSLDatei )( ); NLNachricht::NLNachricht( Schrift *zSchrift, Text *titel ) { 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 ); maxHöhe = 20; ref = 1; animation = 1; ausgewählt = 0; tickVal = 0; rend = 0; höhe = 0; } NLNachricht::~NLNachricht() { titel = (TextFeld *)titel->release(); close = (Knopf *)close->release(); rahmen->release(); } void NLNachricht::entfernen() { animation = 3; } void NLNachricht::setAusgewählt( bool ausgewählt ) { if( animation != 3 ) { this->ausgewählt = ausgewählt; if( ausgewählt ) animation = 2; else animation = 1; } } void NLNachricht::doMausEreignis( MausEreignis & me ) { if( animation != 3 ) { bool tmp = 0; if( me.my > höhe || !ausgewählt ) { tmp = me.verarbeitet; me.verarbeitet = 1; } char aktion = me.verarbeitet ? 2 : 0; close->doMausEreignis( me ); if( !aktion ) aktion = me.verarbeitet ? 1 : 0; if( me.my > höhe || !ausgewählt ) { me.verarbeitet = tmp; return; } if( me.id != ME_RLinks ) return; if( aktion == 1 ) entfernen(); } } bool NLNachricht::tick( double tickVal ) { rend |= close->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 NLNachricht::render( int y, Bild & zRObj ) { 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 ); close->render( zRObj ); zRObj.releaseDrawOptions(); zRObj.releaseDrawOptions(); } // contant bool NLNachricht::istAusgewählt() const { return ausgewählt; } int NLNachricht::getHeight() const { return höhe; } Text *NLNachricht::zTitel() const { return titel->zText(); } // Reference Counting NLNachricht *NLNachricht::getThis() { ref++; return this; } NLNachricht *NLNachricht::release() { ref--; if( !ref ) delete this; return 0; } SpielUpdateNachricht::SpielUpdateNachricht( Schrift * zSchrift, Text * titel, Text * nachricht, int dgID, std::function posAk, std::function negAk ) : NLNachricht( zSchrift, titel ) { Text *result = new Text( nachricht->getText() ); int län = nachricht->getLength(); char *txt = nachricht->getText(); int x = 0; int y = 0; Alphabet *tmp = zSchrift->getAlphabet( 12 ); TextRenderer rd( zSchrift->getThis() ); rd.setSchriftSize( 12 ); int zeilenHöhe = rd.getZeilenHeight() + rd.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(); nachricht = nachricht->release(); text = initTextFeld( 1, 22, 228, y, zSchrift, TextFeld::Style::Text, result->getText() ); result = result->release(); fortschritt = initFBalken( 5, y + 20, 215, 20, zSchrift, FBalken::Style::normal ); herunterladen = initKnopf( 10, 45 + y, 120, 20, zSchrift, Knopf::Style::Sichtbar, "herunterladen" ); abbrechen = initKnopf( 140, 45 + y, 80, 20, zSchrift, Knopf::Style::Sichtbar, "abbrechen" ); this->posAk = posAk; this->negAk = negAk; maxHöhe = 75 + y; update = new Update( zSchrift, (FBalken *)fortschritt->getThis(), dgID, [ this ]( bool ok ) { this->animation = 3; if( ok ) this->posAk(); else this->negAk(); } ); if( !updateH->add( (Update*)update->getThis() ) ) entfernen(); } SpielUpdateNachricht::~SpielUpdateNachricht() { text->release(); herunterladen->release(); abbrechen->release(); fortschritt->release(); updateH->remove( update->getDateiGruppe() ); update->release(); } // nicht constant void SpielUpdateNachricht::entfernen() { __super::entfernen(); negAk(); } void SpielUpdateNachricht::doMausEreignis( MausEreignis & me ) { __super::doMausEreignis( me ); if( animation != 3 ) { bool tmp = 0; if( me.my > höhe || !ausgewählt ) { tmp = me.verarbeitet; me.verarbeitet = 1; } char aktion = me.verarbeitet ? 3 : 0; herunterladen->doMausEreignis( me ); if( !aktion ) aktion = me.verarbeitet ? 1 : 0; abbrechen->doMausEreignis( me ); if( !aktion ) aktion = me.verarbeitet ? 2 : 0; if( me.my > höhe || !ausgewählt ) { me.verarbeitet = tmp; return; } if( me.id != ME_RLinks ) return; switch( aktion ) { case 1: // positiv update->herunterladen(); herunterladen->removeStyle( Knopf::Style::Erlaubt | Knopf::Style::Sichtbar ); break; case 2: // negativ update->abbrechen(); abbrechen->removeStyle( Knopf::Style::Erlaubt | Knopf::Style::Sichtbar ); break; } } } bool SpielUpdateNachricht::tick( double tickVal ) { rend |= herunterladen->tick( tickVal ); rend |= fortschritt->tick( tickVal ); rend |= abbrechen->tick( tickVal ); rend |= text->tick( tickVal ); return __super::tick( tickVal ); } void SpielUpdateNachricht::render( int y, Bild & zRObj ) { __super::render( y, zRObj ); int rbr = rahmen->getRBreite(); if( !zRObj.setDrawOptions( rbr, y + rbr, rahmen->getBreite() - rbr * 2, rahmen->getHeight() - rbr * 2 ) ) return; text->render( zRObj ); fortschritt->render( zRObj ); herunterladen->render( zRObj ); abbrechen->render( zRObj ); zRObj.releaseDrawOptions(); } // Inhalt der Nachricht Klasse aus NachrichtListe.h // Konstruktor Nachricht::Nachricht( Schrift * zSchrift, Text * titel, Text * nachricht, Text * positiv, Text * negativ, std::function posAk, std::function negAk ) : NLNachricht( zSchrift, titel ) { Text *result = new Text( nachricht->getText() ); int län = nachricht->getLength(); char *txt = nachricht->getText(); int x = 0; int y = 0; Alphabet *tmp = zSchrift->getAlphabet( 12 ); TextRenderer rd( zSchrift->getThis() ); rd.setSchriftSize( 12 ); int zeilenHöhe = rd.getZeilenHeight() + rd.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(); 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; this->posAk = posAk; this->negAk = negAk; maxHöhe = 50 + y; } // Destruktor Nachricht::~Nachricht() { text = (TextFeld *)text->release(); if( positiv ) positiv = (Knopf *)positiv->release(); if( negativ ) negativ = (Knopf *)negativ->release(); } void Nachricht::entfernen() { __super::entfernen(); negAk(); } void Nachricht::doMausEreignis( MausEreignis & me ) { __super::doMausEreignis( me ); if( animation != 3 ) { bool tmp = 0; if( me.my > höhe || !ausgewählt ) { tmp = me.verarbeitet; me.verarbeitet = 1; } char aktion = me.verarbeitet ? 3 : 0; if( positiv ) positiv->doMausEreignis( me ); if( !aktion ) aktion = me.verarbeitet ? 1 : 0; if( negativ ) negativ->doMausEreignis( me ); if( !aktion ) aktion = me.verarbeitet ? 2 : 0; if( me.my > höhe || !ausgewählt ) { me.verarbeitet = tmp; return; } if( me.id != ME_RLinks ) return; switch( aktion ) { case 1: // positiv __super::entfernen(); posAk(); break; case 2: // negativ __super::entfernen(); negAk(); break; } } } bool Nachricht::tick( double tickVal ) { rend |= positiv ? positiv->tick( tickVal ) : 0; rend |= negativ ? negativ->tick( tickVal ) : 0; rend |= text->tick( tickVal ); return __super::tick( tickVal ); } void Nachricht::render( int yPos, Bild & zRObj ) { __super::render( yPos, zRObj ); int rbr = rahmen->getRBreite(); if( !zRObj.setDrawOptions( rbr, yPos + rbr, rahmen->getBreite() - rbr * 2, rahmen->getHeight() - rbr * 2 ) ) return; text->render( zRObj ); if( positiv ) positiv->render( zRObj ); if( negativ ) negativ->render( zRObj ); zRObj.releaseDrawOptions(); } // Inhalt der NachrichtenListeObj Klasse aus NachrichtListe.h // Konstruktor NachrichtenListeObj::NachrichtenListeObj( Schrift * zSchrift ) : Zeichnung() { members = new RCArray< NLNachricht >(); 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 ); } // Destruktor NachrichtenListeObj::~NachrichtenListeObj() { schrift = schrift->release(); vsb = (VScrollBar *)vsb->release(); members = members->release(); } // nicht constant void NachrichtenListeObj::addNachricht( NLNachricht * nachricht ) { members->add( nachricht, anzahl ); anzahl++; rend = 1; } void NachrichtenListeObj::removeNachricht( NLNachricht * 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++ ) { NLNachricht *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++ ) { NLNachricht *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++ ) { NLNachricht *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++ ) { NLNachricht *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(); } // Inhalt der NachrichtenListe Klasse aus NachrichtListe.h // Konstruktor NachrichtenListe::NachrichtenListe( Schrift * zSchrift, Fenster * zNachLoginFenster ) { schrift = zSchrift->getThis(); 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->getThis() ); 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->getThis() ); nachrichtenListe = new NachrichtenListeObj( zSchrift ); nachrichtenListe->setPosition( 1, 21 ); nachrichtenListe->setSize( 248, bildschirmGröße.y - 122 ); fenster->addMember( nachrichtenListe->getThis() ); zNachLoginFenster->addMember( fenster->getThis() ); tickVal = 0; animation = 1; rend = 0; msgSound = 0; errSound = 0; HMODULE dll = Framework::getDLLRegister()->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 ) Framework::getDLLRegister()->releaseDLL( "GSL.dll" ); } ref = 1; } // Destruktor NachrichtenListe::~NachrichtenListe() { if( msgSound || errSound ) { if( msgSound ) { msgSound->stopSound(); msgSound->release(); } if( errSound ) { errSound->stopSound(); errSound->release(); } Framework::getDLLRegister()->releaseDLL( "GSL.dll" ); } überschrift = (TextFeld *)überschrift->release(); fenster = (Fenster *)fenster->release(); minMax = (Knopf *)minMax->release(); nachrichtenListe = (NachrichtenListeObj*)nachrichtenListe->release(); minimierenBild = minimierenBild->release(); maximierenBild = maximierenBild->release(); schrift->release(); } // nicht constant void NachrichtenListe::addNachricht( Text * titel, Text * nachricht, Text * positiv, Text * negativ, std::function posAk, std::function negAk ) { if( titel &&titel->hat( "Fehler" ) && errSound ) errSound->playSound(); else if( msgSound ) msgSound->playSound(); nachrichtenListe->addNachricht( new Nachricht( schrift, titel, nachricht, positiv, negativ, posAk, negAk ) ); } void NachrichtenListe::addNachricht( NLNachricht * nachricht ) { if( nachricht->zTitel() && nachricht->zTitel()->hat( "Fehler" ) && errSound ) errSound->playSound(); else if( msgSound ) msgSound->playSound(); nachrichtenListe->addNachricht( nachricht ); } void NachrichtenListe::removeNachricht( NLNachricht * 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() ); // TODO minMax->zToolTip()->setText( "Nachrichten Leiste maximieren." ); } else { animation = 1; minMax->setHintergrundBildZ( minimierenBild->getThis() ); // TODO 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 Schrift *NachrichtenListe::zSchrift() const { return schrift; } // 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 ); }