#include "NachrichtenListe.h" #include #include #include #include "../../Global/Initialisierung.h" #include #include "../../Global/Variablen.h" #include #include #include #include #include #include #include typedef GSL::GSLDateiV* (*GetGSLDatei)(); NLNachricht::NLNachricht(Text* titel) : ReferenceCounter() { rahmen = new LRahmen(); rahmen->setRamenBreite(1); rahmen->setFarbe(0xFFFFFFFF); this->titel = initTextFeld(1, 1, 208, 20, TextFeld::Style::Text | TextFeld::Style::Center, titel->getText()); titel->release(); close = initKnopf(208, 1, 20, 20, 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("data/client/bilder/chat.ltdb/entfernen.png"); close->setHintergrundBildZ(closeBild); initToolTip(close, "Nachricht ignorieren."); maxHöhe = 20; 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::doPublicMausEreignis(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->doPublicMausEreignis(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(); } SpielUpdateNachricht::SpielUpdateNachricht(Text* titel, Text* nachricht, int dgID, std::function posAk, std::function negAk) : NLNachricht(titel) { Text* result = new Text(nachricht->getText()); int län = nachricht->getLength(); const char* txt = nachricht->getText(); int x = 0; int y = 0; Alphabet* tmp = uiFactory.initParam.schrift->getAlphabet(12); TextRenderer rd(dynamic_cast(uiFactory.initParam.schrift->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->release(); } } y += zeilenHöhe; tmp->release(); nachricht->release(); text = initTextFeld(1, 22, 228, y, TextFeld::Style::Text, result->getText()); result->release(); fortschritt = initFBalken(5, y + 20, 215, 20, FBalken::Style::normal); herunterladen = initKnopf(10, 45 + y, 120, 20, Knopf::Style::Sichtbar, "herunterladen"); abbrechen = initKnopf(140, 45 + y, 80, 20, Knopf::Style::Sichtbar, "abbrechen"); this->posAk = posAk; this->negAk = negAk; maxHöhe = 75 + y; update = new Update(dynamic_cast(fortschritt->getThis()), dgID, [this](bool ok) { this->animation = 3; if (ok) this->posAk(); else this->negAk(); }); if (!updateH->add(dynamic_cast(update->getThis()))) entfernen(); } SpielUpdateNachricht::~SpielUpdateNachricht() { text->release(); herunterladen->release(); abbrechen->release(); fortschritt->release(); updateH->remove(update->getDateiGruppe()); update->abbrechen(); update->warteAufThread(10000); update->ende(); update->release(); } // nicht constant void SpielUpdateNachricht::entfernen() { __super::entfernen(); negAk(); } void SpielUpdateNachricht::doPublicMausEreignis(MausEreignis& me) { __super::doPublicMausEreignis(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->doPublicMausEreignis(me); if (!aktion) aktion = me.verarbeitet ? 1 : 0; abbrechen->doPublicMausEreignis(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(Text* titel, Text* nachricht, Text* positiv, Text* negativ, std::function posAk, std::function negAk) : NLNachricht(titel) { Text* result = new Text(nachricht->getText()); int län = nachricht->getLength(); const char* txt = nachricht->getText(); int x = 0; int y = 0; Alphabet* tmp = uiFactory.initParam.schrift->getAlphabet(12); TextRenderer rd(dynamic_cast(uiFactory.initParam.schrift->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->release(); } } y += zeilenHöhe; tmp->release(); nachricht->release(); text = initTextFeld(1, 22, 228, y, TextFeld::Style::Text, result->getText()); result->release(); if (positiv) { this->positiv = initKnopf(10, 20 + y, 100, 20, Knopf::Style::Sichtbar, positiv->getText()); positiv->release(); } else this->positiv = 0; if (negativ) { this->negativ = initKnopf(120, 20 + y, 100, 20, Knopf::Style::Sichtbar, negativ->getText()); 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::doPublicMausEreignis(MausEreignis& me) { __super::doPublicMausEreignis(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->doPublicMausEreignis(me); if (!aktion) aktion = me.verarbeitet ? 1 : 0; if (negativ) negativ->doPublicMausEreignis(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() : Zeichnung() { members = new RCArray< NLNachricht >(); vsb = new VScrollBar(); vsb->setKlickScroll(10); bildschirmGröße = uiFactory.initParam.bildschirm->getBackBufferSize(); vsb->update(0, bildschirmGröße.y - 122); anzahl = 0; gr = Punkt(250, bildschirmGröße.y - 122); } // Destruktor NachrichtenListeObj::~NachrichtenListeObj() { vsb = (VScrollBar*)vsb->release(); 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::doPublicMausEreignis(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->doPublicMausEreignis(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->doPublicMausEreignis(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(Fenster* zNachLoginFenster) : ReferenceCounter() { minimierenBild = bilder->get("data/client/bilder/chat.ltdb/minimieren.png"); maximierenBild = bilder->get("data/client/bilder/chat.ltdb/maximieren.png"); bildschirmGröße = uiFactory.initParam.bildschirm->getBackBufferSize(); fenster = initFenster(bildschirmGröße.x - 21, 100, 250, 22, Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::BodyHintergrund, ""); fenster->setKBgFarbe(0xFF000000); überschrift = initTextFeld(1, 1, 248, 20, TextFeld::Style::Text | TextFeld::Style::Center | TextFeld::Style::Sichtbar, "Nachrichten"); überschrift->setSchriftSize(15); fenster->addMember(dynamic_cast(überschrift->getThis())); minMax = initKnopf(1, 1, 20, 20, 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(dynamic_cast(minimierenBild->getThis())); initToolTip(minMax, "Nachrichten Leiste minimieren."); fenster->addMember(dynamic_cast(minMax->getThis())); nachrichtenListe = new NachrichtenListeObj(); nachrichtenListe->setPosition(1, 21); nachrichtenListe->setSize(248, bildschirmGröße.y - 122); fenster->addMember(dynamic_cast(nachrichtenListe->getThis())); zNachLoginFenster->addMember(dynamic_cast(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"); } } // 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->release(); maximierenBild->release(); schrift->release(); } // nicht constant void NachrichtenListe::addNachricht(Text* titel, Text* nachricht, Text* positiv, Text* negativ, std::function posAk, std::function negAk) { int sound = userOptions->wertExistiert("GUISound") ? (int)*userOptions->zWert("GUISound") : 100; if (titel && titel->hat("Fehler") && errSound) { errSound->setVolume((int)((sound / 100.0) * 0xFFFF), (int)((sound / 100.0) * 0xFFFF)); errSound->playSound(); } else if (msgSound) { msgSound->setVolume((int)((sound / 100.0) * 0xFFFF), (int)((sound / 100.0) * 0xFFFF)); msgSound->playSound(); } nachrichtenListe->addNachricht(new Nachricht(titel, nachricht, positiv, negativ, posAk, negAk)); } void NachrichtenListe::addNachricht(NLNachricht* nachricht) { int sound = userOptions->wertExistiert("GUISound") ? (int)*userOptions->zWert("GUISound") : 100; if (nachricht->zTitel() && nachricht->zTitel()->hat("Fehler") && errSound) { errSound->setVolume((int)((sound / 100.0) * 0xFFFF), (int)((sound / 100.0) * 0xFFFF)); errSound->playSound(); } else if (msgSound) { msgSound->setVolume((int)((sound / 100.0) * 0xFFFF), (int)((sound / 100.0) * 0xFFFF)); 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(dynamic_cast(maximierenBild->getThis())); // TODO minMax->zToolTip()->setText( "Nachrichten Leiste maximieren." ); } else { animation = 1; minMax->setHintergrundBildZ(dynamic_cast(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; } // Nachrichten bool NachrichtenListeMinMaxME(void* p, void* obj, MausEreignis me) { return ((NachrichtenListe*)p)->druckMinMax(me); }