diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CGUIMessageBox.cpp Irrlicht_starsonata/source/Irrlicht/CGUIMessageBox.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/CGUIMessageBox.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CGUIMessageBox.cpp 2008-02-26 04:27:40.000000000 +0100 @@ -7,6 +7,8 @@ #include "IGUIEnvironment.h" #include "IGUIButton.h" #include "IGUIFont.h" +#include "IGUIImage.h" +#include "ITexture.h" namespace irr { @@ -15,11 +17,13 @@ namespace gui //! constructor CGUIMessageBox::CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption, - const wchar_t* text, s32 flags, - IGUIElement* parent, s32 id, core::rect rectangle) -: CGUIWindow(environment, parent, id, rectangle), + const wchar_t* text, s32 boxflags, + IGUIElement* parent, s32 id, core::rect rectangle, + video::ITexture* image, s32 windowflags) +: CGUIWindow(environment, parent, id, rectangle, windowflags), OkButton(0), CancelButton(0), YesButton(0), NoButton(0), StaticText(0), - Flags(flags), MessageText(text), Pressed(false) + BoxFlags(boxflags), MessageText(text), Pressed(false) + , Icon(0), IconTexture(image) { #ifdef _DEBUG setDebugName("CGUIMessageBox"); @@ -41,76 +45,136 @@ CGUIMessageBox::CGUIMessageBox(IGUIEnvir Environment->setFocus(this); + if ( IconTexture ) + IconTexture->grab(); + refreshControls(); } void CGUIMessageBox::refreshControls() { + // Layout can be seen as 4 boxes (a layoutmanager would be nice...) + // One box at top over the whole width for title + // Two boxes with same height at the middle beside each other for icon and for text + // One box at the bottom for the buttons + IGUISkin* skin = Environment->getSkin(); IGUIElement* focusMe = 0; s32 buttonHeight = skin->getSize(EGDS_BUTTON_HEIGHT); s32 buttonWidth = skin->getSize(EGDS_BUTTON_WIDTH); - s32 titleHeight = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH)+2; + s32 titleHeight = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH)+2; //MICHA: it seems the titlebar has no own constant yet. Rather strange... s32 buttonDistance = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + s32 borderWidth = buttonDistance; // MICHA: Clear Borders at sides and between icon-text and between content-buttons A constant in the skin for that would be nicer. - // add static multiline text - - core::dimension2d dim(AbsoluteClippingRect.getWidth() - buttonWidth, - AbsoluteClippingRect.getHeight() - (buttonHeight * 3)); - core::position2d pos((AbsoluteClippingRect.getWidth() - dim.Width) / 2, - buttonHeight / 2 + titleHeight); - + // add the static text first using the maximum possible size + // We need to do so, because it's at the moment the only way to find out the size which text will need. + // A common class or function (outside statictext) to calculate textsplitting + needed textarea should be done someday if (!StaticText) { - StaticText = Environment->addStaticText(MessageText.c_str(), - core::rect(pos, dim), false, false, this); + core::rect staticRect; + staticRect.UpperLeftCorner.X = borderWidth; + staticRect.UpperLeftCorner.Y = titleHeight + borderWidth; + staticRect.LowerRightCorner.X = getRelativePosition().getWidth() - borderWidth; + staticRect.LowerRightCorner.Y = getRelativePosition().getHeight() - borderWidth; + + StaticText = Environment->addStaticText(MessageText.c_str(), staticRect, false, false, this); StaticText->setWordWrap(true); StaticText->setSubElement(true); StaticText->grab(); } else { - StaticText->setRelativePosition( core::rect(pos, dim)); + StaticText->setRelativePosition( AbsoluteClippingRect ); StaticText->setText(MessageText.c_str()); } - // adjust static text height - s32 textHeight = StaticText->getTextHeight(); - core::rect tmp = StaticText->getRelativePosition(); - tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + textHeight; - StaticText->setRelativePosition(tmp); - dim.Height = textHeight; + s32 textWidth = StaticText->getTextWidth() + 6; // +6 because the static itself needs that + s32 iconHeight = IconTexture ? IconTexture->getOriginalSize().Height : 0; - // adjust message box height + // content is text + icons + borders (but not titlebar) + s32 contentHeight = textHeight > iconHeight ? textHeight : iconHeight; + contentHeight += borderWidth; + s32 contentWidth = 0; - tmp = getRelativePosition(); - s32 msgBoxHeight = textHeight + (s32)(2.5f * buttonHeight) + titleHeight; + // add icon + if ( IconTexture ) + { + core::position2d iconPos; + iconPos.Y = titleHeight + borderWidth; + if ( iconHeight < textHeight ) + iconPos.Y += (textHeight-iconHeight) / 2; + iconPos.X = borderWidth; - // adjust message box position + if (!Icon) + { + Icon = Environment->addImage(IconTexture, iconPos, true, this); + Icon->setSubElement(true); + Icon->grab(); + } + else + { + core::rect iconRect( iconPos.X, iconPos.Y, iconPos.X + IconTexture->getOriginalSize().Width, iconPos.Y + IconTexture->getOriginalSize().Height ); + Icon->setRelativePosition(iconRect); + } + + contentWidth += borderWidth + IconTexture->getOriginalSize().Width; + } + else if ( Icon ) + { + Icon->drop(); + Icon->remove(); + Icon = 0; + } + // position text + core::rect textRect; + textRect.UpperLeftCorner.X = contentWidth + borderWidth; + textRect.UpperLeftCorner.Y = titleHeight + borderWidth; + if ( textHeight < iconHeight ) + textRect.UpperLeftCorner.Y += (iconHeight-textHeight) / 2; + textRect.LowerRightCorner.X = textRect.UpperLeftCorner.X + textWidth; + textRect.LowerRightCorner.Y = textRect.UpperLeftCorner.Y + textHeight; + contentWidth += 2*borderWidth + textWidth; + StaticText->setRelativePosition( textRect ); + + // find out button size needs + s32 countButtons = 0; + if (BoxFlags & EMBF_OK) ++countButtons; + if (BoxFlags & EMBF_CANCEL) ++countButtons; + if (BoxFlags & EMBF_YES) ++countButtons; + if (BoxFlags & EMBF_NO) ++countButtons; + s32 buttonBoxWidth = countButtons * buttonWidth + 2 * borderWidth; + if ( countButtons > 1 ) + buttonBoxWidth += (countButtons-1)*buttonDistance; + s32 buttonBoxHeight = buttonHeight + 2 * borderWidth; + + + // calc new message box sizes + core::rect tmp = getRelativePosition(); + s32 msgBoxHeight = titleHeight + contentHeight + buttonBoxHeight; + s32 msgBoxWidth = contentWidth > buttonBoxWidth ? contentWidth : buttonBoxWidth; + + // adjust message box position tmp.UpperLeftCorner.Y = (Parent->getAbsolutePosition().getHeight() - msgBoxHeight) / 2; tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + msgBoxHeight; + tmp.UpperLeftCorner.X = (Parent->getAbsolutePosition().getWidth() - msgBoxWidth) / 2; + tmp.LowerRightCorner.X = tmp.UpperLeftCorner.X + msgBoxWidth; setRelativePosition(tmp); // add buttons - s32 countButtons = 0; - if (Flags & EMBF_OK) ++countButtons; - if (Flags & EMBF_CANCEL) ++countButtons; - if (Flags & EMBF_YES) ++countButtons; - if (Flags & EMBF_NO) ++countButtons; - core::rect btnRect; - btnRect.UpperLeftCorner.Y = pos.Y + dim.Height + buttonHeight / 2; + btnRect.UpperLeftCorner.Y = titleHeight + contentHeight + borderWidth; btnRect.LowerRightCorner.Y = btnRect.UpperLeftCorner.Y + buttonHeight; - btnRect.UpperLeftCorner.X = (AbsoluteClippingRect.getWidth() - - ((buttonWidth + buttonDistance)*countButtons)) / 2; + btnRect.UpperLeftCorner.X = borderWidth; + if ( contentWidth > buttonBoxWidth ) + btnRect.UpperLeftCorner.X += (contentWidth - buttonBoxWidth) / 2; // center buttons btnRect.LowerRightCorner.X = btnRect.UpperLeftCorner.X + buttonWidth; // add/remove ok button - if (Flags & EMBF_OK) + if (BoxFlags & EMBF_OK) { if (!OkButton) { @@ -136,7 +200,7 @@ void CGUIMessageBox::refreshControls() } // add cancel button - if (Flags & EMBF_CANCEL) + if (BoxFlags & EMBF_CANCEL) { if (!CancelButton) { @@ -148,7 +212,6 @@ void CGUIMessageBox::refreshControls() CancelButton->setRelativePosition(btnRect); CancelButton->setText(skin->getDefaultText(EGDT_MSG_BOX_CANCEL)); - CancelButton->grab(); btnRect.LowerRightCorner.X += buttonWidth + buttonDistance; btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance; @@ -166,7 +229,7 @@ void CGUIMessageBox::refreshControls() // add/remove yes button - if (Flags & EMBF_YES) + if (BoxFlags & EMBF_YES) { if (!YesButton) { @@ -193,7 +256,7 @@ void CGUIMessageBox::refreshControls() } // add no button - if (Flags & EMBF_NO) + if (BoxFlags & EMBF_NO) { if (!NoButton) { @@ -242,6 +305,12 @@ CGUIMessageBox::~CGUIMessageBox() if (NoButton) NoButton->drop(); + + if (Icon) + Icon->drop(); + + if ( IconTexture ) + IconTexture->drop(); } @@ -389,10 +458,11 @@ void CGUIMessageBox::serializeAttributes { CGUIWindow::serializeAttributes(out,options); - out->addBool ("OkayButton", (Flags & EMBF_OK) != 0 ); - out->addBool ("CancelButton", (Flags & EMBF_CANCEL)!= 0 ); - out->addBool ("YesButton", (Flags & EMBF_YES) != 0 ); - out->addBool ("NoButton", (Flags & EMBF_NO) != 0 ); + out->addBool ("OkayButton", (BoxFlags & EMBF_OK) != 0 ); + out->addBool ("CancelButton", (BoxFlags & EMBF_CANCEL)!= 0 ); + out->addBool ("YesButton", (BoxFlags & EMBF_YES) != 0 ); + out->addBool ("NoButton", (BoxFlags & EMBF_NO) != 0 ); + out->addTexture ("Texture", IconTexture); out->addString ("MessageText", MessageText.c_str() ); } @@ -400,12 +470,21 @@ void CGUIMessageBox::serializeAttributes //! Reads attributes of the element void CGUIMessageBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) { - Flags = 0; + BoxFlags = 0; - Flags = in->getAttributeAsBool("OkayButton") ? EMBF_OK : 0; - Flags |= in->getAttributeAsBool("CancelButton")? EMBF_CANCEL : 0; - Flags |= in->getAttributeAsBool("YesButton") ? EMBF_YES : 0; - Flags |= in->getAttributeAsBool("NoButton") ? EMBF_NO : 0; + BoxFlags = in->getAttributeAsBool("OkayButton") ? EMBF_OK : 0; + BoxFlags |= in->getAttributeAsBool("CancelButton")? EMBF_CANCEL : 0; + BoxFlags |= in->getAttributeAsBool("YesButton") ? EMBF_YES : 0; + BoxFlags |= in->getAttributeAsBool("NoButton") ? EMBF_NO : 0; + + if ( IconTexture ) + { + IconTexture->drop(); + IconTexture = NULL; + } + IconTexture = in->getAttributeAsTexture("Texture"); + if ( IconTexture ) + IconTexture->grab(); MessageText = in->getAttributeAsStringW("MessageText").c_str(); diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CGUIMessageBox.h Irrlicht_starsonata/source/Irrlicht/CGUIMessageBox.h --- irrlicht-svn-ss/trunk/source/Irrlicht/CGUIMessageBox.h 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CGUIMessageBox.h 2008-05-31 04:52:42.000000000 +0200 @@ -13,14 +13,17 @@ namespace irr { namespace gui { + class IGUIImage; + class CGUIMessageBox : public CGUIWindow { public: //! constructor CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption, - const wchar_t* text, s32 flag, - IGUIElement* parent, s32 id, core::rect rectangle); + const wchar_t* text, s32 boxflags, + IGUIElement* parent, s32 id, core::rect rectangle, + video::ITexture* image=0, s32 windowflags=EWF_TITLEBAR); //! destructor ~CGUIMessageBox(); @@ -44,9 +47,12 @@ namespace gui IGUIButton* NoButton; IGUIStaticText* StaticText; - s32 Flags; + s32 BoxFlags; core::stringw MessageText; bool Pressed; + + IGUIImage * Icon; + video::ITexture * IconTexture; }; } // end namespace gui