From c6bcd75058a51fbd8d4130eed629d36231c5a4a7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 12 Sep 2014 05:14:21 +0200 Subject: [PATCH] Add various custom widgets used in OpenMW to the MyGUI plugin --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/bookwindow.cpp | 2 +- apps/openmw/mwgui/bookwindow.hpp | 12 +- apps/openmw/mwgui/journalwindow.cpp | 13 +- apps/openmw/mwgui/mainmenu.cpp | 9 +- apps/openmw/mwgui/mainmenu.hpp | 8 +- apps/openmw/mwgui/scrollwindow.cpp | 2 +- apps/openmw/mwgui/scrollwindow.hpp | 7 +- apps/openmw/mwgui/waitdialog.cpp | 4 +- apps/openmw/mwgui/widgets.cpp | 406 ----------------- apps/openmw/mwgui/widgets.hpp | 112 ----- apps/openmw/mwgui/windowmanagerimp.cpp | 14 +- components/CMakeLists.txt | 2 +- components/widgets/box.cpp | 407 ++++++++++++++++++ components/widgets/box.hpp | 118 +++++ .../widgets}/imagebutton.cpp | 2 +- .../widgets}/imagebutton.hpp | 2 +- libs/mygui_resource_plugin/plugin.cpp | 17 + 18 files changed, 587 insertions(+), 552 deletions(-) create mode 100644 components/widgets/box.cpp create mode 100644 components/widgets/box.hpp rename {apps/openmw/mwgui => components/widgets}/imagebutton.cpp (99%) rename {apps/openmw/mwgui => components/widgets}/imagebutton.hpp (98%) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 53c79f7c6..308b883fd 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -36,7 +36,7 @@ add_openmw_dir (mwgui formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog - enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons + enchantingdialog trainingwindow travelwindow exposedwindow cursor spellicons merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 32a5255c9..372e81844 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -193,7 +193,7 @@ namespace MWGui } } - void BookWindow::adjustButton (MWGui::ImageButton* button) + void BookWindow::adjustButton (Gui::ImageButton* button) { MyGUI::IntSize diff = button->getSize() - button->getRequestedSize(); button->setSize(button->getRequestedSize()); diff --git a/apps/openmw/mwgui/bookwindow.hpp b/apps/openmw/mwgui/bookwindow.hpp index a944f56e2..e0f921dc1 100644 --- a/apps/openmw/mwgui/bookwindow.hpp +++ b/apps/openmw/mwgui/bookwindow.hpp @@ -5,7 +5,7 @@ #include "../mwworld/ptr.hpp" -#include "imagebutton.hpp" +#include namespace MWGui { @@ -31,13 +31,13 @@ namespace MWGui void updatePages(); void clearPages(); - void adjustButton(MWGui::ImageButton* button); + void adjustButton(Gui::ImageButton* button); private: - MWGui::ImageButton* mCloseButton; - MWGui::ImageButton* mTakeButton; - MWGui::ImageButton* mNextPageButton; - MWGui::ImageButton* mPrevPageButton; + Gui::ImageButton* mCloseButton; + Gui::ImageButton* mTakeButton; + Gui::ImageButton* mNextPageButton; + Gui::ImageButton* mPrevPageButton; MyGUI::TextBox* mLeftPageNumber; MyGUI::TextBox* mRightPageNumber; MyGUI::Widget* mLeftPage; diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 057e12414..bc7fbde15 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -15,9 +15,10 @@ #include #include "boost/lexical_cast.hpp" +#include + #include "bookpage.hpp" #include "windowbase.hpp" -#include "imagebutton.hpp" #include "journalviewmodel.hpp" #include "journalbooks.hpp" #include "list.hpp" @@ -82,7 +83,7 @@ namespace void adviseButtonClick (char const * name, void (JournalWindowImpl::*Handler) (MyGUI::Widget* _sender)) { - getWidget (name) -> + getWidget (name) -> eventMouseButtonClick += newDelegate(this, Handler); } @@ -146,12 +147,12 @@ namespace adjustButton(ShowActiveBTN, true); adjustButton(JournalBTN); - MWGui::ImageButton* optionsButton = getWidget(OptionsBTN); + Gui::ImageButton* optionsButton = getWidget(OptionsBTN); if (optionsButton->getWidth() == 0) { // If tribunal is not installed (-> no options button), we still want the Topics button available, // so place it where the options button would have been - MWGui::ImageButton* topicsButton = getWidget(TopicsBTN); + Gui::ImageButton* topicsButton = getWidget(TopicsBTN); topicsButton->detachFromWidget(); topicsButton->attachToWidget(optionsButton->getParent()); topicsButton->setPosition(optionsButton->getPosition()); @@ -159,7 +160,7 @@ namespace topicsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &JournalWindowImpl::notifyOptions); } - MWGui::ImageButton* nextButton = getWidget(NextPageBTN); + Gui::ImageButton* nextButton = getWidget(NextPageBTN); if (nextButton->getSize().width == 64) { // english button has a 7 pixel wide strip of garbage on its right edge @@ -182,7 +183,7 @@ namespace void adjustButton (char const * name, bool optional = false) { - MWGui::ImageButton* button = getWidget(name); + Gui::ImageButton* button = getWidget(name); MyGUI::IntSize diff = button->getSize() - button->getRequestedSize(!optional); button->setSize(button->getRequestedSize(!optional)); diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 7c60353d2..81b082568 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -4,6 +4,8 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" @@ -16,7 +18,6 @@ #include "savegamedialog.hpp" #include "confirmationdialog.hpp" -#include "imagebutton.hpp" #include "backgroundimage.hpp" #include "videowidget.hpp" @@ -249,7 +250,7 @@ namespace MWGui { if (mButtons.find(*it) == mButtons.end()) { - MWGui::ImageButton* button = mButtonBox->createWidget + Gui::ImageButton* button = mButtonBox->createWidget ("ImageBox", MyGUI::IntCoord(0, curH, 0, 0), MyGUI::Align::Default); button->setProperty("ImageHighlighted", "textures\\menu_" + *it + "_over.dds"); button->setProperty("ImageNormal", "textures\\menu_" + *it + ".dds"); @@ -262,7 +263,7 @@ namespace MWGui // Start by hiding all buttons int maxwidth = 0; - for (std::map::iterator it = mButtons.begin(); it != mButtons.end(); ++it) + for (std::map::iterator it = mButtons.begin(); it != mButtons.end(); ++it) { it->second->setVisible(false); MyGUI::IntSize requested = it->second->getRequestedSize(); @@ -274,7 +275,7 @@ namespace MWGui for (std::vector::iterator it = buttons.begin(); it != buttons.end(); ++it) { assert(mButtons.find(*it) != mButtons.end()); - MWGui::ImageButton* button = mButtons[*it]; + Gui::ImageButton* button = mButtons[*it]; button->setVisible(true); MyGUI::IntSize requested = button->getRequestedSize(); diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index ccd8df4b0..cd2050d0f 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -3,10 +3,14 @@ #include +namespace Gui +{ + class ImageButton; +} + namespace MWGui { - class ImageButton; class BackgroundImage; class SaveGameDialog; class VideoWidget; @@ -39,7 +43,7 @@ namespace MWGui MyGUI::ImageBox* mVideoBackground; VideoWidget* mVideo; // For animated main menus - std::map mButtons; + std::map mButtons; void onButtonClicked (MyGUI::Widget* sender); void onNewGameConfirmed(); diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index 867bef0d7..7530d7a9e 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -13,7 +13,7 @@ namespace { - void adjustButton (MWGui::ImageButton* button) + void adjustButton (Gui::ImageButton* button) { MyGUI::IntSize diff = button->getSize() - button->getRequestedSize(); button->setSize(button->getRequestedSize()); diff --git a/apps/openmw/mwgui/scrollwindow.hpp b/apps/openmw/mwgui/scrollwindow.hpp index 17e56f334..08ce6a905 100644 --- a/apps/openmw/mwgui/scrollwindow.hpp +++ b/apps/openmw/mwgui/scrollwindow.hpp @@ -2,7 +2,8 @@ #define MWGUI_SCROLLWINDOW_H #include "windowbase.hpp" -#include "imagebutton.hpp" + +#include #include "../mwworld/ptr.hpp" @@ -23,8 +24,8 @@ namespace MWGui void onTakeButtonClicked (MyGUI::Widget* _sender); private: - MWGui::ImageButton* mCloseButton; - MWGui::ImageButton* mTakeButton; + Gui::ImageButton* mCloseButton; + Gui::ImageButton* mTakeButton; MyGUI::ScrollView* mTextView; MWWorld::Ptr mScroll; diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 434c6926e..ac70d3eed 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" @@ -190,7 +192,7 @@ namespace MWGui mSleeping = canRest; - dynamic_cast(mMainWidget)->notifyChildrenSizeChanged(); + dynamic_cast(mMainWidget)->notifyChildrenSizeChanged(); center(); } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 1264185a2..5c5b9b894 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -537,412 +537,6 @@ namespace MWGui assignWidget(mBarTextWidget, "BarText"); } - - - - // --------------------------------------------------------------------------------------------------------------------- - - void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w) - { - MyGUI::Widget * parent = w->getParent(); - if (parent != 0) - { - if (mExpandDirection == MyGUI::Align::Left) - { - int hdiff = getRequestedSize ().width - w->getSize().width; - w->setPosition(w->getPosition() - MyGUI::IntPoint(hdiff, 0)); - } - w->setSize(getRequestedSize ()); - - while (parent != 0) - { - Box * b = dynamic_cast(parent); - if (b) - b->notifyChildrenSizeChanged(); - else - break; - parent = parent->getParent(); - } - } - } - - - MyGUI::IntSize AutoSizedTextBox::getRequestedSize() - { - return getTextSize(); - } - - void AutoSizedTextBox::setCaption(const MyGUI::UString& _value) - { - TextBox::setCaption(_value); - - notifySizeChange (this); - } - - void AutoSizedTextBox::setPropertyOverride(const std::string& _key, const std::string& _value) - { - if (_key == "ExpandDirection") - { - mExpandDirection = MyGUI::Align::parse (_value); - } - else - { - TextBox::setPropertyOverride (_key, _value); - } - } - - MyGUI::IntSize AutoSizedEditBox::getRequestedSize() - { - if (getAlign().isHStretch()) - throw std::runtime_error("AutoSizedEditBox can't have HStretch align (" + getName() + ")"); - return MyGUI::IntSize(getSize().width, getTextSize().height); - } - - void AutoSizedEditBox::setCaption(const MyGUI::UString& _value) - { - EditBox::setCaption(_value); - - notifySizeChange (this); - } - - void AutoSizedEditBox::setPropertyOverride(const std::string& _key, const std::string& _value) - { - if (_key == "ExpandDirection") - { - mExpandDirection = MyGUI::Align::parse (_value); - } - else - { - EditBox::setPropertyOverride (_key, _value); - } - } - - - MyGUI::IntSize AutoSizedButton::getRequestedSize() - { - MyGUI::IntSize padding(24, 8); - if (isUserString("TextPadding")) - padding = MyGUI::IntSize::parse(getUserString("TextPadding")); - - MyGUI::IntSize size = getTextSize() + MyGUI::IntSize(padding.width,padding.height); - return size; - } - - void AutoSizedButton::setCaption(const MyGUI::UString& _value) - { - Button::setCaption(_value); - - notifySizeChange (this); - } - - void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::string& _value) - { - if (_key == "ExpandDirection") - { - mExpandDirection = MyGUI::Align::parse (_value); - } - else - { - Button::setPropertyOverride (_key, _value); - } - } - - Box::Box() - : mSpacing(4) - , mPadding(0) - , mAutoResize(false) - { - - } - - void Box::notifyChildrenSizeChanged () - { - align(); - } - - bool Box::_setPropertyImpl(const std::string& _key, const std::string& _value) - { - if (_key == "Spacing") - mSpacing = MyGUI::utility::parseValue(_value); - else if (_key == "Padding") - mPadding = MyGUI::utility::parseValue(_value); - else if (_key == "AutoResize") - mAutoResize = MyGUI::utility::parseValue(_value); - else - return false; - - return true; - } - - void HBox::align () - { - unsigned int count = getChildCount (); - size_t h_stretched_count = 0; - int total_width = 0; - int total_height = 0; - std::vector< std::pair > sizes; - sizes.resize(count); - - for (unsigned int i = 0; i < count; ++i) - { - MyGUI::Widget* w = getChildAt(i); - bool hstretch = w->getUserString ("HStretch") == "true"; - bool hidden = w->getUserString("Hidden") == "true"; - if (hidden) - continue; - h_stretched_count += hstretch; - AutoSizedWidget* aw = dynamic_cast(w); - if (aw) - { - sizes[i] = std::make_pair(aw->getRequestedSize (), hstretch); - total_width += aw->getRequestedSize ().width; - total_height = std::max(total_height, aw->getRequestedSize ().height); - } - else - { - sizes[i] = std::make_pair(w->getSize(), hstretch); - total_width += w->getSize().width; - if (!(w->getUserString("VStretch") == "true")) - total_height = std::max(total_height, w->getSize().height); - } - - if (i != count-1) - total_width += mSpacing; - } - - if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height)) - { - setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2)); - return; - } - - - int curX = 0; - for (unsigned int i = 0; i < count; ++i) - { - if (i == 0) - curX += mPadding; - - MyGUI::Widget* w = getChildAt(i); - - bool hidden = w->getUserString("Hidden") == "true"; - if (hidden) - continue; - - bool vstretch = w->getUserString ("VStretch") == "true"; - int max_height = getSize().height - mPadding*2; - int height = vstretch ? max_height : sizes[i].first.height; - - MyGUI::IntCoord widgetCoord; - widgetCoord.left = curX; - widgetCoord.top = mPadding + (getSize().height-mPadding*2 - height) / 2; - int width = sizes[i].second ? sizes[i].first.width + (getSize().width-mPadding*2 - total_width)/h_stretched_count - : sizes[i].first.width; - widgetCoord.width = width; - widgetCoord.height = height; - w->setCoord(widgetCoord); - curX += width; - - if (i != count-1) - curX += mSpacing; - } - } - - void HBox::setPropertyOverride(const std::string& _key, const std::string& _value) - { - if (!Box::_setPropertyImpl (_key, _value)) - MyGUI::Widget::setPropertyOverride(_key, _value); - } - - void HBox::setSize (const MyGUI::IntSize& _value) - { - MyGUI::Widget::setSize (_value); - align(); - } - - void HBox::setCoord (const MyGUI::IntCoord& _value) - { - MyGUI::Widget::setCoord (_value); - align(); - } - - void HBox::onWidgetCreated(MyGUI::Widget* _widget) - { - align(); - } - - MyGUI::IntSize HBox::getRequestedSize () - { - MyGUI::IntSize size(0,0); - for (unsigned int i = 0; i < getChildCount (); ++i) - { - bool hidden = getChildAt(i)->getUserString("Hidden") == "true"; - if (hidden) - continue; - - AutoSizedWidget* w = dynamic_cast(getChildAt(i)); - if (w) - { - MyGUI::IntSize requested = w->getRequestedSize (); - size.height = std::max(size.height, requested.height); - size.width = size.width + requested.width; - if (i != getChildCount()-1) - size.width += mSpacing; - } - else - { - MyGUI::IntSize requested = getChildAt(i)->getSize (); - size.height = std::max(size.height, requested.height); - - if (getChildAt(i)->getUserString("HStretch") != "true") - size.width = size.width + requested.width; - - if (i != getChildCount()-1) - size.width += mSpacing; - } - size.height += mPadding*2; - size.width += mPadding*2; - } - return size; - } - - - - - void VBox::align () - { - unsigned int count = getChildCount (); - size_t v_stretched_count = 0; - int total_height = 0; - int total_width = 0; - std::vector< std::pair > sizes; - sizes.resize(count); - for (unsigned int i = 0; i < count; ++i) - { - MyGUI::Widget* w = getChildAt(i); - - bool hidden = w->getUserString("Hidden") == "true"; - if (hidden) - continue; - - bool vstretch = w->getUserString ("VStretch") == "true"; - v_stretched_count += vstretch; - AutoSizedWidget* aw = dynamic_cast(w); - if (aw) - { - sizes[i] = std::make_pair(aw->getRequestedSize (), vstretch); - total_height += aw->getRequestedSize ().height; - total_width = std::max(total_width, aw->getRequestedSize ().width); - } - else - { - sizes[i] = std::make_pair(w->getSize(), vstretch); - total_height += w->getSize().height; - - if (!(w->getUserString("HStretch") == "true")) - total_width = std::max(total_width, w->getSize().width); - } - - if (i != count-1) - total_height += mSpacing; - } - - if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height)) - { - setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2)); - return; - } - - - int curY = 0; - for (unsigned int i = 0; i < count; ++i) - { - if (i==0) - curY += mPadding; - - MyGUI::Widget* w = getChildAt(i); - - bool hidden = w->getUserString("Hidden") == "true"; - if (hidden) - continue; - - bool hstretch = w->getUserString ("HStretch") == "true"; - int maxWidth = getSize().width - mPadding*2; - int width = hstretch ? maxWidth : sizes[i].first.width; - - MyGUI::IntCoord widgetCoord; - widgetCoord.top = curY; - widgetCoord.left = mPadding + (getSize().width-mPadding*2 - width) / 2; - int height = sizes[i].second ? sizes[i].first.height + (getSize().height-mPadding*2 - total_height)/v_stretched_count - : sizes[i].first.height; - widgetCoord.height = height; - widgetCoord.width = width; - w->setCoord(widgetCoord); - curY += height; - - if (i != count-1) - curY += mSpacing; - } - } - - void VBox::setPropertyOverride(const std::string& _key, const std::string& _value) - { - if (!Box::_setPropertyImpl (_key, _value)) - MyGUI::Widget::setPropertyOverride(_key, _value); - } - - void VBox::setSize (const MyGUI::IntSize& _value) - { - MyGUI::Widget::setSize (_value); - align(); - } - - void VBox::setCoord (const MyGUI::IntCoord& _value) - { - MyGUI::Widget::setCoord (_value); - align(); - } - - MyGUI::IntSize VBox::getRequestedSize () - { - MyGUI::IntSize size(0,0); - for (unsigned int i = 0; i < getChildCount (); ++i) - { - bool hidden = getChildAt(i)->getUserString("Hidden") == "true"; - if (hidden) - continue; - - AutoSizedWidget* w = dynamic_cast(getChildAt(i)); - if (w) - { - MyGUI::IntSize requested = w->getRequestedSize (); - size.width = std::max(size.width, requested.width); - size.height = size.height + requested.height; - if (i != getChildCount()-1) - size.height += mSpacing; - } - else - { - MyGUI::IntSize requested = getChildAt(i)->getSize (); - size.width = std::max(size.width, requested.width); - - if (getChildAt(i)->getUserString("VStretch") != "true") - size.height = size.height + requested.height; - - if (i != getChildCount()-1) - size.height += mSpacing; - } - size.height += mPadding*2; - size.width += mPadding*2; - } - return size; - } - - void VBox::onWidgetCreated(MyGUI::Widget* _widget) - { - align(); - } - MWScrollBar::MWScrollBar() : mEnableRepeat(true) , mRepeatTriggerTime(0.5) diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index dad49eb45..10b723cae 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -298,118 +298,6 @@ namespace MWGui }; typedef MWDynamicStat* MWDynamicStatPtr; - - - - - // --------------------------------------------------------------------------------------------------------------------- - - - - class AutoSizedWidget - { - public: - virtual MyGUI::IntSize getRequestedSize() = 0; - - protected: - void notifySizeChange(MyGUI::Widget* w); - - MyGUI::Align mExpandDirection; - }; - - class AutoSizedTextBox : public AutoSizedWidget, public MyGUI::TextBox - { - MYGUI_RTTI_DERIVED( AutoSizedTextBox ) - - public: - virtual MyGUI::IntSize getRequestedSize(); - virtual void setCaption(const MyGUI::UString& _value); - - protected: - virtual void setPropertyOverride(const std::string& _key, const std::string& _value); - }; - - class AutoSizedEditBox : public AutoSizedWidget, public MyGUI::EditBox - { - MYGUI_RTTI_DERIVED( AutoSizedEditBox ) - - public: - virtual MyGUI::IntSize getRequestedSize(); - virtual void setCaption(const MyGUI::UString& _value); - - protected: - virtual void setPropertyOverride(const std::string& _key, const std::string& _value); - }; - - class AutoSizedButton : public AutoSizedWidget, public MyGUI::Button - { - MYGUI_RTTI_DERIVED( AutoSizedButton ) - - public: - virtual MyGUI::IntSize getRequestedSize(); - virtual void setCaption(const MyGUI::UString& _value); - - protected: - virtual void setPropertyOverride(const std::string& _key, const std::string& _value); - }; - - /** - * @brief A container widget that automatically sizes its children - * @note the box being an AutoSizedWidget as well allows to put boxes inside a box - */ - class Box : public AutoSizedWidget - { - public: - Box(); - - void notifyChildrenSizeChanged(); - - protected: - virtual void align() = 0; - - virtual bool _setPropertyImpl(const std::string& _key, const std::string& _value); - - int mSpacing; // how much space to put between elements - - int mPadding; // outer padding - - bool mAutoResize; // auto resize the box so that it exactly fits all elements - }; - - class HBox : public Box, public MyGUI::Widget - { - MYGUI_RTTI_DERIVED( HBox ) - - public: - virtual void setSize (const MyGUI::IntSize &_value); - virtual void setCoord (const MyGUI::IntCoord &_value); - - protected: - virtual void align(); - virtual MyGUI::IntSize getRequestedSize(); - - virtual void setPropertyOverride(const std::string& _key, const std::string& _value); - - virtual void onWidgetCreated(MyGUI::Widget* _widget); - }; - - class VBox : public Box, public MyGUI::Widget - { - MYGUI_RTTI_DERIVED( VBox) - - public: - virtual void setSize (const MyGUI::IntSize &_value); - virtual void setCoord (const MyGUI::IntCoord &_value); - - protected: - virtual void align(); - virtual MyGUI::IntSize getRequestedSize(); - - virtual void setPropertyOverride(const std::string& _key, const std::string& _value); - - virtual void onWidgetCreated(MyGUI::Widget* _widget); - }; - class MWScrollBar : public MyGUI::ScrollBar { MYGUI_RTTI_DERIVED(MWScrollBar) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5882ae2b6..ab791f090 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -18,6 +18,8 @@ #include +#include + #include "../mwbase/inputmanager.hpp" #include "../mwbase/statemanager.hpp" @@ -161,12 +163,12 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 1178a3a28..50d11e9bb 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -92,7 +92,7 @@ add_component_dir (ogreinit ) add_component_dir (widgets - box + box imagebutton ) add_component_dir (fontloader diff --git a/components/widgets/box.cpp b/components/widgets/box.cpp new file mode 100644 index 000000000..6ec471b65 --- /dev/null +++ b/components/widgets/box.cpp @@ -0,0 +1,407 @@ +#include "box.hpp" + +namespace Gui +{ + + void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w) + { + MyGUI::Widget * parent = w->getParent(); + if (parent != 0) + { + if (mExpandDirection == MyGUI::Align::Left) + { + int hdiff = getRequestedSize ().width - w->getSize().width; + w->setPosition(w->getPosition() - MyGUI::IntPoint(hdiff, 0)); + } + w->setSize(getRequestedSize ()); + + while (parent != 0) + { + Box * b = dynamic_cast(parent); + if (b) + b->notifyChildrenSizeChanged(); + else + break; + parent = parent->getParent(); + } + } + } + + + MyGUI::IntSize AutoSizedTextBox::getRequestedSize() + { + return getTextSize(); + } + + void AutoSizedTextBox::setCaption(const MyGUI::UString& _value) + { + TextBox::setCaption(_value); + + notifySizeChange (this); + } + + void AutoSizedTextBox::setPropertyOverride(const std::string& _key, const std::string& _value) + { + if (_key == "ExpandDirection") + { + mExpandDirection = MyGUI::Align::parse (_value); + } + else + { + TextBox::setPropertyOverride (_key, _value); + } + } + + MyGUI::IntSize AutoSizedEditBox::getRequestedSize() + { + if (getAlign().isHStretch()) + throw std::runtime_error("AutoSizedEditBox can't have HStretch align (" + getName() + ")"); + return MyGUI::IntSize(getSize().width, getTextSize().height); + } + + void AutoSizedEditBox::setCaption(const MyGUI::UString& _value) + { + EditBox::setCaption(_value); + + notifySizeChange (this); + } + + void AutoSizedEditBox::setPropertyOverride(const std::string& _key, const std::string& _value) + { + if (_key == "ExpandDirection") + { + mExpandDirection = MyGUI::Align::parse (_value); + } + else + { + EditBox::setPropertyOverride (_key, _value); + } + } + + + MyGUI::IntSize AutoSizedButton::getRequestedSize() + { + MyGUI::IntSize padding(24, 8); + if (isUserString("TextPadding")) + padding = MyGUI::IntSize::parse(getUserString("TextPadding")); + + MyGUI::IntSize size = getTextSize() + MyGUI::IntSize(padding.width,padding.height); + return size; + } + + void AutoSizedButton::setCaption(const MyGUI::UString& _value) + { + Button::setCaption(_value); + + notifySizeChange (this); + } + + void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::string& _value) + { + if (_key == "ExpandDirection") + { + mExpandDirection = MyGUI::Align::parse (_value); + } + else + { + Button::setPropertyOverride (_key, _value); + } + } + + Box::Box() + : mSpacing(4) + , mPadding(0) + , mAutoResize(false) + { + + } + + void Box::notifyChildrenSizeChanged () + { + align(); + } + + bool Box::_setPropertyImpl(const std::string& _key, const std::string& _value) + { + if (_key == "Spacing") + mSpacing = MyGUI::utility::parseValue(_value); + else if (_key == "Padding") + mPadding = MyGUI::utility::parseValue(_value); + else if (_key == "AutoResize") + mAutoResize = MyGUI::utility::parseValue(_value); + else + return false; + + return true; + } + + void HBox::align () + { + unsigned int count = getChildCount (); + size_t h_stretched_count = 0; + int total_width = 0; + int total_height = 0; + std::vector< std::pair > sizes; + sizes.resize(count); + + for (unsigned int i = 0; i < count; ++i) + { + MyGUI::Widget* w = getChildAt(i); + bool hstretch = w->getUserString ("HStretch") == "true"; + bool hidden = w->getUserString("Hidden") == "true"; + if (hidden) + continue; + h_stretched_count += hstretch; + AutoSizedWidget* aw = dynamic_cast(w); + if (aw) + { + sizes[i] = std::make_pair(aw->getRequestedSize (), hstretch); + total_width += aw->getRequestedSize ().width; + total_height = std::max(total_height, aw->getRequestedSize ().height); + } + else + { + sizes[i] = std::make_pair(w->getSize(), hstretch); + total_width += w->getSize().width; + if (!(w->getUserString("VStretch") == "true")) + total_height = std::max(total_height, w->getSize().height); + } + + if (i != count-1) + total_width += mSpacing; + } + + if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height)) + { + setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2)); + return; + } + + + int curX = 0; + for (unsigned int i = 0; i < count; ++i) + { + if (i == 0) + curX += mPadding; + + MyGUI::Widget* w = getChildAt(i); + + bool hidden = w->getUserString("Hidden") == "true"; + if (hidden) + continue; + + bool vstretch = w->getUserString ("VStretch") == "true"; + int max_height = getSize().height - mPadding*2; + int height = vstretch ? max_height : sizes[i].first.height; + + MyGUI::IntCoord widgetCoord; + widgetCoord.left = curX; + widgetCoord.top = mPadding + (getSize().height-mPadding*2 - height) / 2; + int width = sizes[i].second ? sizes[i].first.width + (getSize().width-mPadding*2 - total_width)/h_stretched_count + : sizes[i].first.width; + widgetCoord.width = width; + widgetCoord.height = height; + w->setCoord(widgetCoord); + curX += width; + + if (i != count-1) + curX += mSpacing; + } + } + + void HBox::setPropertyOverride(const std::string& _key, const std::string& _value) + { + if (!Box::_setPropertyImpl (_key, _value)) + MyGUI::Widget::setPropertyOverride(_key, _value); + } + + void HBox::setSize (const MyGUI::IntSize& _value) + { + MyGUI::Widget::setSize (_value); + align(); + } + + void HBox::setCoord (const MyGUI::IntCoord& _value) + { + MyGUI::Widget::setCoord (_value); + align(); + } + + void HBox::onWidgetCreated(MyGUI::Widget* _widget) + { + align(); + } + + MyGUI::IntSize HBox::getRequestedSize () + { + MyGUI::IntSize size(0,0); + for (unsigned int i = 0; i < getChildCount (); ++i) + { + bool hidden = getChildAt(i)->getUserString("Hidden") == "true"; + if (hidden) + continue; + + AutoSizedWidget* w = dynamic_cast(getChildAt(i)); + if (w) + { + MyGUI::IntSize requested = w->getRequestedSize (); + size.height = std::max(size.height, requested.height); + size.width = size.width + requested.width; + if (i != getChildCount()-1) + size.width += mSpacing; + } + else + { + MyGUI::IntSize requested = getChildAt(i)->getSize (); + size.height = std::max(size.height, requested.height); + + if (getChildAt(i)->getUserString("HStretch") != "true") + size.width = size.width + requested.width; + + if (i != getChildCount()-1) + size.width += mSpacing; + } + size.height += mPadding*2; + size.width += mPadding*2; + } + return size; + } + + + + + void VBox::align () + { + unsigned int count = getChildCount (); + size_t v_stretched_count = 0; + int total_height = 0; + int total_width = 0; + std::vector< std::pair > sizes; + sizes.resize(count); + for (unsigned int i = 0; i < count; ++i) + { + MyGUI::Widget* w = getChildAt(i); + + bool hidden = w->getUserString("Hidden") == "true"; + if (hidden) + continue; + + bool vstretch = w->getUserString ("VStretch") == "true"; + v_stretched_count += vstretch; + AutoSizedWidget* aw = dynamic_cast(w); + if (aw) + { + sizes[i] = std::make_pair(aw->getRequestedSize (), vstretch); + total_height += aw->getRequestedSize ().height; + total_width = std::max(total_width, aw->getRequestedSize ().width); + } + else + { + sizes[i] = std::make_pair(w->getSize(), vstretch); + total_height += w->getSize().height; + + if (!(w->getUserString("HStretch") == "true")) + total_width = std::max(total_width, w->getSize().width); + } + + if (i != count-1) + total_height += mSpacing; + } + + if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height)) + { + setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2)); + return; + } + + + int curY = 0; + for (unsigned int i = 0; i < count; ++i) + { + if (i==0) + curY += mPadding; + + MyGUI::Widget* w = getChildAt(i); + + bool hidden = w->getUserString("Hidden") == "true"; + if (hidden) + continue; + + bool hstretch = w->getUserString ("HStretch") == "true"; + int maxWidth = getSize().width - mPadding*2; + int width = hstretch ? maxWidth : sizes[i].first.width; + + MyGUI::IntCoord widgetCoord; + widgetCoord.top = curY; + widgetCoord.left = mPadding + (getSize().width-mPadding*2 - width) / 2; + int height = sizes[i].second ? sizes[i].first.height + (getSize().height-mPadding*2 - total_height)/v_stretched_count + : sizes[i].first.height; + widgetCoord.height = height; + widgetCoord.width = width; + w->setCoord(widgetCoord); + curY += height; + + if (i != count-1) + curY += mSpacing; + } + } + + void VBox::setPropertyOverride(const std::string& _key, const std::string& _value) + { + if (!Box::_setPropertyImpl (_key, _value)) + MyGUI::Widget::setPropertyOverride(_key, _value); + } + + void VBox::setSize (const MyGUI::IntSize& _value) + { + MyGUI::Widget::setSize (_value); + align(); + } + + void VBox::setCoord (const MyGUI::IntCoord& _value) + { + MyGUI::Widget::setCoord (_value); + align(); + } + + MyGUI::IntSize VBox::getRequestedSize () + { + MyGUI::IntSize size(0,0); + for (unsigned int i = 0; i < getChildCount (); ++i) + { + bool hidden = getChildAt(i)->getUserString("Hidden") == "true"; + if (hidden) + continue; + + AutoSizedWidget* w = dynamic_cast(getChildAt(i)); + if (w) + { + MyGUI::IntSize requested = w->getRequestedSize (); + size.width = std::max(size.width, requested.width); + size.height = size.height + requested.height; + if (i != getChildCount()-1) + size.height += mSpacing; + } + else + { + MyGUI::IntSize requested = getChildAt(i)->getSize (); + size.width = std::max(size.width, requested.width); + + if (getChildAt(i)->getUserString("VStretch") != "true") + size.height = size.height + requested.height; + + if (i != getChildCount()-1) + size.height += mSpacing; + } + size.height += mPadding*2; + size.width += mPadding*2; + } + return size; + } + + void VBox::onWidgetCreated(MyGUI::Widget* _widget) + { + align(); + } + +} diff --git a/components/widgets/box.hpp b/components/widgets/box.hpp new file mode 100644 index 000000000..40e76aca0 --- /dev/null +++ b/components/widgets/box.hpp @@ -0,0 +1,118 @@ +#ifndef OPENMW_WIDGETS_BOX_H +#define OPENMW_WIDGETS_BOX_H + +#include +#include +#include +#include + +namespace Gui +{ + + class AutoSizedWidget + { + public: + virtual MyGUI::IntSize getRequestedSize() = 0; + + protected: + void notifySizeChange(MyGUI::Widget* w); + + MyGUI::Align mExpandDirection; + }; + + class AutoSizedTextBox : public AutoSizedWidget, public MyGUI::TextBox + { + MYGUI_RTTI_DERIVED( AutoSizedTextBox ) + + public: + virtual MyGUI::IntSize getRequestedSize(); + virtual void setCaption(const MyGUI::UString& _value); + + protected: + virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + }; + + class AutoSizedEditBox : public AutoSizedWidget, public MyGUI::EditBox + { + MYGUI_RTTI_DERIVED( AutoSizedEditBox ) + + public: + virtual MyGUI::IntSize getRequestedSize(); + virtual void setCaption(const MyGUI::UString& _value); + + protected: + virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + }; + + class AutoSizedButton : public AutoSizedWidget, public MyGUI::Button + { + MYGUI_RTTI_DERIVED( AutoSizedButton ) + + public: + virtual MyGUI::IntSize getRequestedSize(); + virtual void setCaption(const MyGUI::UString& _value); + + protected: + virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + }; + + /** + * @brief A container widget that automatically sizes its children + * @note the box being an AutoSizedWidget as well allows to put boxes inside a box + */ + class Box : public AutoSizedWidget + { + public: + Box(); + + void notifyChildrenSizeChanged(); + + protected: + virtual void align() = 0; + + virtual bool _setPropertyImpl(const std::string& _key, const std::string& _value); + + int mSpacing; // how much space to put between elements + + int mPadding; // outer padding + + bool mAutoResize; // auto resize the box so that it exactly fits all elements + }; + + class HBox : public Box, public MyGUI::Widget + { + MYGUI_RTTI_DERIVED( HBox ) + + public: + virtual void setSize (const MyGUI::IntSize &_value); + virtual void setCoord (const MyGUI::IntCoord &_value); + + protected: + virtual void align(); + virtual MyGUI::IntSize getRequestedSize(); + + virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + + virtual void onWidgetCreated(MyGUI::Widget* _widget); + }; + + class VBox : public Box, public MyGUI::Widget + { + MYGUI_RTTI_DERIVED( VBox) + + public: + virtual void setSize (const MyGUI::IntSize &_value); + virtual void setCoord (const MyGUI::IntCoord &_value); + + protected: + virtual void align(); + virtual MyGUI::IntSize getRequestedSize(); + + virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + + virtual void onWidgetCreated(MyGUI::Widget* _widget); + }; + +} + +#endif diff --git a/apps/openmw/mwgui/imagebutton.cpp b/components/widgets/imagebutton.cpp similarity index 99% rename from apps/openmw/mwgui/imagebutton.cpp rename to components/widgets/imagebutton.cpp index f2565f5c0..24e4d9a62 100644 --- a/apps/openmw/mwgui/imagebutton.cpp +++ b/components/widgets/imagebutton.cpp @@ -2,7 +2,7 @@ #include -namespace MWGui +namespace Gui { void ImageButton::setPropertyOverride(const std::string &_key, const std::string &_value) diff --git a/apps/openmw/mwgui/imagebutton.hpp b/components/widgets/imagebutton.hpp similarity index 98% rename from apps/openmw/mwgui/imagebutton.hpp rename to components/widgets/imagebutton.hpp index f4191a3a5..bed6a2794 100644 --- a/apps/openmw/mwgui/imagebutton.hpp +++ b/components/widgets/imagebutton.hpp @@ -3,7 +3,7 @@ #include -namespace MWGui +namespace Gui { /** diff --git a/libs/mygui_resource_plugin/plugin.cpp b/libs/mygui_resource_plugin/plugin.cpp index 02088f693..a3d178051 100644 --- a/libs/mygui_resource_plugin/plugin.cpp +++ b/libs/mygui_resource_plugin/plugin.cpp @@ -4,11 +4,15 @@ #include #include #include +#include #include #include #include +#include +#include + #include #include @@ -47,6 +51,12 @@ namespace MyGUIPlugin MYGUI_RTTI_DERIVED( MWDynamicStat ) }; + // Dummy - runtime use only + class ExposedWindow : public MyGUI::Window + { + MYGUI_RTTI_DERIVED( ExposedWindow ) + }; + const std::string& ResourcePlugin::getName() const { @@ -114,6 +124,13 @@ namespace MyGUIPlugin void ResourcePlugin::registerWidgets() { MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); } void ResourcePlugin::createTransparentBGTexture()