#include "messagebox.hpp" using namespace MWGui; MessageBoxManager::MessageBoxManager (WindowManager *windowManager) { mWindowManager = windowManager; // defines mMessageBoxSpeed = 0.1; mInterMessageBoxe = NULL; } void MessageBoxManager::onFrame (float frameDuration) { std::vector::iterator it; for(it = mTimers.begin(); it != mTimers.end();) { it->current += frameDuration; if(it->current >= it->max) { it->messageBox->mMarkedToDelete = true; if(*mMessageBoxes.begin() == it->messageBox) // if this box is the last one { // collect all with mMarkedToDelete and delete them. // and place the other messageboxes on the right position int height = 0; std::vector::iterator it2 = mMessageBoxes.begin(); while(it2 != mMessageBoxes.end()) { if((*it2)->mMarkedToDelete) { delete (*it2); it2 = mMessageBoxes.erase(it2); } else { (*it2)->update(height); height += (*it2)->getHeight(); it2++; } } } it = mTimers.erase(it); } else { it++; } } if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { delete mInterMessageBoxe; mInterMessageBoxe = NULL; mWindowManager->setNextMode(GM_Game); } } 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.push_back(box); std::vector::iterator it; if(mMessageBoxes.size() > 3) { delete *mMessageBoxes.begin(); mMessageBoxes.erase(mMessageBoxes.begin()); } int height = 0; for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it) { (*it)->update(height); height += (*it)->getHeight(); } } 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; mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons); return true; } bool MessageBoxManager::isInteractiveMessageBox () { return mInterMessageBoxe != NULL; } 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; } int MessageBoxManager::readPressedButton () { if(mInterMessageBoxe != NULL) { return mInterMessageBoxe->readPressedButton(); } return -1; } MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message) : Layout("openmw_messagebox_layout.xml") , mMessageBoxManager(parMessageBoxManager) , cMessage(message) { // defines mFixedWidth = 300; mBottomPadding = 20; mNextBoxPadding = 20; mMarkedToDelete = false; 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 -= 15; // this is to center the text (see messagebox_layout.xml, Widget type="Edit" position="-2 -3 0 0") mMessageWidget->setSize(size); } 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 } 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; }