diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index b206934179..bb62c00442 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -65,6 +65,7 @@ set(GAMEGUI mwgui/dialogue_history.cpp mwgui/window_base.cpp mwgui/stats_window.cpp + mwgui/messagebox.cpp ) source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI}) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 483a74eef5..5a05043ae6 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -155,6 +155,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) try { mEnvironment.mFrameDuration = evt.timeSinceLastFrame; + + // + mEnvironment.mWindowManager->onFrame(mEnvironment.mFrameDuration); // global scripts mEnvironment.mGlobalScripts->run (mEnvironment); diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp new file mode 100644 index 0000000000..76b35eab39 --- /dev/null +++ b/apps/openmw/mwgui/messagebox.cpp @@ -0,0 +1,160 @@ +#include "messagebox.hpp" + +using namespace MWGui; + +MessageBoxManager::MessageBoxManager (WindowManager *windowManager) +{ + mWindowManager = windowManager; + // defines + mMessageBoxSpeed = 0.1; +} + +void MessageBoxManager::onFrame (float frameDuration) +{ + std::vector::iterator it; + for(it = mTimers.begin(); it != mTimers.end();) + { + it->current += frameDuration; + if(it->current >= it->max) + { + removeMessageBox(it->messageBox); + it = mTimers.erase(it); + } + else + { + it++; + } + } +} + +void MessageBoxManager::createMessageBox (const std::string& message) +{ + std::cout << "MessageBox: " << message << std::endl; + + MessageBox *box = new MessageBox(*this, message); + + removeMessageBox(message.length()*mMessageBoxSpeed, box); + + mMessageBoxes.insert(mMessageBoxes.begin(), box); + int height = box->getHeight(); + std::vector::iterator it; + + int i = 0; + for(it = mMessageBoxes.begin()+1; it != mMessageBoxes.end(); ++it) + { + if(i == 2) { + delete (*it); + mMessageBoxes.erase(it); + break; + } + else { + (*it)->update(height); + height += (*it)->getHeight(); + i++; + } + } +} + +void MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector& buttons) +{ + std::cout << "interactive MessageBox: " << message << " - "; + std::copy (buttons.begin(), buttons.end(), std::ostream_iterator (std::cout, ", ")); + std::cout << std::endl; + + std::vector::iterator it = mMessageBoxes.begin(); + while(it != mMessageBoxes.end()) + { + delete (*it); + it = mMessageBoxes.erase(it); + } + mMessageBoxes.clear(); +} + +void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox) +{ + MessageBoxManagerTimer timer; + timer.current = 0; + timer.max = time; + timer.messageBox = msgbox; + + mTimers.insert(mTimers.end(), timer); +} + +bool MessageBoxManager::removeMessageBox (MessageBox *msgbox) +{ + std::vector::iterator it; + for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it) + { + if((*it) == msgbox) + { + delete (*it); + mMessageBoxes.erase(it); + return true; + } + } + return false; +} + +void MessageBoxManager::setMessageBoxSpeed (int speed) +{ + mMessageBoxSpeed = speed; +} + + + + +MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message) + : Layout("openmw_messagebox_layout.xml") + , mMessageBoxManager(parMessageBoxManager) + , cMessage(message) +{ + // defines + mFixedWidth = 300; + mBottomPadding = 20; + mNextBoxPadding = 20; + + getWidget(mMessageWidget, "message"); + + mMessageWidget->setOverflowToTheLeft(true); + mMessageWidget->addText(cMessage); + + MyGUI::IntSize size; + size.width = mFixedWidth; + size.height = 100; // dummy + + MyGUI::IntCoord coord; + coord.left = 10; // dummy + coord.top = 10; // dummy + + mMessageWidget->setSize(size); + + MyGUI::IntSize textSize = mMessageWidget->_getTextSize(); + size.height = mHeight = textSize.height + 20; // this is the padding between the text and the box + + mMainWidget->setSize(size); + size.width -= 5; // this is to center the text (see messagebox_layout.xml, Widget type="Edit" position="-2 -3 0 0") + mMessageWidget->setSize(size); + + update(0); +} + +void MessageBox::update (int height) +{ + MyGUI::IntSize gameWindowSize = mMessageBoxManager.mWindowManager->getGui()->getViewSize(); + MyGUI::IntCoord coord; + coord.left = (gameWindowSize.width - mFixedWidth)/2; + coord.top = (gameWindowSize.height - mHeight - height - mBottomPadding); + + MyGUI::IntSize size; + size.width = mFixedWidth; + size.height = mHeight; + + mMainWidget->setCoord(coord); + mMainWidget->setSize(size); + mMainWidget->setVisible(true); +} + +int MessageBox::getHeight () +{ + return mHeight+mNextBoxPadding; // 20 is the padding between this and the next MessageBox +} diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp new file mode 100644 index 0000000000..37c4db77ae --- /dev/null +++ b/apps/openmw/mwgui/messagebox.hpp @@ -0,0 +1,63 @@ +#ifndef MWGUI_MESSAGE_BOX_H +#define MWGUI_MESSAGE_BOX_H + +#include +#include + +#include "window_base.hpp" +#include "window_manager.hpp" + + +namespace MWGui +{ + + class MessageBoxManager; + class MessageBox; + + struct MessageBoxManagerTimer { + float current; + float max; + MessageBox *messageBox; + }; + + class MessageBoxManager + { + public: + MessageBoxManager (WindowManager* windowManager); + void onFrame (float frameDuration); + void createMessageBox (const std::string& message); + void createInteractiveMessageBox (const std::string& message, const std::vector& buttons); + + void removeMessageBox (float time, MessageBox *msgbox); + bool removeMessageBox (MessageBox *msgbox); + void setMessageBoxSpeed (int speed); + + WindowManager *mWindowManager; + + private: + std::vector mMessageBoxes; + std::vector mTimers; + float mMessageBoxSpeed; + }; + + class MessageBox : public OEngine::GUI::Layout + { + public: + MessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message); + void setMessage (const std::string& message); + int getHeight (); + void update (int height); + + protected: + MessageBoxManager& mMessageBoxManager; + int mHeight; + const std::string& cMessage; + MyGUI::EditPtr mMessageWidget; + int mFixedWidth; + int mBottomPadding; + int mNextBoxPadding; + }; + +} + +#endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 2d7f70ef86..8e9a14837d 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -8,6 +8,7 @@ #include "dialogue.hpp" #include "dialogue_history.hpp" #include "stats_window.hpp" +#include "messagebox.hpp" #include "../mwmechanics/mechanicsmanager.hpp" #include "../mwinput/inputmanager.hpp" @@ -60,6 +61,7 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment inventory = new InventoryWindow (); #endif console = new Console(w,h, environment, extensions); + mMessageBoxManager = new MessageBoxManager(this); // The HUD is always on hud->setVisible(true); @@ -82,6 +84,7 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment WindowManager::~WindowManager() { delete console; + delete mMessageBoxManager; delete hud; delete map; delete menu; @@ -446,13 +449,21 @@ void WindowManager::removeDialog(OEngine::GUI::Layout*dialog) void WindowManager::messageBox (const std::string& message, const std::vector& buttons) { - std::cout << "message box: " << message << std::endl; + /*std::cout << "message box: " << message << std::endl; if (!buttons.empty()) { std::cout << "buttons: "; std::copy (buttons.begin(), buttons.end(), std::ostream_iterator (std::cout, ", ")); std::cout << std::endl; + }*/ + if (buttons.empty()) + { + mMessageBoxManager->createMessageBox(message); + } + else + { + mMessageBoxManager->createInteractiveMessageBox(message, buttons); } } @@ -555,6 +566,11 @@ void WindowManager::onClassChoice(int _index) }; } +void WindowManager::onFrame (float frameDuration) +{ + mMessageBoxManager->onFrame(frameDuration); +} + namespace MWGui { diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index d3fbf3ea31..ebe115d309 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -62,6 +62,7 @@ namespace MWGui class CreateClassDialog; class BirthDialog; class ReviewDialog; + class MessageBoxManager; struct ClassPoint { @@ -84,6 +85,7 @@ namespace MWGui MapWindow *map; MainMenu *menu; StatsWindow *stats; + MessageBoxManager *mMessageBoxManager; #if 0 InventoryWindow *inventory; #endif @@ -245,8 +247,10 @@ namespace MWGui void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted. - + void messageBox (const std::string& message, const std::vector& buttons); + + void onFrame (float frameDuration); /** * Fetches a GMST string from the store, if there is no setting with the given diff --git a/extern/mygui_3.0.1/CMakeLists.txt b/extern/mygui_3.0.1/CMakeLists.txt index 8101ad91a7..36467733dd 100644 --- a/extern/mygui_3.0.1/CMakeLists.txt +++ b/extern/mygui_3.0.1/CMakeLists.txt @@ -68,6 +68,7 @@ configure_file("${SDIR}/openmw_progress.skin.xml" "${DDIR}/openmw_progress.skin. configure_file("${SDIR}/openmw_stats_window_layout.xml" "${DDIR}/openmw_stats_window_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_text.skin.xml" "${DDIR}/openmw_text.skin.xml" COPYONLY) configure_file("${SDIR}/openmw_windows.skin.xml" "${DDIR}/openmw_windows.skin.xml" COPYONLY) +configure_file("${SDIR}/openmw_messagebox_layout.xml" "${DDIR}/openmw_messagebox_layout.xml" COPYONLY) configure_file("${SDIR}/smallbars.png" "${DDIR}/smallbars.png" COPYONLY) configure_file("${SDIR}/transparent.png" "${DDIR}/transparent.png" COPYONLY) configure_file("${SDIR}/VeraMono.ttf" "${DDIR}/VeraMono.ttf" COPYONLY) diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_messagebox_layout.xml b/extern/mygui_3.0.1/openmw_resources/openmw_messagebox_layout.xml new file mode 100644 index 0000000000..aa1e00258d --- /dev/null +++ b/extern/mygui_3.0.1/openmw_resources/openmw_messagebox_layout.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + +