1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 17:19:56 +00:00
openmw-tes3mp/apps/openmw/mwgui/messagebox.cpp

429 lines
14 KiB
C++
Raw Normal View History

#include <components/misc/stringops.hpp>
#include "messagebox.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/inputmanager.hpp"
2013-04-17 22:56:48 +00:00
namespace MWGui
2011-06-14 20:11:36 +00:00
{
2013-04-17 22:56:48 +00:00
MessageBoxManager::MessageBoxManager ()
{
2013-04-17 22:56:48 +00:00
// defines
mMessageBoxSpeed = 0.1;
mInterMessageBoxe = NULL;
2013-05-03 10:44:27 +00:00
mStaticMessageBox = NULL;
2013-04-17 22:56:48 +00:00
}
2013-04-17 22:56:48 +00:00
void MessageBoxManager::onFrame (float frameDuration)
{
std::vector<MessageBoxManagerTimer>::iterator it;
for(it = mTimers.begin(); it != mTimers.end();)
{
2013-04-17 22:56:48 +00:00
// if this messagebox is already deleted, remove the timer and move on
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
{
it = mTimers.erase(it);
continue;
}
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
it->current += frameDuration;
if(it->current >= it->max)
{
2013-04-17 22:56:48 +00:00
it->messageBox->mMarkedToDelete = true;
if(*mMessageBoxes.begin() == it->messageBox) // if this box is the last one
{
2013-04-17 22:56:48 +00:00
// collect all with mMarkedToDelete and delete them.
// and place the other messageboxes on the right position
int height = 0;
std::vector<MessageBox*>::iterator it2 = mMessageBoxes.begin();
while(it2 != mMessageBoxes.end())
{
2013-04-17 22:56:48 +00:00
if((*it2)->mMarkedToDelete)
{
delete (*it2);
it2 = mMessageBoxes.erase(it2);
}
else {
(*it2)->update(height);
height += (*it2)->getHeight();
it2++;
}
}
}
2013-04-17 22:56:48 +00:00
it = mTimers.erase(it);
}
else
{
it++;
}
}
2013-04-17 22:56:48 +00:00
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
delete mInterMessageBoxe;
mInterMessageBoxe = NULL;
MWBase::Environment::get().getInputManager()->changeInputMode(
MWBase::Environment::get().getWindowManager()->isGuiMode());
}
}
2012-03-20 09:15:22 +00:00
2013-05-03 10:44:27 +00:00
void MessageBoxManager::createMessageBox (const std::string& message, bool stat)
2013-04-17 22:56:48 +00:00
{
MessageBox *box = new MessageBox(*this, message);
2011-06-14 20:11:36 +00:00
2013-05-03 10:44:27 +00:00
if(stat)
mStaticMessageBox = box;
else
removeMessageBox(message.length()*mMessageBoxSpeed, box);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMessageBoxes.push_back(box);
std::vector<MessageBox*>::iterator it;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
if(mMessageBoxes.size() > 3) {
delete *mMessageBoxes.begin();
mMessageBoxes.erase(mMessageBoxes.begin());
}
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
int height = 0;
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
{
(*it)->update(height);
height += (*it)->getHeight();
}
}
2012-03-20 09:15:22 +00:00
2013-05-03 10:44:27 +00:00
void MessageBoxManager::removeStaticMessageBox ()
{
removeMessageBox(mStaticMessageBox);
mStaticMessageBox = NULL;
}
2013-04-17 22:56:48 +00:00
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
{
2013-04-17 22:56:48 +00:00
if(mInterMessageBoxe != NULL) {
throw std::runtime_error("There is a message box already");
}
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
return true;
}
2011-06-19 17:10:44 +00:00
2013-04-17 22:56:48 +00:00
bool MessageBoxManager::isInteractiveMessageBox ()
{
return mInterMessageBoxe != NULL;
}
2011-06-14 16:29:55 +00:00
2013-04-17 22:56:48 +00:00
void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox)
{
MessageBoxManagerTimer timer;
timer.current = 0;
timer.max = time;
timer.messageBox = msgbox;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mTimers.insert(mTimers.end(), timer);
}
2013-04-17 22:56:48 +00:00
bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
{
2013-04-17 22:56:48 +00:00
std::vector<MessageBox*>::iterator it;
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
{
2013-04-17 22:56:48 +00:00
if((*it) == msgbox)
{
delete (*it);
mMessageBoxes.erase(it);
return true;
}
}
2013-04-17 22:56:48 +00:00
return false;
}
2013-04-17 22:56:48 +00:00
void MessageBoxManager::setMessageBoxSpeed (int speed)
{
mMessageBoxSpeed = speed;
}
2013-04-17 22:56:48 +00:00
void MessageBoxManager::enterPressed ()
{
if(mInterMessageBoxe != NULL)
mInterMessageBoxe->enterPressed();
}
2013-04-17 22:56:48 +00:00
int MessageBoxManager::readPressedButton ()
{
2013-04-17 22:56:48 +00:00
if(mInterMessageBoxe != NULL)
{
return mInterMessageBoxe->readPressedButton();
}
return -1;
}
2013-04-17 22:56:48 +00:00
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
: Layout("openmw_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager)
, mMessage(message)
{
// defines
mFixedWidth = 300;
mBottomPadding = 20;
mNextBoxPadding = 20;
mMarkedToDelete = false;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
getWidget(mMessageWidget, "message");
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMessageWidget->setOverflowToTheLeft(true);
mMessageWidget->setCaptionWithReplacing(mMessage);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntSize size;
size.width = mFixedWidth;
size.height = 100; // dummy
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntCoord coord;
coord.left = 10; // dummy
coord.top = 10; // dummy
2011-06-15 17:42:20 +00:00
2013-04-17 22:56:48 +00:00
mMessageWidget->setSize(size);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
2012-03-20 19:24:36 +00:00
2013-04-17 22:56:48 +00:00
size.height = mHeight = textSize.height + 20; // this is the padding between the text and the box
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMainWidget->setSize(size);
size.width -= 15; // this is to center the text (see messagebox.layout, Widget type="Edit" position="-2 -3 0 0")
mMessageWidget->setSize(size);
}
2013-04-17 22:56:48 +00:00
void MessageBox::update (int height)
{
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().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);
}
2013-04-17 22:56:48 +00:00
int MessageBox::getHeight ()
{
return mHeight+mNextBoxPadding; // 20 is the padding between this and the next MessageBox
}
2011-06-18 13:50:41 +00:00
2013-04-17 22:56:48 +00:00
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
: WindowModal("openmw_interactive_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager)
, mButtonPressed(-1)
{
WindowModal::open();
2013-04-17 22:56:48 +00:00
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
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMarkedToDelete = false;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
getWidget(mMessageWidget, "message");
getWidget(mButtonsWidget, "buttons");
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMessageWidget->setOverflowToTheLeft(true);
mMessageWidget->setCaptionWithReplacing(message);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
int biggestButtonWidth = 0;
int buttonWidth = 0;
int buttonsWidth = 0;
int buttonHeight = 0;
MyGUI::IntCoord dummyCoord(0, 0, 0, 0);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
std::vector<std::string>::const_iterator it;
for(it = buttons.begin(); it != buttons.end(); ++it)
{
MyGUI::Button* button = mButtonsWidget->createWidget<MyGUI::Button>(
MyGUI::WidgetStyle::Child,
std::string("MW_Button"),
dummyCoord,
MyGUI::Align::Default);
button->setCaptionWithReplacing(*it);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mButtons.push_back(button);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
buttonWidth = button->getTextSize().width + 2*buttonPadding + buttonLeftPadding;
buttonsWidth += buttonWidth;
buttonHeight = button->getTextSize().height + 2*buttonPadding + buttonTopPadding;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
if(buttonWidth > biggestButtonWidth)
{
biggestButtonWidth = buttonWidth;
}
}
2013-04-17 22:56:48 +00:00
buttonsWidth += buttonLeftPadding;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntSize mainWidgetSize;
if(buttonsWidth < fixedWidth)
{
2013-04-17 22:56:48 +00:00
// on one line
if(textSize.width + 2*textPadding < buttonsWidth)
{
mainWidgetSize.width = buttonsWidth;
}
else
{
mainWidgetSize.width = textSize.width + 3*textPadding;
}
mainWidgetSize.height = textSize.height + textButtonPadding + buttonHeight + buttonMainPadding;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntCoord absCoord;
absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMainWidget->setCoord(absCoord);
mMainWidget->setSize(mainWidgetSize);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
mMessageWidget->setCoord(messageWidgetCoord);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMessageWidget->setSize(textSize);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonCord.left = left;
buttonCord.top = textSize.height + textButtonPadding;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
left += buttonSize.width + buttonLeftPadding;
}
}
2013-04-17 22:56:48 +00:00
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;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMainWidget->setSize(mainWidgetSize);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntCoord absCoord;
absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMainWidget->setCoord(absCoord);
mMainWidget->setSize(mainWidgetSize);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
mMessageWidget->setCoord(messageWidgetCoord);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
mMessageWidget->setSize(textSize);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
int top = textButtonPadding + buttonTopPadding + textSize.height;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
std::vector<MyGUI::Button*>::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;
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
top += buttonSize.height + 2*buttonTopPadding;
}
2012-03-20 09:15:22 +00:00
2013-04-17 22:56:48 +00:00
}
}
2011-06-18 13:50:41 +00:00
2013-04-17 22:56:48 +00:00
void InteractiveMessageBox::enterPressed()
{
2013-04-17 22:56:48 +00:00
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
2013-02-10 15:41:02 +00:00
{
2013-04-17 22:56:48 +00:00
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
{
buttonActivated(*button);
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
break;
}
2013-02-10 15:41:02 +00:00
}
2013-04-17 22:56:48 +00:00
}
2013-04-17 22:56:48 +00:00
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
{
buttonActivated (pressed);
}
2013-04-17 22:56:48 +00:00
void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
{
2013-04-17 22:56:48 +00:00
mMarkedToDelete = true;
int index = 0;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
2013-04-17 22:56:48 +00:00
if(*button == pressed)
{
mButtonPressed = index;
mMessageBoxManager.onButtonPressed(mButtonPressed);
return;
}
index++;
}
}
2013-04-17 22:56:48 +00:00
int InteractiveMessageBox::readPressedButton ()
{
int pressed = mButtonPressed;
mButtonPressed = -1;
return pressed;
}
}