diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 28aae874f..f0745bbbe 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -7,6 +7,7 @@ MessageBoxManager::MessageBoxManager (WindowManager *windowManager) mWindowManager = windowManager; // defines mMessageBoxSpeed = 0.1; + mInterMessageBoxe = NULL; } void MessageBoxManager::onFrame (float frameDuration) @@ -46,6 +47,12 @@ void MessageBoxManager::onFrame (float frameDuration) it++; } } + + if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { + delete mInterMessageBoxe; + mInterMessageBoxe = NULL; + mWindowManager->setNextMode(GM_Game); + } } void MessageBoxManager::createMessageBox (const std::string& message) @@ -72,19 +79,24 @@ void MessageBoxManager::createMessageBox (const std::string& message) } } -void MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector& buttons) +bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector& buttons) { + if(mInterMessageBoxe != NULL) { + std::cout << "there is a MessageBox already" << std::endl; + return false; + } 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(); + mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons); + + return true; +} + +bool MessageBoxManager::isInteractiveMessageBox () +{ + return mInterMessageBoxe != NULL; } void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox) @@ -118,6 +130,16 @@ void MessageBoxManager::setMessageBoxSpeed (int speed) } +int MessageBoxManager::readPressedButton () +{ + if(mInterMessageBoxe != NULL) + { + return mInterMessageBoxe->readPressedButton(); + } + return -1; +} + + MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message) @@ -174,3 +196,199 @@ int MessageBox::getHeight () { return mHeight+mNextBoxPadding; // 20 is the padding between this and the next MessageBox } + + + +InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons) + : Layout("openmw_interactive_messagebox_layout.xml") + , mMessageBoxManager(parMessageBoxManager) + , mButtonPressed(-1) +{ + int fixedWidth = 500; + int textPadding = 10; // padding between text-widget and main-widget + int textButtonPadding = 20; // padding between the text-widget und the button-widget + int buttonLeftPadding = 10; // padding between the buttons if horizontal + int buttonTopPadding = 5; // ^-- if vertical + int buttonPadding = 5; // padding between button label and button itself + int buttonMainPadding = 10; // padding between buttons and bottom of the main widget + + mMarkedToDelete = false; + + + getWidget(mMessageWidget, "message"); + getWidget(mButtonsWidget, "buttons"); + + mMessageWidget->setOverflowToTheLeft(true); + mMessageWidget->addText(message); + + MyGUI::IntSize textSize = mMessageWidget->_getTextSize(); + + MyGUI::IntSize gameWindowSize = mMessageBoxManager.mWindowManager->getGui()->getViewSize(); + + int biggestButtonWidth = 0; + int buttonWidth = 0; + int buttonsWidth = 0; + int buttonHeight = 0; + MyGUI::IntCoord dummyCoord(0, 0, 0, 0); + + std::vector::const_iterator it; + for(it = buttons.begin(); it != buttons.end(); ++it) + { + MyGUI::ButtonPtr button = mButtonsWidget->createWidget( + MyGUI::WidgetStyle::Child, + std::string("MW_Button"), + dummyCoord, + MyGUI::Align::Default); + button->setCaption(*it); + + button->eventMouseButtonClick = MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed); + + mButtons.push_back(button); + + buttonWidth = button->_getTextSize().width + 2*buttonPadding + buttonLeftPadding; + buttonsWidth += buttonWidth; + buttonHeight = button->_getTextSize().height + 2*buttonPadding + buttonTopPadding; + + if(buttonWidth > biggestButtonWidth) + { + biggestButtonWidth = buttonWidth; + } + } + buttonsWidth += buttonLeftPadding; + + MyGUI::IntSize mainWidgetSize; + if(buttonsWidth < fixedWidth) + { + // on one line + std::cout << "on one line" << std::endl; + + if(textSize.width + 2*textPadding < buttonsWidth) + { + std::cout << "width = buttonsWidth" << std::endl; + mainWidgetSize.width = buttonsWidth; + } + else + { + mainWidgetSize.width = textSize.width + 3*textPadding; + } + mainWidgetSize.height = textSize.height + textButtonPadding + buttonHeight + buttonMainPadding; + + MyGUI::IntCoord absCoord; + absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2; + absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2; + + std::cout << "width " << mainWidgetSize.width << " height " << mainWidgetSize.height << std::endl; + std::cout << "left " << absCoord.left << " top " << absCoord.top << std::endl; + + mMainWidget->setCoord(absCoord); + mMainWidget->setSize(mainWidgetSize); + + + MyGUI::IntCoord messageWidgetCoord; + messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2; + messageWidgetCoord.top = textPadding; + mMessageWidget->setCoord(messageWidgetCoord); + + mMessageWidget->setSize(textSize); + + MyGUI::IntCoord buttonCord; + MyGUI::IntSize buttonSize(0, buttonHeight); + int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding; + + std::vector::const_iterator button; + for(button = mButtons.begin(); button != mButtons.end(); ++button) + { + buttonCord.left = left; + buttonCord.top = textSize.height + textButtonPadding; + + buttonSize.width = (*button)->_getTextSize().width + 2*buttonPadding; + buttonSize.height = (*button)->_getTextSize().height + 2*buttonPadding; + + (*button)->setCoord(buttonCord); + (*button)->setSize(buttonSize); + + left += buttonSize.width + buttonLeftPadding; + } + } + else + { + // among each other + + if(biggestButtonWidth > textSize.width) { + mainWidgetSize.width = biggestButtonWidth + buttonTopPadding; + } + else { + mainWidgetSize.width = textSize.width + 3*textPadding; + } + mainWidgetSize.height = textSize.height + 2*textPadding + textButtonPadding + buttonHeight * buttons.size() + buttonMainPadding; + + std::cout << "biggestButtonWidth " << biggestButtonWidth << " textSize.width " << textSize.width << std::endl; + std::cout << "width " << mainWidgetSize.width << " height " << mainWidgetSize.height << std::endl; + mMainWidget->setSize(mainWidgetSize); + + MyGUI::IntCoord absCoord; + absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2; + absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2; + + mMainWidget->setCoord(absCoord); + mMainWidget->setSize(mainWidgetSize); + + + MyGUI::IntCoord messageWidgetCoord; + messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2; + messageWidgetCoord.top = textPadding; + mMessageWidget->setCoord(messageWidgetCoord); + + mMessageWidget->setSize(textSize); + + MyGUI::IntCoord buttonCord; + MyGUI::IntSize buttonSize(0, buttonHeight); + + int top = textButtonPadding + buttonTopPadding + textSize.height; + + std::vector::const_iterator button; + for(button = mButtons.begin(); button != mButtons.end(); ++button) + { + buttonSize.width = (*button)->_getTextSize().width + buttonPadding*2; + buttonSize.height = (*button)->_getTextSize().height + buttonPadding*2; + + buttonCord.top = top; + buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/ + + (*button)->setCoord(buttonCord); + (*button)->setSize(buttonSize); + + top += buttonSize.height + 2*buttonTopPadding; + } + + } +} + +void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed) +{ + mMarkedToDelete = true; + int index = 0; + std::vector::const_iterator button; + for(button = mButtons.begin(); button != mButtons.end(); ++button) + { + if(*button == pressed) + { + mButtonPressed = index; + return; + } + index++; + } + std::cout << "Cant be possible :/" << std::endl; +} + +int InteractiveMessageBox::readPressedButton () +{ + int pressed = mButtonPressed; + mButtonPressed = -1; + return pressed; +} + + + + + diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index fe58a31c8..bf3307acc 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -11,6 +11,7 @@ namespace MWGui { + class InteractiveMessageBox; class MessageBoxManager; class MessageBox; @@ -26,16 +27,20 @@ namespace MWGui MessageBoxManager (WindowManager* windowManager); void onFrame (float frameDuration); void createMessageBox (const std::string& message); - void createInteractiveMessageBox (const std::string& message, const std::vector& buttons); + bool createInteractiveMessageBox (const std::string& message, const std::vector& buttons); + bool isInteractiveMessageBox (); void removeMessageBox (float time, MessageBox *msgbox); bool removeMessageBox (MessageBox *msgbox); void setMessageBoxSpeed (int speed); + int readPressedButton (); + WindowManager *mWindowManager; private: std::vector mMessageBoxes; + InteractiveMessageBox* mInterMessageBoxe; std::vector mTimers; float mMessageBoxSpeed; }; @@ -59,6 +64,25 @@ namespace MWGui int mBottomPadding; int mNextBoxPadding; }; + + class InteractiveMessageBox : public OEngine::GUI::Layout + { + public: + InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons); + void mousePressed (MyGUI::Widget* _widget); + int readPressedButton (); + + bool mMarkedToDelete; + + private: + MessageBoxManager& mMessageBoxManager; + MyGUI::EditPtr mMessageWidget; + MyGUI::WidgetPtr mButtonsWidget; + std::vector mButtons; + + int mTextButtonPadding; + int mButtonPressed; + }; } diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 313b097cf..b0dc14029 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -26,7 +26,10 @@ namespace MWGui GM_ClassGenerate, GM_ClassPick, GM_ClassCreate, - GM_Review + GM_Review, + + // interactive MessageBox + GM_InterMessageBox }; // Windows shown in inventory mode diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 8e9a14837..84e45859f 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -329,6 +329,14 @@ void WindowManager::updateVisible() dialogueWindow->open(); return; } + + if(mode == GM_InterMessageBox) + { + if(!mMessageBoxManager->isInteractiveMessageBox()) { + setGuiMode(GM_Game); + } + return; + } // Unsupported mode, switch back to game @@ -449,14 +457,6 @@ 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; - - 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); @@ -464,9 +464,15 @@ void WindowManager::messageBox (const std::string& message, const std::vectorcreateInteractiveMessageBox(message, buttons); + setGuiMode(GM_InterMessageBox); } } +int WindowManager::readPressedButton () +{ + return mMessageBoxManager->readPressedButton(); +} + const std::string &WindowManager::getGameSettingString(const std::string &id, const std::string &default_) { const ESM::GameSetting *setting = environment.mWorld->getStore().gameSettings.search(id); diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index ebe115d30..293bac601 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -250,6 +250,9 @@ namespace MWGui void messageBox (const std::string& message, const std::vector& buttons); + int readPressedButton (); + ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) + void onFrame (float frameDuration); /** diff --git a/extern/mygui_3.0.1/CMakeLists.txt b/extern/mygui_3.0.1/CMakeLists.txt index 36467733d..566fea773 100644 --- a/extern/mygui_3.0.1/CMakeLists.txt +++ b/extern/mygui_3.0.1/CMakeLists.txt @@ -69,6 +69,7 @@ configure_file("${SDIR}/openmw_stats_window_layout.xml" "${DDIR}/openmw_stats_wi 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}/openmw_interactive_messagebox_layout.xml" "${DDIR}/openmw_interactive_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_interactive_messagebox_layout.xml b/extern/mygui_3.0.1/openmw_resources/openmw_interactive_messagebox_layout.xml new file mode 100644 index 000000000..40c0787b8 --- /dev/null +++ b/extern/mygui_3.0.1/openmw_resources/openmw_interactive_messagebox_layout.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + 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 index fb4235ff1..890752db3 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_messagebox_layout.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_messagebox_layout.xml @@ -12,6 +12,8 @@ + +