mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-06 00:55:50 +00:00
Add SharedStateButton, used in spell window and controls box to apply mouseover effect to all buttons within one row (Fixes #1986)
This commit is contained in:
parent
3f0bc6eecb
commit
9a1b7cbe52
@ -9,6 +9,8 @@
|
||||
|
||||
#include <SDL_video.h>
|
||||
|
||||
#include <components/widgets/sharedstatebutton.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
@ -454,16 +456,21 @@ namespace MWGui
|
||||
|
||||
std::string binding = MWBase::Environment::get().getInputManager()->getActionBindingName (*it);
|
||||
|
||||
MyGUI::TextBox* leftText = mControlsBox->createWidget<MyGUI::TextBox>("SandText", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default);
|
||||
Gui::SharedStateButton* leftText = mControlsBox->createWidget<Gui::SharedStateButton>("SandTextButton", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default);
|
||||
leftText->setCaptionWithReplacing(desc);
|
||||
|
||||
MyGUI::Button* rightText = mControlsBox->createWidget<MyGUI::Button>("SandTextButton", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default);
|
||||
Gui::SharedStateButton* rightText = mControlsBox->createWidget<Gui::SharedStateButton>("SandTextButton", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default);
|
||||
rightText->setCaptionWithReplacing(binding);
|
||||
rightText->setTextAlign (MyGUI::Align::Right);
|
||||
rightText->setUserData(*it); // save the action id for callbacks
|
||||
rightText->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onRebindAction);
|
||||
rightText->eventMouseWheel += MyGUI::newDelegate(this, &SettingsWindow::onInputTabMouseWheel);
|
||||
curH += h;
|
||||
|
||||
Gui::ButtonGroup group;
|
||||
group.push_back(leftText);
|
||||
group.push_back(rightText);
|
||||
Gui::SharedStateButton::createButtonGroup(group);
|
||||
}
|
||||
|
||||
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <components/widgets/sharedstatebutton.hpp>
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
@ -177,7 +179,7 @@ namespace MWGui
|
||||
for (std::vector<std::string>::const_iterator it = spellList.begin(); it != spellList.end(); ++it)
|
||||
{
|
||||
const ESM::Spell* spell = esmStore.get<ESM::Spell>().find(*it);
|
||||
MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>("SandTextButton",
|
||||
Gui::SharedStateButton* t = mSpellView->createWidget<Gui::SharedStateButton>("SandTextButton",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
t->setCaption(spell->mName);
|
||||
t->setTextAlign(MyGUI::Align::Left);
|
||||
@ -185,20 +187,28 @@ namespace MWGui
|
||||
t->setUserString("Spell", *it);
|
||||
t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
|
||||
t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected);
|
||||
t->setStateSelected(*it == MWBase::Environment::get().getWindowManager()->getSelectedSpell());
|
||||
|
||||
// cost / success chance
|
||||
MyGUI::Button* costChance = mSpellView->createWidget<MyGUI::Button>("SandTextButton",
|
||||
Gui::SharedStateButton* costChance = mSpellView->createWidget<Gui::SharedStateButton>("SandTextButton",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
std::string cost = boost::lexical_cast<std::string>(spell->mData.mCost);
|
||||
std::string chance = boost::lexical_cast<std::string>(int(MWMechanics::getSpellSuccessChance(*it, player)));
|
||||
costChance->setCaption(cost + "/" + chance);
|
||||
costChance->setTextAlign(MyGUI::Align::Right);
|
||||
costChance->setNeedMouseFocus(false);
|
||||
costChance->setStateSelected(*it == MWBase::Environment::get().getWindowManager()->getSelectedSpell());
|
||||
costChance->setUserString("ToolTipType", "Spell");
|
||||
costChance->setUserString("Spell", *it);
|
||||
costChance->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
|
||||
costChance->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected);
|
||||
|
||||
t->setSize(mWidth-12-costChance->getTextSize().width, t->getHeight());
|
||||
|
||||
Gui::ButtonGroup group;
|
||||
group.push_back(t);
|
||||
group.push_back(costChance);
|
||||
Gui::SharedStateButton::createButtonGroup(group);
|
||||
|
||||
t->setStateSelected(*it == MWBase::Environment::get().getWindowManager()->getSelectedSpell());
|
||||
|
||||
mHeight += spellHeight;
|
||||
}
|
||||
|
||||
@ -224,7 +234,7 @@ namespace MWGui
|
||||
}
|
||||
}
|
||||
|
||||
MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>(equipped ? "SandTextButton" : "SpellTextUnequipped",
|
||||
Gui::SharedStateButton* t = mSpellView->createWidget<Gui::SharedStateButton>(equipped ? "SandTextButton" : "SpellTextUnequipped",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
t->setCaption(item.getClass().getName(item));
|
||||
t->setTextAlign(MyGUI::Align::Left);
|
||||
@ -233,12 +243,9 @@ namespace MWGui
|
||||
t->setUserString("Equipped", equipped ? "true" : "false");
|
||||
t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onEnchantedItemSelected);
|
||||
t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
|
||||
if (store.getSelectedEnchantItem() != store.end())
|
||||
t->setStateSelected(item == *store.getSelectedEnchantItem());
|
||||
|
||||
|
||||
// cost / charge
|
||||
MyGUI::Button* costCharge = mSpellView->createWidget<MyGUI::Button>(equipped ? "SandTextButton" : "SpellTextUnequipped",
|
||||
Gui::SharedStateButton* costCharge = mSpellView->createWidget<Gui::SharedStateButton>(equipped ? "SandTextButton" : "SpellTextUnequipped",
|
||||
MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
|
||||
float enchantCost = enchant->mData.mCost;
|
||||
@ -257,11 +264,22 @@ namespace MWGui
|
||||
charge = "100";
|
||||
}
|
||||
|
||||
|
||||
costCharge->setUserData(item);
|
||||
costCharge->setUserString("ToolTipType", "ItemPtr");
|
||||
costCharge->setUserString("Equipped", equipped ? "true" : "false");
|
||||
costCharge->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onEnchantedItemSelected);
|
||||
costCharge->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel);
|
||||
costCharge->setCaption(cost + "/" + charge);
|
||||
costCharge->setTextAlign(MyGUI::Align::Right);
|
||||
costCharge->setNeedMouseFocus(false);
|
||||
|
||||
Gui::ButtonGroup group;
|
||||
group.push_back(t);
|
||||
group.push_back(costCharge);
|
||||
Gui::SharedStateButton::createButtonGroup(group);
|
||||
|
||||
if (store.getSelectedEnchantItem() != store.end())
|
||||
costCharge->setStateSelected(item == *store.getSelectedEnchantItem());
|
||||
t->setStateSelected(item == *store.getSelectedEnchantItem());
|
||||
|
||||
t->setSize(mWidth-12-costCharge->getTextSize().width, t->getHeight());
|
||||
|
||||
|
@ -96,7 +96,7 @@ add_component_dir (ogreinit
|
||||
)
|
||||
|
||||
add_component_dir (widgets
|
||||
box imagebutton tags list numericeditbox widgets
|
||||
box imagebutton tags list numericeditbox sharedstatebutton widgets
|
||||
)
|
||||
|
||||
add_component_dir (fontloader
|
||||
|
128
components/widgets/sharedstatebutton.cpp
Normal file
128
components/widgets/sharedstatebutton.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "sharedstatebutton.hpp"
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
SharedStateButton::SharedStateButton()
|
||||
: mIsMousePressed(false)
|
||||
, mIsMouseFocus(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SharedStateButton::shutdownOverride()
|
||||
{
|
||||
ButtonGroup group = mSharedWith; // make a copy so that we don't nuke the vector during iteration
|
||||
for (ButtonGroup::iterator it = group.begin(); it != group.end(); ++it)
|
||||
{
|
||||
(*it)->shareStateWith(ButtonGroup());
|
||||
}
|
||||
}
|
||||
|
||||
void SharedStateButton::shareStateWith(ButtonGroup shared)
|
||||
{
|
||||
mSharedWith = shared;
|
||||
}
|
||||
|
||||
void SharedStateButton::onMouseButtonPressed(int _left, int _top, MyGUI::MouseButton _id)
|
||||
{
|
||||
mIsMousePressed = true;
|
||||
Base::onMouseButtonPressed(_left, _top, _id);
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
void SharedStateButton::onMouseButtonReleased(int _left, int _top, MyGUI::MouseButton _id)
|
||||
{
|
||||
mIsMousePressed = false;
|
||||
Base::onMouseButtonReleased(_left, _top, _id);
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
void SharedStateButton::onMouseSetFocus(MyGUI::Widget *_old)
|
||||
{
|
||||
mIsMouseFocus = true;
|
||||
Base::onMouseSetFocus(_old);
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
void SharedStateButton::onMouseLostFocus(MyGUI::Widget *_new)
|
||||
{
|
||||
mIsMouseFocus = false;
|
||||
Base::onMouseLostFocus(_new);
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
void SharedStateButton::baseUpdateEnable()
|
||||
{
|
||||
Base::baseUpdateEnable();
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
void SharedStateButton::setStateSelected(bool _value)
|
||||
{
|
||||
Base::setStateSelected(_value);
|
||||
updateButtonState();
|
||||
|
||||
for (ButtonGroup::iterator it = mSharedWith.begin(); it != mSharedWith.end(); ++it)
|
||||
{
|
||||
(*it)->MyGUI::Button::setStateSelected(getStateSelected());
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedStateButton::_setState(const std::string &_value)
|
||||
{
|
||||
bool ret = _setWidgetState(_value);
|
||||
if (ret)
|
||||
{
|
||||
for (ButtonGroup::iterator it = mSharedWith.begin(); it != mSharedWith.end(); ++it)
|
||||
{
|
||||
(*it)->_setWidgetState(_value);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SharedStateButton::updateButtonState()
|
||||
{
|
||||
if (getStateSelected())
|
||||
{
|
||||
if (!getInheritedEnabled())
|
||||
{
|
||||
if (!_setState("disabled_checked"))
|
||||
_setState("disabled");
|
||||
}
|
||||
else if (mIsMousePressed)
|
||||
{
|
||||
if (!_setState("pushed_checked"))
|
||||
_setState("pushed");
|
||||
}
|
||||
else if (mIsMouseFocus)
|
||||
{
|
||||
if (!_setState("highlighted_checked"))
|
||||
_setState("pushed");
|
||||
}
|
||||
else
|
||||
_setState("normal_checked");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!getInheritedEnabled())
|
||||
_setState("disabled");
|
||||
else if (mIsMousePressed)
|
||||
_setState("pushed");
|
||||
else if (mIsMouseFocus)
|
||||
_setState("highlighted");
|
||||
else
|
||||
_setState("normal");
|
||||
}
|
||||
}
|
||||
|
||||
void SharedStateButton::createButtonGroup(ButtonGroup group)
|
||||
{
|
||||
for (ButtonGroup::iterator it = group.begin(); it != group.end(); ++it)
|
||||
{
|
||||
(*it)->shareStateWith(group);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
51
components/widgets/sharedstatebutton.hpp
Normal file
51
components/widgets/sharedstatebutton.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef OPENMW_WIDGETS_SHAREDSTATEBUTTON_HPP
|
||||
#define OPENMW_WIDGETS_SHAREDSTATEBUTTON_HPP
|
||||
|
||||
#include <MyGUI_Button.h>
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
class SharedStateButton;
|
||||
|
||||
typedef std::vector<SharedStateButton*> ButtonGroup;
|
||||
|
||||
/// @brief A button that applies its own state changes to other widgets, to do this you define it as part of a ButtonGroup.
|
||||
class SharedStateButton : public MyGUI::Button
|
||||
{
|
||||
MYGUI_RTTI_DERIVED(SharedStateButton)
|
||||
|
||||
public:
|
||||
SharedStateButton();
|
||||
|
||||
protected:
|
||||
void updateButtonState();
|
||||
|
||||
virtual void onMouseButtonPressed(int _left, int _top, MyGUI::MouseButton _id);
|
||||
virtual void onMouseButtonReleased(int _left, int _top, MyGUI::MouseButton _id);
|
||||
virtual void onMouseSetFocus(MyGUI::Widget* _old);
|
||||
virtual void onMouseLostFocus(MyGUI::Widget* _new);
|
||||
virtual void baseUpdateEnable();
|
||||
|
||||
virtual void shutdownOverride();
|
||||
|
||||
bool _setState(const std::string &_value);
|
||||
|
||||
public:
|
||||
void shareStateWith(ButtonGroup shared);
|
||||
|
||||
/// @note The ButtonGroup connection will be destroyed when any widget in the group gets destroyed.
|
||||
static void createButtonGroup(ButtonGroup group);
|
||||
|
||||
//! Set button selected state
|
||||
void setStateSelected(bool _value);
|
||||
|
||||
private:
|
||||
ButtonGroup mSharedWith;
|
||||
|
||||
bool mIsMousePressed;
|
||||
bool mIsMouseFocus;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
#include "numericeditbox.hpp"
|
||||
#include "box.hpp"
|
||||
#include "imagebutton.hpp"
|
||||
#include "sharedstatebutton.hpp"
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
@ -20,6 +21,7 @@ namespace Gui
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<Gui::AutoSizedButton>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<Gui::ImageButton>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<Gui::NumericEditBox>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<Gui::SharedStateButton>("Widget");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user