From 0bc840aadd8473158948e72fc69d1e4523fbf0db Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 25 Sep 2014 20:28:00 +0200 Subject: [PATCH] Add NumericEditBox widget --- apps/openmw/mwgui/countdialog.cpp | 32 ++++------ apps/openmw/mwgui/countdialog.hpp | 9 ++- apps/openmw/mwgui/tradewindow.cpp | 32 ++++------ apps/openmw/mwgui/tradewindow.hpp | 9 ++- apps/openmw/mwgui/windowmanagerimp.cpp | 10 +--- components/CMakeLists.txt | 2 +- components/widgets/numericeditbox.cpp | 74 ++++++++++++++++++++++++ components/widgets/numericeditbox.hpp | 45 ++++++++++++++ components/widgets/widgets.cpp | 25 ++++++++ components/widgets/widgets.hpp | 12 ++++ files/mygui/openmw_count_window.layout | 2 +- files/mygui/openmw_trade_window.layout | 2 +- plugins/mygui_resource_plugin/plugin.cpp | 12 +--- 13 files changed, 196 insertions(+), 70 deletions(-) create mode 100644 components/widgets/numericeditbox.cpp create mode 100644 components/widgets/numericeditbox.hpp create mode 100644 components/widgets/widgets.cpp create mode 100644 components/widgets/widgets.hpp diff --git a/apps/openmw/mwgui/countdialog.cpp b/apps/openmw/mwgui/countdialog.cpp index 53c33b3c4..24d0af0d7 100644 --- a/apps/openmw/mwgui/countdialog.cpp +++ b/apps/openmw/mwgui/countdialog.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -19,7 +21,7 @@ namespace MWGui mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked); - mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange); + mItemEdit->eventValueChanged += MyGUI::newDelegate(this, &CountDialog::onEditValueChanged); mSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &CountDialog::onSliderMoved); // make sure we read the enter key being pressed to accept multiple items mItemEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &CountDialog::onEnterKeyPressed); @@ -46,7 +48,10 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit); mSlider->setScrollPosition(maxCount-1); - mItemEdit->setCaption(boost::lexical_cast(maxCount)); + + mItemEdit->setMinValue(1); + mItemEdit->setMaxValue(maxCount); + mItemEdit->setValue(maxCount); } void CountDialog::cancel() //Keeping this here as I don't know if anything else relies on it. @@ -80,30 +85,13 @@ namespace MWGui setVisible(false); } - void CountDialog::onEditTextChange(MyGUI::EditBox* _sender) + void CountDialog::onEditValueChanged(int value) { - if (_sender->getCaption() == "") - return; - - unsigned int count; - try - { - count = boost::lexical_cast(_sender->getCaption()); - } - catch (std::bad_cast&) - { - count = 1; - } - if (count > mSlider->getScrollRange()) - { - count = mSlider->getScrollRange(); - } - mSlider->setScrollPosition(count-1); - onSliderMoved(mSlider, count-1); + mSlider->setScrollPosition(value-1); } void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position) { - mItemEdit->setCaption(boost::lexical_cast(_position+1)); + mItemEdit->setValue(_position+1); } } diff --git a/apps/openmw/mwgui/countdialog.hpp b/apps/openmw/mwgui/countdialog.hpp index a00b0b223..a54e99cf4 100644 --- a/apps/openmw/mwgui/countdialog.hpp +++ b/apps/openmw/mwgui/countdialog.hpp @@ -3,6 +3,11 @@ #include "windowbase.hpp" +namespace Gui +{ + class NumericEditBox; +} + namespace MWGui { class CountDialog : public WindowModal @@ -22,7 +27,7 @@ namespace MWGui private: MyGUI::ScrollBar* mSlider; - MyGUI::EditBox* mItemEdit; + Gui::NumericEditBox* mItemEdit; MyGUI::TextBox* mItemText; MyGUI::TextBox* mLabelText; MyGUI::Button* mOkButton; @@ -30,7 +35,7 @@ namespace MWGui void onCancelButtonClicked(MyGUI::Widget* _sender); void onOkButtonClicked(MyGUI::Widget* _sender); - void onEditTextChange(MyGUI::EditBox* _sender); + void onEditValueChanged(int value); void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position); void onEnterKeyPressed(MyGUI::EditBox* _sender); }; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 3d888e468..081a1e2c2 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" @@ -86,7 +88,7 @@ namespace MWGui mDecreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonPressed); mDecreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased); - mTotalBalance->eventEditTextChange += MyGUI::newDelegate(this, &TradeWindow::onBalanceEdited); + mTotalBalance->eventValueChanged += MyGUI::newDelegate(this, &TradeWindow::onBalanceValueChanged); setCoord(400, 0, 400, 300); } @@ -433,21 +435,14 @@ namespace MWGui MyGUI::ControllerManager::getInstance().removeItem(_sender); } - void TradeWindow::onBalanceEdited(MyGUI::EditBox *_sender) + void TradeWindow::onBalanceValueChanged(int value) { - try - { - unsigned int count = boost::lexical_cast(_sender->getCaption()); - mCurrentBalance = count * (mCurrentBalance >= 0 ? 1 : -1); - updateLabels(); - } - catch (std::bad_cast&) - { - if (_sender->getCaption().empty()) - mTotalBalance->setCaption("0"); - else - mTotalBalance->setCaption(boost::lexical_cast(std::abs(mCurrentBalance))); - } + // Entering a "-" sign inverts the buying/selling state + mCurrentBalance = (mCurrentBalance >= 0 ? 1 : -1) * value; + updateLabels(); + + if (value != std::abs(value)) + mTotalBalance->setValue(std::abs(value)); } void TradeWindow::onIncreaseButtonTriggered() @@ -471,19 +466,16 @@ namespace MWGui mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast(playerGold)); - std::string balanceCaption; if (mCurrentBalance > 0) { mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}"); - balanceCaption = boost::lexical_cast(mCurrentBalance); } else { mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalCost}"); - balanceCaption = boost::lexical_cast(-mCurrentBalance); } - if (balanceCaption != mTotalBalance->getCaption().asUTF8()) // Don't reset text cursor if text doesn't need to be changed - mTotalBalance->setCaption(balanceCaption); + + mTotalBalance->setValue(std::abs(mCurrentBalance)); mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast(getMerchantGold())); } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 11c0614b7..47de9215a 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -3,10 +3,9 @@ #include "container.hpp" -namespace MyGUI +namespace Gui { - class Gui; - class Widget; + class NumericEditBox; } namespace MWGui @@ -54,7 +53,7 @@ namespace MWGui MyGUI::Button* mIncreaseButton; MyGUI::Button* mDecreaseButton; MyGUI::TextBox* mTotalBalanceLabel; - MyGUI::EditBox* mTotalBalance; + Gui::NumericEditBox* mTotalBalance; MyGUI::Widget* mBottomPane; @@ -84,7 +83,7 @@ namespace MWGui void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); - void onBalanceEdited(MyGUI::EditBox* _sender); + void onBalanceValueChanged(int value); void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller); void addRepeatController(MyGUI::Widget* widget); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1b400bb58..ef7622a62 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -18,7 +18,7 @@ #include -#include +#include #include #include "../mwbase/inputmanager.hpp" @@ -165,13 +165,6 @@ 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"); @@ -179,6 +172,7 @@ namespace MWGui BookPage::registerMyGUIComponents (); ItemView::registerComponents(); ItemWidget::registerComponents(); + Gui::registerAllWidgets(); MyGUI::FactoryManager::getInstance().registerFactory("Controller"); MyGUI::FactoryManager::getInstance().registerFactory("Controller"); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index baddfd6a2..d0508e9d4 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -96,7 +96,7 @@ add_component_dir (ogreinit ) add_component_dir (widgets - box imagebutton tags list + box imagebutton tags list numericeditbox widgets ) add_component_dir (fontloader diff --git a/components/widgets/numericeditbox.cpp b/components/widgets/numericeditbox.cpp new file mode 100644 index 000000000..5361b3127 --- /dev/null +++ b/components/widgets/numericeditbox.cpp @@ -0,0 +1,74 @@ +#include "numericeditbox.hpp" + +#include + +namespace Gui +{ + + void NumericEditBox::initialiseOverride() + { + Base::initialiseOverride(); + eventEditTextChange += MyGUI::newDelegate(this, &NumericEditBox::onEditTextChange); + + mValue = 0; + setCaption("0"); + } + + void NumericEditBox::shutdownOverride() + { + Base::shutdownOverride(); + eventEditTextChange -= MyGUI::newDelegate(this, &NumericEditBox::onEditTextChange); + } + + void NumericEditBox::onEditTextChange(MyGUI::EditBox *sender) + { + std::string newCaption = sender->getCaption(); + if (newCaption.empty()) + { + return; + } + + try + { + mValue = boost::lexical_cast(newCaption); + int capped = std::min(mMaxValue, std::max(mValue, mMinValue)); + if (capped != mValue) + { + mValue = capped; + setCaption(MyGUI::utility::toString(mValue)); + } + } + catch (boost::bad_lexical_cast&) + { + setCaption(MyGUI::utility::toString(mValue)); + } + + eventValueChanged(mValue); + } + + void NumericEditBox::setValue(int value) + { + if (value != mValue) + { + setCaption(MyGUI::utility::toString(value)); + mValue = value; + } + } + + void NumericEditBox::setMinValue(int minValue) + { + mMinValue = minValue; + } + + void NumericEditBox::setMaxValue(int maxValue) + { + mMaxValue = maxValue; + } + + void NumericEditBox::onKeyLostFocus(MyGUI::Widget* _new) + { + Base::onKeyLostFocus(_new); + setCaption(MyGUI::utility::toString(mValue)); + } + +} diff --git a/components/widgets/numericeditbox.hpp b/components/widgets/numericeditbox.hpp new file mode 100644 index 000000000..bbc0e48f4 --- /dev/null +++ b/components/widgets/numericeditbox.hpp @@ -0,0 +1,45 @@ +#ifndef OPENMW_NUMERIC_EDIT_BOX_H +#define OPENMW_NUMERIC_EDIT_BOX_H + +#include + +namespace Gui +{ + + /** + * @brief A variant of the EditBox that only allows integer inputs + */ + class NumericEditBox : public MyGUI::EditBox + { + MYGUI_RTTI_DERIVED(NumericEditBox) + + public: + NumericEditBox() + : mValue(0), mMinValue(std::numeric_limits().min()), + mMaxValue(std::numeric_limits().max()) + {} + + void initialiseOverride(); + void shutdownOverride(); + + typedef MyGUI::delegates::CMultiDelegate1 EventHandle_ValueChanged; + EventHandle_ValueChanged eventValueChanged; + + /// @note Does not trigger eventValueChanged + void setValue (int value); + + void setMinValue(int minValue); + void setMaxValue(int maxValue); + private: + void onEditTextChange(MyGUI::EditBox* sender); + void onKeyLostFocus(MyGUI::Widget* _new); + + int mValue; + + int mMinValue; + int mMaxValue; + }; + +} + +#endif diff --git a/components/widgets/widgets.cpp b/components/widgets/widgets.cpp new file mode 100644 index 000000000..b35dc88a4 --- /dev/null +++ b/components/widgets/widgets.cpp @@ -0,0 +1,25 @@ +#include "widgets.hpp" + +#include + +#include "list.hpp" +#include "numericeditbox.hpp" +#include "box.hpp" +#include "imagebutton.hpp" + +namespace Gui +{ + + void registerAllWidgets() + { + 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/widgets/widgets.hpp b/components/widgets/widgets.hpp new file mode 100644 index 000000000..d17132135 --- /dev/null +++ b/components/widgets/widgets.hpp @@ -0,0 +1,12 @@ +#ifndef OPENMW_COMPONENTS_WIDGETS_H +#define OPENMW_COMPONENTS_WIDGETS_H + +namespace Gui +{ + + /// Register all widgets from this component with MyGUI's factory manager. + void registerAllWidgets(); + +} + +#endif diff --git a/files/mygui/openmw_count_window.layout b/files/mygui/openmw_count_window.layout index 5f3a30af4..c5fe9e2c5 100644 --- a/files/mygui/openmw_count_window.layout +++ b/files/mygui/openmw_count_window.layout @@ -12,7 +12,7 @@ - + diff --git a/files/mygui/openmw_trade_window.layout b/files/mygui/openmw_trade_window.layout index cb00d7d50..b2017661b 100644 --- a/files/mygui/openmw_trade_window.layout +++ b/files/mygui/openmw_trade_window.layout @@ -44,7 +44,7 @@ - + diff --git a/plugins/mygui_resource_plugin/plugin.cpp b/plugins/mygui_resource_plugin/plugin.cpp index 349b440a5..ac4c9a3d4 100644 --- a/plugins/mygui_resource_plugin/plugin.cpp +++ b/plugins/mygui_resource_plugin/plugin.cpp @@ -11,10 +11,8 @@ #include #include -#include -#include #include -#include +#include #include #include @@ -137,13 +135,7 @@ namespace MyGUIPlugin { 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"); + Gui::registerAllWidgets(); } void ResourcePlugin::createTransparentBGTexture()