aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHugues Ross <hugues.ross@gmail.com>2019-10-12 12:44:23 -0400
committerSmallJoker <SmallJoker@users.noreply.github.com>2019-10-12 18:44:23 +0200
commit69a2099c04527404f2d0942f2088b3d22dd75b5a (patch)
tree8d6fcc7dd688ace290b50f171dc319ccb68e5a5e /src
parent894008ce6fa02aed05f1ac12e0d7bc62e2476359 (diff)
downloadminetest-69a2099c04527404f2d0942f2088b3d22dd75b5a.tar.gz
minetest-69a2099c04527404f2d0942f2088b3d22dd75b5a.tar.bz2
minetest-69a2099c04527404f2d0942f2088b3d22dd75b5a.zip
Add more visual feedback for button states (#8916)
- Add style properties for overriding the the hovered/pressed state - By default, hovered buttons are a lighter version of the base color - By default, pressed buttons are a darker version of the base color - Add hovered bg image support for image buttons (style property)
Diffstat (limited to 'src')
-rw-r--r--src/gui/StyleSpec.h9
-rw-r--r--src/gui/guiButton.cpp84
-rw-r--r--src/gui/guiButton.h38
-rw-r--r--src/gui/guiConfirmRegistration.cpp5
-rw-r--r--src/gui/guiFormSpecMenu.cpp21
-rw-r--r--src/gui/guiKeyChangeMenu.cpp9
-rw-r--r--src/gui/guiPasswordChange.cpp5
-rw-r--r--src/gui/guiVolumeChange.cpp4
8 files changed, 140 insertions, 35 deletions
diff --git a/src/gui/StyleSpec.h b/src/gui/StyleSpec.h
index 29aae0836..5784a552c 100644
--- a/src/gui/StyleSpec.h
+++ b/src/gui/StyleSpec.h
@@ -29,9 +29,12 @@ public:
{
TEXTCOLOR,
BGCOLOR,
+ BGCOLOR_HOVERED,
+ BGCOLOR_PRESSED,
NOCLIP,
BORDER,
BGIMG,
+ BGIMG_HOVERED,
BGIMG_PRESSED,
ALPHA,
NUM_PROPERTIES,
@@ -49,12 +52,18 @@ public:
return TEXTCOLOR;
} else if (name == "bgcolor") {
return BGCOLOR;
+ } else if (name == "bgcolor_hovered") {
+ return BGCOLOR_HOVERED;
+ } else if (name == "bgcolor_pressed") {
+ return BGCOLOR_PRESSED;
} else if (name == "noclip") {
return NOCLIP;
} else if (name == "border") {
return BORDER;
} else if (name == "bgimg") {
return BGIMG;
+ } else if (name == "bgimg_hovered") {
+ return BGIMG_HOVERED;
} else if (name == "bgimg_pressed") {
return BGIMG_PRESSED;
} else if (name == "alpha") {
diff --git a/src/gui/guiButton.cpp b/src/gui/guiButton.cpp
index 60d330f4a..6ed5d3772 100644
--- a/src/gui/guiButton.cpp
+++ b/src/gui/guiButton.cpp
@@ -14,6 +14,12 @@
using namespace irr;
using namespace gui;
+// Multiply with a color to get the default corresponding hovered color
+#define COLOR_HOVERED_MOD 1.25f
+
+// Multiply with a color to get the default corresponding pressed color
+#define COLOR_PRESSED_MOD 0.85f
+
//! constructor
GUIButton::GUIButton(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool noclip)
@@ -34,6 +40,14 @@ GUIButton::GUIButton(IGUIEnvironment* environment, IGUIElement* parent,
// PATCH
for (size_t i = 0; i < 4; i++) {
Colors[i] = Environment->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
+ HoveredColors[i] = irr::video::SColor(Colors[i].getAlpha(),
+ core::clamp<u32>(Colors[i].getRed() * COLOR_HOVERED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getGreen() * COLOR_HOVERED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getBlue() * COLOR_HOVERED_MOD, 0, 255));
+ PressedColors[i] = irr::video::SColor(Colors[i].getAlpha(),
+ core::clamp<u32>(Colors[i].getRed() * COLOR_PRESSED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getGreen() * COLOR_PRESSED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getBlue() * COLOR_PRESSED_MOD, 0, 255));
}
// END PATCH
}
@@ -247,13 +261,15 @@ void GUIButton::draw()
if (!Pressed)
{
// PATCH
- skin->drawColored3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect, Colors);
+ skin->drawColored3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect,
+ Environment->getHovered() == this ? HoveredColors : Colors);
// END PATCH
}
else
{
// PATCH
- skin->drawColored3DButtonPanePressed(this, AbsoluteRect, &AbsoluteClippingRect, Colors);
+ skin->drawColored3DButtonPanePressed(this,
+ AbsoluteRect, &AbsoluteClippingRect, PressedColors);
// END PATCH
}
}
@@ -389,10 +405,11 @@ EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const
// find a compatible state that has images
while ( state != EGBIS_IMAGE_UP && !ButtonImages[(u32)state].Texture )
{
+ // PATCH
switch ( state )
{
case EGBIS_IMAGE_UP_FOCUSED:
- state = EGBIS_IMAGE_UP_MOUSEOVER;
+ state = EGBIS_IMAGE_UP;
break;
case EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER:
state = EGBIS_IMAGE_UP_FOCUSED;
@@ -401,7 +418,7 @@ EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const
state = EGBIS_IMAGE_DOWN;
break;
case EGBIS_IMAGE_DOWN_FOCUSED:
- state = EGBIS_IMAGE_DOWN_MOUSEOVER;
+ state = EGBIS_IMAGE_DOWN;
break;
case EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER:
state = EGBIS_IMAGE_DOWN_FOCUSED;
@@ -415,6 +432,7 @@ EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const
default:
state = EGBIS_IMAGE_UP;
}
+ // END PATCH
}
return state;
@@ -490,6 +508,40 @@ void GUIButton::setImage(EGUI_BUTTON_IMAGE_STATE state, video::ITexture* image,
ButtonImages[stateIdx].SourceRect = sourceRect;
}
+// PATCH
+void GUIButton::setImage(video::ITexture* image)
+{
+ setImage(gui::EGBIS_IMAGE_UP, image);
+}
+
+void GUIButton::setImage(video::ITexture* image, const core::rect<s32>& pos)
+{
+ setImage(gui::EGBIS_IMAGE_UP, image, pos);
+}
+
+void GUIButton::setPressedImage(video::ITexture* image)
+{
+ setImage(gui::EGBIS_IMAGE_DOWN, image);
+}
+
+void GUIButton::setPressedImage(video::ITexture* image, const core::rect<s32>& pos)
+{
+ setImage(gui::EGBIS_IMAGE_DOWN, image, pos);
+}
+
+void GUIButton::setHoveredImage(video::ITexture* image)
+{
+ setImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image);
+ setImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image);
+}
+
+void GUIButton::setHoveredImage(video::ITexture* image, const core::rect<s32>& pos)
+{
+ setImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image, pos);
+ setImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image, pos);
+}
+// END PATCH
+
//! Sets if the button should behave like a push button. Which means it
//! can be in two states: Normal or Pressed. With a click on the button,
//! the user can change the state of the button.
@@ -644,6 +696,30 @@ void GUIButton::setColor(video::SColor color)
for (size_t i = 0; i < 4; i++) {
video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);
Colors[i] = base.getInterpolated(color, d);
+ HoveredColors[i] = irr::video::SColor(Colors[i].getAlpha(),
+ core::clamp<u32>(Colors[i].getRed() * COLOR_HOVERED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getGreen() * COLOR_HOVERED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getBlue() * COLOR_HOVERED_MOD, 0, 255));
+ PressedColors[i] = irr::video::SColor(Colors[i].getAlpha(),
+ core::clamp<u32>(Colors[i].getRed() * COLOR_PRESSED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getGreen() * COLOR_PRESSED_MOD, 0, 255),
+ core::clamp<u32>(Colors[i].getBlue() * COLOR_PRESSED_MOD, 0, 255));
+ }
+}
+void GUIButton::setHoveredColor(video::SColor color)
+{
+ float d = 0.65f;
+ for (size_t i = 0; i < 4; i++) {
+ video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);
+ HoveredColors[i] = base.getInterpolated(color, d);
+ }
+}
+void GUIButton::setPressedColor(video::SColor color)
+{
+ float d = 0.65f;
+ for (size_t i = 0; i < 4; i++) {
+ video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);
+ PressedColors[i] = base.getInterpolated(color, d);
}
}
// END PATCH
diff --git a/src/gui/guiButton.h b/src/gui/guiButton.h
index 63e29ccfc..3c353d240 100644
--- a/src/gui/guiButton.h
+++ b/src/gui/guiButton.h
@@ -102,34 +102,30 @@ public:
//! Checks if an override color is enabled
virtual bool isOverrideColorEnabled(void) const;
+ // PATCH
//! Sets an image which should be displayed on the button when it is in the given state.
virtual void setImage(gui::EGUI_BUTTON_IMAGE_STATE state,
- video::ITexture* image=0,
+ video::ITexture* image=nullptr,
const core::rect<s32>& sourceRect=core::rect<s32>(0,0,0,0));
//! Sets an image which should be displayed on the button when it is in normal state.
- virtual void setImage(video::ITexture* image=0) override
- {
- setImage(gui::EGBIS_IMAGE_UP, image);
- }
+ virtual void setImage(video::ITexture* image=nullptr) override;
//! Sets an image which should be displayed on the button when it is in normal state.
- virtual void setImage(video::ITexture* image, const core::rect<s32>& pos) override
- {
- setImage(gui::EGBIS_IMAGE_UP, image, pos);
- }
+ virtual void setImage(video::ITexture* image, const core::rect<s32>& pos) override;
//! Sets an image which should be displayed on the button when it is in pressed state.
- virtual void setPressedImage(video::ITexture* image=0) override
- {
- setImage(gui::EGBIS_IMAGE_DOWN, image);
- }
+ virtual void setPressedImage(video::ITexture* image=nullptr) override;
//! Sets an image which should be displayed on the button when it is in pressed state.
- virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) override
- {
- setImage(gui::EGBIS_IMAGE_DOWN, image, pos);
- }
+ virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) override;
+
+ //! Sets an image which should be displayed on the button when it is in hovered state.
+ virtual void setHoveredImage(video::ITexture* image=nullptr);
+ // END PATCH
+
+ //! Sets an image which should be displayed on the button when it is in hovered state.
+ virtual void setHoveredImage(video::ITexture* image, const core::rect<s32>& pos);
//! Sets the sprite bank used by the button
virtual void setSpriteBank(gui::IGUISpriteBank* bank=0) override;
@@ -215,6 +211,10 @@ public:
void setColor(video::SColor color);
+ // PATCH
+ void setHoveredColor(video::SColor color);
+ void setPressedColor(video::SColor color);
+ // END PATCH
//! Do not drop returned handle
@@ -307,4 +307,8 @@ private:
bool ScaleImage;
video::SColor Colors[4];
+ // PATCH
+ video::SColor HoveredColors[4];
+ video::SColor PressedColors[4];
+ // END PATCH
};
diff --git a/src/gui/guiConfirmRegistration.cpp b/src/gui/guiConfirmRegistration.cpp
index 6fe2a4fc4..49b81b01d 100644
--- a/src/gui/guiConfirmRegistration.cpp
+++ b/src/gui/guiConfirmRegistration.cpp
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiConfirmRegistration.h"
#include "client/client.h"
+#include "guiButton.h"
#include <IGUICheckBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
@@ -128,14 +129,14 @@ void GUIConfirmRegistration::regenerateGui(v2u32 screensize)
core::rect<s32> rect2(0, 0, 230 * s, 35 * s);
rect2 = rect2 + v2s32(size.X / 2 - 220 * s, ypos);
text = wgettext("Register and Join");
- Environment->addButton(rect2, this, ID_confirm, text);
+ GUIButton::addButton(Environment, rect2, this, ID_confirm, text);
delete[] text;
}
{
core::rect<s32> rect2(0, 0, 120 * s, 35 * s);
rect2 = rect2 + v2s32(size.X / 2 + 70 * s, ypos);
text = wgettext("Cancel");
- Environment->addButton(rect2, this, ID_cancel, text);
+ GUIButton::addButton(Environment, rect2, this, ID_cancel, text);
delete[] text;
}
{
diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp
index aee7da869..ea6072cab 100644
--- a/src/gui/guiFormSpecMenu.cpp
+++ b/src/gui/guiFormSpecMenu.cpp
@@ -712,6 +712,13 @@ void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element,
if (style.isNotDefault(StyleSpec::BGCOLOR)) {
e->setColor(style.getColor(StyleSpec::BGCOLOR));
}
+ if (style.isNotDefault(StyleSpec::BGCOLOR_HOVERED)) {
+ e->setHoveredColor(style.getColor(StyleSpec::BGCOLOR_HOVERED));
+ }
+ if (style.isNotDefault(StyleSpec::BGCOLOR_PRESSED)) {
+ e->setPressedColor(style.getColor(StyleSpec::BGCOLOR_PRESSED));
+ }
+
if (style.isNotDefault(StyleSpec::TEXTCOLOR)) {
e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR));
}
@@ -720,11 +727,17 @@ void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element,
if (style.isNotDefault(StyleSpec::BGIMG)) {
std::string image_name = style.get(StyleSpec::BGIMG, "");
+ std::string hovered_image_name = style.get(StyleSpec::BGIMG_HOVERED, "");
std::string pressed_image_name = style.get(StyleSpec::BGIMG_PRESSED, "");
video::ITexture *texture = 0;
+ video::ITexture *hovered_texture = 0;
video::ITexture *pressed_texture = 0;
texture = m_tsrc->getTexture(image_name);
+ if (!hovered_image_name.empty())
+ hovered_texture = m_tsrc->getTexture(hovered_image_name);
+ else
+ hovered_texture = texture;
if (!pressed_image_name.empty())
pressed_texture = m_tsrc->getTexture(pressed_image_name);
else
@@ -733,6 +746,8 @@ void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element,
e->setUseAlphaChannel(style.getBool(StyleSpec::ALPHA, true));
e->setImage(guiScalingImageButton(
Environment->getVideoDriver(), texture, geom.X, geom.Y));
+ e->setHoveredImage(guiScalingImageButton(
+ Environment->getVideoDriver(), hovered_texture, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(
Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));
e->setScaleImage(true);
@@ -1620,7 +1635,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data, const std::string &elem
else
pressed_texture = texture;
- gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
+ GUIButton *e = GUIButton::addButton(Environment, rect, this, spec.fid, spec.flabel.c_str());
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
@@ -1818,7 +1833,7 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &
258 + m_fields.size()
);
- gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, L"");
+ gui::IGUIButton *e = GUIButton::addButton(Environment, rect, this, spec.fid, L"");
auto style = getStyleForElement("item_image_button", spec.fname, "image_button");
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
@@ -2697,7 +2712,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
core::rect<s32>(size.X/2-70, pos.Y,
(size.X/2-70)+140, pos.Y + (m_btn_height*2));
const wchar_t *text = wgettext("Proceed");
- Environment->addButton(mydata.rect, this, 257, text);
+ GUIButton::addButton(Environment, mydata.rect, this, 257, text);
delete[] text;
}
diff --git a/src/gui/guiKeyChangeMenu.cpp b/src/gui/guiKeyChangeMenu.cpp
index ca331a7d4..1d4f351cc 100644
--- a/src/gui/guiKeyChangeMenu.cpp
+++ b/src/gui/guiKeyChangeMenu.cpp
@@ -21,6 +21,7 @@
#include "guiKeyChangeMenu.h"
#include "debug.h"
+#include "guiButton.h"
#include "serialization.h"
#include <string>
#include <IGUICheckBox.h>
@@ -157,7 +158,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 100 * s, 30 * s);
rect += topleft + v2s32(offset.X + 150 * s, offset.Y - 5 * s);
const wchar_t *text = wgettext(k->key.name());
- k->button = Environment->addButton(rect, this, k->id, text);
+ k->button = GUIButton::addButton(Environment, rect, this, k->id, text);
delete[] text;
}
if ((i + 1) % KMaxButtonPerColumns == 0) {
@@ -217,16 +218,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 100 * s, 30 * s);
rect += topleft + v2s32(size.X / 2 - 105 * s, size.Y - 40 * s);
const wchar_t *text = wgettext("Save");
- Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
- text);
+ GUIButton::addButton(Environment, rect, this, GUI_ID_BACK_BUTTON, text);
delete[] text;
}
{
core::rect<s32> rect(0, 0, 100 * s, 30 * s);
rect += topleft + v2s32(size.X / 2 + 5 * s, size.Y - 40 * s);
const wchar_t *text = wgettext("Cancel");
- Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
- text);
+ GUIButton::addButton(Environment, rect, this, GUI_ID_ABORT_BUTTON, text);
delete[] text;
}
}
diff --git a/src/gui/guiPasswordChange.cpp b/src/gui/guiPasswordChange.cpp
index 469c38dbe..af91ce84c 100644
--- a/src/gui/guiPasswordChange.cpp
+++ b/src/gui/guiPasswordChange.cpp
@@ -18,6 +18,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "guiPasswordChange.h"
#include "client/client.h"
+#include "guiButton.h"
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
@@ -145,14 +146,14 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 100 * s, 30 * s);
rect = rect + v2s32(size.X / 4 + 56 * s, ypos);
text = wgettext("Change");
- Environment->addButton(rect, this, ID_change, text);
+ GUIButton::addButton(Environment, rect, this, ID_change, text);
delete[] text;
}
{
core::rect<s32> rect(0, 0, 100 * s, 30 * s);
rect = rect + v2s32(size.X / 4 + 185 * s, ypos);
text = wgettext("Cancel");
- Environment->addButton(rect, this, ID_cancel, text);
+ GUIButton::addButton(Environment, rect, this, ID_cancel, text);
delete[] text;
}
diff --git a/src/gui/guiVolumeChange.cpp b/src/gui/guiVolumeChange.cpp
index 45d2ee139..9428cde83 100644
--- a/src/gui/guiVolumeChange.cpp
+++ b/src/gui/guiVolumeChange.cpp
@@ -19,6 +19,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "guiVolumeChange.h"
#include "debug.h"
+#include "guiButton.h"
#include "serialization.h"
#include <string>
#include <IGUICheckBox.h>
@@ -103,8 +104,7 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 80 * s, 30 * s);
rect = rect + v2s32(size.X / 2 - 80 * s / 2, size.Y / 2 + 55 * s);
const wchar_t *text = wgettext("Exit");
- Environment->addButton(rect, this, ID_soundExitButton,
- text);
+ GUIButton::addButton(Environment, rect, this, ID_soundExitButton, text);
delete[] text;
}
{