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

384 lines
12 KiB
C++
Raw Normal View History

#include "messagebox.hpp"
using namespace MWGui;
MessageBoxManager::MessageBoxManager (MWBase::WindowManager *windowManager)
2011-06-14 20:11:36 +00:00
{
mWindowManager = windowManager;
// defines
mMessageBoxSpeed = 0.1;
2011-06-19 17:10:44 +00:00
mInterMessageBoxe = NULL;
}
void MessageBoxManager::onFrame (float frameDuration)
{
std::vector<MessageBoxManagerTimer>::iterator it;
for(it = mTimers.begin(); it != mTimers.end();)
{
// 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;
}
it->current += frameDuration;
if(it->current >= it->max)
{
it->messageBox->mMarkedToDelete = true;
2012-03-20 09:15:22 +00:00
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<MessageBox*>::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++;
}
}
2012-03-20 09:15:22 +00:00
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
delete mInterMessageBoxe;
mInterMessageBoxe = NULL;
mWindowManager->removeGuiMode(GM_InterMessageBox);
}
2011-06-14 20:11:36 +00:00
}
void MessageBoxManager::createMessageBox (const std::string& message)
{
2011-06-14 16:29:55 +00:00
MessageBox *box = new MessageBox(*this, message);
2012-03-20 09:15:22 +00:00
removeMessageBox(message.length()*mMessageBoxSpeed, box);
2012-03-20 09:15:22 +00:00
mMessageBoxes.push_back(box);
std::vector<MessageBox*>::iterator it;
2012-03-20 09:15:22 +00:00
if(mMessageBoxes.size() > 3) {
delete *mMessageBoxes.begin();
mMessageBoxes.erase(mMessageBoxes.begin());
}
2012-03-20 09:15:22 +00:00
int height = 0;
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
{
(*it)->update(height);
height += (*it)->getHeight();
}
}
2011-06-19 17:10:44 +00:00
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
{
2012-06-16 14:42:35 +00:00
/// \todo Don't write this kind of error message to cout. Either discard the old message box
/// silently or throw an exception.
2011-06-19 17:10:44 +00:00
if(mInterMessageBoxe != NULL) {
std::cout << "there is a MessageBox already" << std::endl;
return false;
}
2012-03-20 09:15:22 +00:00
2011-06-19 17:41:42 +00:00
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
2012-03-20 09:15:22 +00:00
2011-06-19 17:10:44 +00:00
return true;
}
bool MessageBoxManager::isInteractiveMessageBox ()
{
return mInterMessageBoxe != NULL;
}
2011-06-14 16:29:55 +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
mTimers.insert(mTimers.end(), timer);
}
bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
{
std::vector<MessageBox*>::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;
}
2011-06-14 16:29:55 +00:00
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
: Layout("openmw_messagebox.layout")
2011-06-14 16:29:55 +00:00
, mMessageBoxManager(parMessageBoxManager)
, mMessage(message)
2011-06-14 16:29:55 +00:00
{
// defines
2011-06-15 17:42:20 +00:00
mFixedWidth = 300;
mBottomPadding = 20;
mNextBoxPadding = 20;
mMarkedToDelete = false;
2012-03-20 09:15:22 +00:00
2011-06-15 17:42:20 +00:00
getWidget(mMessageWidget, "message");
2012-03-20 09:15:22 +00:00
2011-06-15 17:42:20 +00:00
mMessageWidget->setOverflowToTheLeft(true);
mMessageWidget->setCaptionWithReplacing(mMessage);
2012-03-20 09:15:22 +00:00
2011-06-15 17:42:20 +00:00
MyGUI::IntSize size;
size.width = mFixedWidth;
2011-06-15 17:42:20 +00:00
size.height = 100; // dummy
2012-03-20 09:15:22 +00:00
2011-06-15 17:42:20 +00:00
MyGUI::IntCoord coord;
coord.left = 10; // dummy
coord.top = 10; // dummy
mMessageWidget->setSize(size);
2012-03-20 09:15:22 +00:00
2012-03-20 19:24:36 +00:00
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
2011-06-15 17:42:20 +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
2011-06-15 17:42:20 +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")
2011-06-15 17:42:20 +00:00
mMessageWidget->setSize(size);
}
void MessageBox::update (int height)
{
2012-03-21 12:32:32 +00:00
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
2011-06-14 20:11:36 +00:00
MyGUI::IntCoord coord;
2011-06-15 17:42:20 +00:00
coord.left = (gameWindowSize.width - mFixedWidth)/2;
coord.top = (gameWindowSize.height - mHeight - height - mBottomPadding);
2012-03-20 09:15:22 +00:00
2011-06-15 17:42:20 +00:00
MyGUI::IntSize size;
size.width = mFixedWidth;
size.height = mHeight;
2012-03-20 09:15:22 +00:00
2011-06-14 20:11:36 +00:00
mMainWidget->setCoord(coord);
mMainWidget->setSize(size);
2011-06-15 17:42:20 +00:00
mMainWidget->setVisible(true);
}
int MessageBox::getHeight ()
{
return mHeight+mNextBoxPadding; // 20 is the padding between this and the next MessageBox
2011-06-14 16:29:55 +00:00
}
2011-06-18 13:50:41 +00:00
2011-06-19 17:41:42 +00:00
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
: Layout("openmw_interactive_messagebox.layout")
2011-06-18 13:50:41 +00:00
, mMessageBoxManager(parMessageBoxManager)
, mButtonPressed(-1)
2011-06-18 13:50:41 +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
mMarkedToDelete = false;
2012-03-20 09:15:22 +00:00
2011-06-18 13:50:41 +00:00
getWidget(mMessageWidget, "message");
getWidget(mButtonsWidget, "buttons");
2012-03-20 09:15:22 +00:00
2011-06-18 13:50:41 +00:00
mMessageWidget->setOverflowToTheLeft(true);
mMessageWidget->addText(message);
2012-03-20 09:15:22 +00:00
2012-03-20 19:24:36 +00:00
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
2012-03-20 09:15:22 +00:00
2012-03-21 12:32:32 +00:00
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
2012-03-20 09:15:22 +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
2011-06-19 17:10:44 +00:00
std::vector<std::string>::const_iterator it;
for(it = buttons.begin(); it != buttons.end(); ++it)
{
2011-06-19 17:41:42 +00:00
MyGUI::ButtonPtr button = mButtonsWidget->createWidget<MyGUI::Button>(
MyGUI::WidgetStyle::Child,
std::string("MW_Button"),
dummyCoord,
2011-06-19 17:41:42 +00:00
MyGUI::Align::Default);
2011-06-19 17:10:44 +00:00
button->setCaption(*it);
2012-03-20 09:15:22 +00:00
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed);
2012-03-20 09:15:22 +00:00
2011-06-19 17:41:42 +00:00
mButtons.push_back(button);
2012-03-20 09:15:22 +00:00
2012-03-20 19:24:36 +00:00
buttonWidth = button->getTextSize().width + 2*buttonPadding + buttonLeftPadding;
buttonsWidth += buttonWidth;
2012-03-20 19:24:36 +00:00
buttonHeight = button->getTextSize().height + 2*buttonPadding + buttonTopPadding;
2012-03-20 09:15:22 +00:00
if(buttonWidth > biggestButtonWidth)
{
biggestButtonWidth = buttonWidth;
}
2011-06-19 17:10:44 +00:00
}
buttonsWidth += buttonLeftPadding;
2012-03-20 09:15:22 +00:00
MyGUI::IntSize mainWidgetSize;
if(buttonsWidth < fixedWidth)
{
// 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
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
mMainWidget->setCoord(absCoord);
mMainWidget->setSize(mainWidgetSize);
2012-03-20 09:15:22 +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
mMessageWidget->setSize(textSize);
2012-03-20 09:15:22 +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
std::vector<MyGUI::ButtonPtr>::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
2012-03-20 19:24:36 +00:00
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
2012-03-20 09:15:22 +00:00
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
2012-03-20 09:15:22 +00:00
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;
2012-03-20 09:15:22 +00:00
mMainWidget->setSize(mainWidgetSize);
2012-03-20 09:15:22 +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
mMainWidget->setCoord(absCoord);
mMainWidget->setSize(mainWidgetSize);
2012-03-20 09:15:22 +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
mMessageWidget->setSize(textSize);
2012-03-20 09:15:22 +00:00
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
2012-03-20 09:15:22 +00:00
int top = textButtonPadding + buttonTopPadding + textSize.height;
2012-03-20 09:15:22 +00:00
std::vector<MyGUI::ButtonPtr>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
2012-03-20 19:24:36 +00:00
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
2012-03-20 09:15:22 +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
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
2012-03-20 09:15:22 +00:00
top += buttonSize.height + 2*buttonTopPadding;
}
2012-03-20 09:15:22 +00:00
}
2011-06-18 13:50:41 +00:00
}
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
{
mMarkedToDelete = true;
int index = 0;
std::vector<MyGUI::ButtonPtr>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
if(*button == pressed)
{
mButtonPressed = index;
return;
}
index++;
}
}
int InteractiveMessageBox::readPressedButton ()
{
int pressed = mButtonPressed;
mButtonPressed = -1;
return pressed;
}