/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL #include "glgui_notifier.h" #include "multi_line_text.h" #include "debug.h" namespace OrxGui { ObjectListDefinition(GLGuiNotifier); /** * @brief standard constructor */ GLGuiNotifier::GLGuiNotifier () { this->registerObject(this, GLGuiNotifier::_objectList); // Element2D and generals this->lineSpacing = 0; this->linesProcessed = 0; this->_fadeAge = 3.0; this->setHideAge(4.0); this->setDisplayLineCount(10); } /** * @brief standard deconstructor */ GLGuiNotifier::~GLGuiNotifier () { // delete the displayable Buffers /* while (!this->displayLines.empty()) { delete this->displayLines.front().text; this->displayLines.pop_front(); } while (!this->hiddenText.empty()) { delete this->hiddenText.top(); this->hiddenText.pop(); }*/ } /** * @brief push a message onto the notifier. * @param message the message to be pushed. * * @note it is not guaranteed, that the message is delivered instantaniously * The possibility may arise, that the DisplayLines are all in use, then one * has to wait until a line gets hidden, until a new one can be pushed to be * displayed. */ void GLGuiNotifier::pushNotifyMessage(const std::string& message) { if (!this->hiddenText.empty()) { DisplayLine dl; // put everything in here, and then display it // retrieve a Text. dl.text = this->hiddenText.top(); this->hiddenText.pop(); // setup Text dl.text->setBlending(1.0f); dl.text->setText(message); dl.text->setVisibility(true); dl.text->setRelCoor2D(this->calculateLinePosition(0)); dl.age = 0.0f; this->displayLines.push_front(dl); this->repositionText(); } else { // push it onto the List of messages we still need. this->inputBuffer.push_front(message); } } /** * @brief sets the Dipsplay Line Count of the Notifier. * @param coun the count of displayLines. */ void GLGuiNotifier::setDisplayLineCount(unsigned int count) { unsigned int currentCount = displayLines.size() + hiddenText.size(); for (unsigned int i = currentCount; i < count; ++i) { MultiLineText* text = new MultiLineText(); this->applyTextSettings(text); this->hiddenText.push(text); } bufferDisplaySize = count; } void GLGuiNotifier::setFadeAge(float fadeAge) { this->_fadeAge = fadeAge; this->_transformAge = hideAge() - this->fadeAge(); } void GLGuiNotifier::setHideAge(float hideAge) { this->_hideAge = hideAge; this->_transformAge = this->hideAge() - fadeAge(); } /** * @brief repositiones all the Texts to their position. */ void GLGuiNotifier::repositionText() { int linePos = -1; std::list::iterator textIt; for (textIt = this->displayLines.begin() ; textIt != this->displayLines.end(); ++textIt ) { linePos += (*textIt).text->getLineCount(); (*textIt).text->setRelCoorSoft2D(this->calculateLinePosition(linePos), 8); // printf("%f %f\n", (*textIt).text->getAbsCoor2D().x, (*textIt).text->getAbsCoor2D().y); } } /** * @brief applies the GLGuiNotifiers Settings to a single Text of the GLGuiNotifier. * @param text the Text to apply the settings to. */ void GLGuiNotifier::applyTextSettings(MultiLineText* text) { text->setSize(this->textSize()); text->setLineWidth( 300 ); text->setFont("fonts/final_frontier.ttf", (int)this->textSize()); text->setColor(this->foregroundColor() ); if (text->getParent2D() != this) text->setParent2D(this); } /** * @brief ticks the entire Notifier. * @param dt the time passed since the last Tick */ void GLGuiNotifier::tick(float dt) { std::list::iterator line; for (line = this->displayLines.begin() ; line != this->displayLines.end(); ++line ) { (*line).age+=dt; if ((*line).age > this->fadeAge()) { (*line).text->setBlending((hideAge() - (*line).age)/_transformAge); if ((*line).age > hideAge()) { std::list::iterator tmp = line; ++line; (*tmp).text->setVisibility(false); this->hiddenText.push((*tmp).text); this->displayLines.erase(tmp); if (!inputBuffer.empty()) { this->pushNotifyMessage(inputBuffer.back()); inputBuffer.pop_back(); } } } } } /** * displays the GLGuiNotifier */ void GLGuiNotifier::draw() const { // transform for alignment. // setting the Blending effects this->beginDraw(); this->background().select(); this->drawRect(this->backRect()); this->endDraw(); } /////////////////////// // HELPER FUNCTIONS // /////////////////////// /** * @brief calculates the position of a Buffer-Display Line * @param lineNumber the lineNumber from the bottom to calculate the position from * @returns the Position of the Line. */ Vector2D GLGuiNotifier::calculateLinePosition(unsigned int lineNumber) { return Vector2D(0.0f, (float)(textSize() + this->lineSpacing)*(float)((int)this->bufferDisplaySize - (int)lineNumber - (int)1)); } void GLGuiNotifier::resize() {} /** * @brief displays some nice output from the GLGuiNotifier */ void GLGuiNotifier::debug() const { PRINT(3)("Debugging output to console (not this shell)\n"); // if (this->pressedKey != SDLK_FIRST) // printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay); } }