Skip to content

Commit 9284313

Browse files
Hugues Rossrubenwardy
Hugues Ross
authored andcommittedDec 9, 2019
Refactor to centralize GUIButton styling/rendering code (#9090)
1 parent a462181 commit 9284313

18 files changed

+522
-145
lines changed
 

‎build/android/jni/Android.mk

+2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ LOCAL_SRC_FILES := \
181181
jni/src/gui/guiBackgroundImage.cpp \
182182
jni/src/gui/guiBox.cpp \
183183
jni/src/gui/guiButton.cpp \
184+
jni/src/gui/guiButtonImage.cpp \
185+
jni/src/gui/guiButtonItemImage.cpp \
184186
jni/src/gui/guiChatConsole.cpp \
185187
jni/src/gui/guiConfirmRegistration.cpp \
186188
jni/src/gui/guiEditBoxWithScrollbar.cpp \

‎doc/lua_api.txt

+10-12
Original file line numberDiff line numberDiff line change
@@ -2541,20 +2541,20 @@ Some types may inherit styles from parent types.
25412541
* label
25422542
* vertlabel, inherits from field
25432543
* image_button
2544-
* item_image_button, inherits from image_button
2544+
* item_image_button
25452545
* tabheader
25462546

25472547

25482548
### Valid Properties
25492549

2550-
* button, button_exit
2550+
* button, button_exit, image_button, item_image_button
25512551
* alpha - boolean, whether to draw alpha in bgimg. Default true.
25522552
* bgcolor - color, sets button tint.
25532553
* bgcolor_hovered - color when hovered. Defaults to a lighter bgcolor when not provided.
25542554
* bgcolor_pressed - color when pressed. Defaults to a darker bgcolor when not provided.
2555-
* bgimg - standard image. Defaults to none.
2556-
* bgimg_hovered - image when hovered. Defaults to bgimg when not provided.
2557-
* bgimg_pressed - image when pressed. Defaults to bgimg when not provided.
2555+
* bgimg - standard background image. Defaults to none.
2556+
* bgimg_hovered - background image when hovered. Defaults to bgimg when not provided.
2557+
* bgimg_pressed - background image when pressed. Defaults to bgimg when not provided.
25582558
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
25592559
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
25602560
* textcolor - color, default white.
@@ -2572,13 +2572,11 @@ Some types may inherit styles from parent types.
25722572
* textcolor - color. Default white.
25732573
* label, vertlabel
25742574
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
2575-
* image_button
2576-
* alpha - boolean, whether to draw alpha in bgimg. Default true.
2577-
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default false.
2578-
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
2579-
* item_image_button
2580-
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default false.
2581-
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
2575+
* image_button (additional properties)
2576+
* fgimg - standard image. Defaults to none.
2577+
* fgimg_hovered - image when hovered. Defaults to fgimg when not provided.
2578+
* fgimg_pressed - image when pressed. Defaults to fgimg when not provided.
2579+
* NOTE: The parameters of any given image_button will take precedence over fgimg/fgimg_pressed
25822580
* tabheader
25832581
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
25842582
* textcolor - color. Default white.

‎games/minimal/mods/test/formspec.lua

+7
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ local style_fs = [[
7070
style[one_btn13;border=false]
7171
item_image_button[1.25,8.35;1,1;default:sword_steel;one_btn13;NoBor]
7272
73+
style[one_btn14;border=false;bgimg=test_bg.png;bgimg_hovered=test_bg_hovered.png;bgimg_pressed=test_bg_pressed.png;fgimg=bubble.png;fgimg_hovered=default_apple.png;fgimg_pressed=heart.png]
74+
image_button[0,9.6;1,1;bubble.png;one_btn14;Bg]
75+
76+
style[one_btn15;border=false;bgimg=test_bg.png;bgimg_hovered=test_bg_hovered.png;bgimg_pressed=test_bg_pressed.png]
77+
item_image_button[1.25,9.6;1,1;default:sword_steel;one_btn15;Bg]
78+
79+
7380
7481
container[2.75,0]
7582
972 Bytes
Loading
Loading
Loading

‎src/gui/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ set(gui_SRCS
22
${CMAKE_CURRENT_SOURCE_DIR}/guiBackgroundImage.cpp
33
${CMAKE_CURRENT_SOURCE_DIR}/guiBox.cpp
44
${CMAKE_CURRENT_SOURCE_DIR}/guiButton.cpp
5+
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonImage.cpp
6+
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp
57
${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp
68
${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp
79
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp

‎src/gui/StyleSpec.h

+34
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1717
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1818
*/
1919

20+
#include "client/tile.h" // ITextureSource
2021
#include "irrlichttypes_extrabloated.h"
22+
#include "util/string.h"
2123
#include <array>
2224

2325
#pragma once
@@ -36,6 +38,9 @@ class StyleSpec
3638
BGIMG,
3739
BGIMG_HOVERED,
3840
BGIMG_PRESSED,
41+
FGIMG,
42+
FGIMG_HOVERED,
43+
FGIMG_PRESSED,
3944
ALPHA,
4045
NUM_PROPERTIES,
4146
NONE
@@ -66,6 +71,12 @@ class StyleSpec
6671
return BGIMG_HOVERED;
6772
} else if (name == "bgimg_pressed") {
6873
return BGIMG_PRESSED;
74+
} else if (name == "fgimg") {
75+
return FGIMG;
76+
} else if (name == "fgimg_hovered") {
77+
return FGIMG_HOVERED;
78+
} else if (name == "fgimg_pressed") {
79+
return FGIMG_PRESSED;
6980
} else if (name == "alpha") {
7081
return ALPHA;
7182
} else {
@@ -106,6 +117,29 @@ class StyleSpec
106117
return color;
107118
}
108119

120+
video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc,
121+
video::ITexture *def) const
122+
{
123+
const auto &val = properties[prop];
124+
if (val.empty()) {
125+
return def;
126+
}
127+
128+
video::ITexture *texture = tsrc->getTexture(val);
129+
130+
return texture;
131+
}
132+
133+
video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc) const
134+
{
135+
const auto &val = properties[prop];
136+
FATAL_ERROR_IF(val.empty(), "Unexpected missing property");
137+
138+
video::ITexture *texture = tsrc->getTexture(val);
139+
140+
return texture;
141+
}
142+
109143
bool getBool(Property prop, bool def) const
110144
{
111145
const auto &val = properties[prop];

‎src/gui/guiButton.cpp

+94-21
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
#include "guiButton.h"
66

77

8+
#include "client/guiscalingfilter.h"
9+
#include "client/tile.h"
810
#include "IGUISkin.h"
911
#include "IGUIEnvironment.h"
1012
#include "IVideoDriver.h"
1113
#include "IGUIFont.h"
14+
#include "irrlicht_changes/static_text.h"
1215
#include "porting.h"
16+
#include "StyleSpec.h"
1317

1418
using namespace irr;
1519
using namespace gui;
@@ -49,6 +53,9 @@ GUIButton::GUIButton(IGUIEnvironment* environment, IGUIElement* parent,
4953
core::clamp<u32>(Colors[i].getGreen() * COLOR_PRESSED_MOD, 0, 255),
5054
core::clamp<u32>(Colors[i].getBlue() * COLOR_PRESSED_MOD, 0, 255));
5155
}
56+
57+
StaticText = gui::StaticText::add(Environment, Text.c_str(), core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()), false, false, this, id);
58+
StaticText->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
5259
// END PATCH
5360
}
5461

@@ -262,7 +269,7 @@ void GUIButton::draw()
262269
{
263270
// PATCH
264271
skin->drawColored3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect,
265-
Environment->getHovered() == this ? HoveredColors : Colors);
272+
isHovered() ? HoveredColors : Colors);
266273
// END PATCH
267274
}
268275
else
@@ -318,7 +325,7 @@ void GUIButton::draw()
318325
drawSprite(state, FocusTime, pos);
319326

320327
// mouse over / off animation
321-
state = Environment->getHovered() == this ? EGBS_BUTTON_MOUSE_OVER : EGBS_BUTTON_MOUSE_OFF;
328+
state = isHovered() ? EGBS_BUTTON_MOUSE_OVER : EGBS_BUTTON_MOUSE_OFF;
322329
drawSprite(state, HoverTime, pos);
323330
}
324331
else
@@ -328,23 +335,6 @@ void GUIButton::draw()
328335
}
329336
}
330337

331-
if (Text.size())
332-
{
333-
IGUIFont* font = getActiveFont();
334-
335-
core::rect<s32> rect = AbsoluteRect;
336-
if (Pressed)
337-
{
338-
rect.UpperLeftCorner.X += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_X);
339-
rect.UpperLeftCorner.Y += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y);
340-
}
341-
342-
if (font)
343-
font->draw(Text.c_str(), rect,
344-
OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT),
345-
true, true, &AbsoluteClippingRect);
346-
}
347-
348338
IGUIElement::draw();
349339
}
350340

@@ -371,11 +361,18 @@ void GUIButton::drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::p
371361
}
372362

373363
EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const
364+
{
365+
// PATCH
366+
return getImageState(pressed, ButtonImages);
367+
// END PATCH
368+
}
369+
370+
EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed, const ButtonImage* images) const
374371
{
375372
// figure state we should have
376373
EGUI_BUTTON_IMAGE_STATE state = EGBIS_IMAGE_DISABLED;
377374
bool focused = Environment->hasFocus((IGUIElement*)this);
378-
bool mouseOver = static_cast<const IGUIElement*>(Environment->getHovered()) == this; // (static cast for Borland)
375+
bool mouseOver = isHovered();
379376
if (isEnabled())
380377
{
381378
if ( pressed )
@@ -403,7 +400,7 @@ EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const
403400
}
404401

405402
// find a compatible state that has images
406-
while ( state != EGBIS_IMAGE_UP && !ButtonImages[(u32)state].Texture )
403+
while ( state != EGBIS_IMAGE_UP && !images[(u32)state].Texture )
407404
{
408405
// PATCH
409406
switch ( state )
@@ -451,6 +448,8 @@ void GUIButton::setOverrideFont(IGUIFont* font)
451448

452449
if (OverrideFont)
453450
OverrideFont->grab();
451+
452+
StaticText->setOverrideFont(font);
454453
}
455454

456455
//! Gets the override font (if any)
@@ -475,6 +474,8 @@ void GUIButton::setOverrideColor(video::SColor color)
475474
{
476475
OverrideColor = color;
477476
OverrideColorEnabled = true;
477+
478+
StaticText->setOverrideColor(color);
478479
}
479480

480481
video::SColor GUIButton::getOverrideColor() const
@@ -540,6 +541,14 @@ void GUIButton::setHoveredImage(video::ITexture* image, const core::rect<s32>& p
540541
setImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image, pos);
541542
setImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image, pos);
542543
}
544+
545+
//! Sets the text displayed by the button
546+
void GUIButton::setText(const wchar_t* text)
547+
{
548+
StaticText->setText(text);
549+
550+
IGUIButton::setText(text);
551+
}
543552
// END PATCH
544553

545554
//! Sets if the button should behave like a push button. Which means it
@@ -557,6 +566,14 @@ bool GUIButton::isPressed() const
557566
return Pressed;
558567
}
559568

569+
// PATCH
570+
//! Returns if this element (or one of its direct children) is hovered
571+
bool GUIButton::isHovered() const
572+
{
573+
IGUIElement *hovered = Environment->getHovered();
574+
return hovered == this || (hovered != nullptr && hovered->getParent() == this);
575+
}
576+
// END PATCH
560577

561578
//! Sets the pressed state of the button if this is a pushbutton
562579
void GUIButton::setPressed(bool pressed)
@@ -565,6 +582,24 @@ void GUIButton::setPressed(bool pressed)
565582
{
566583
ClickTime = porting::getTimeMs();
567584
Pressed = pressed;
585+
586+
GUISkin* skin = dynamic_cast<GUISkin*>(Environment->getSkin());
587+
588+
for(IGUIElement *child : getChildren())
589+
{
590+
core::rect<s32> originalRect = child->getRelativePosition();
591+
if (Pressed) {
592+
child->setRelativePosition(originalRect +
593+
core::dimension2d<s32>(
594+
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),
595+
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y)));
596+
} else {
597+
child->setRelativePosition(originalRect -
598+
core::dimension2d<s32>(
599+
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),
600+
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y)));
601+
}
602+
}
568603
}
569604
}
570605

@@ -722,4 +757,42 @@ void GUIButton::setPressedColor(video::SColor color)
722757
PressedColors[i] = base.getInterpolated(color, d);
723758
}
724759
}
760+
761+
//! Set element properties from a StyleSpec
762+
void GUIButton::setFromStyle(const StyleSpec& style, ISimpleTextureSource *tsrc)
763+
{
764+
if (style.isNotDefault(StyleSpec::BGCOLOR)) {
765+
setColor(style.getColor(StyleSpec::BGCOLOR));
766+
}
767+
if (style.isNotDefault(StyleSpec::BGCOLOR_HOVERED)) {
768+
setHoveredColor(style.getColor(StyleSpec::BGCOLOR_HOVERED));
769+
}
770+
if (style.isNotDefault(StyleSpec::BGCOLOR_PRESSED)) {
771+
setPressedColor(style.getColor(StyleSpec::BGCOLOR_PRESSED));
772+
}
773+
774+
if (style.isNotDefault(StyleSpec::TEXTCOLOR)) {
775+
setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR));
776+
}
777+
setNotClipped(style.getBool(StyleSpec::NOCLIP, isNotClipped()));
778+
setDrawBorder(style.getBool(StyleSpec::BORDER, DrawBorder));
779+
setUseAlphaChannel(style.getBool(StyleSpec::ALPHA, true));
780+
781+
if (style.isNotDefault(StyleSpec::BGIMG)) {
782+
video::ITexture *texture = style.getTexture(StyleSpec::BGIMG, tsrc);
783+
video::ITexture *hovered_texture = style.getTexture(StyleSpec::BGIMG_HOVERED, tsrc, texture);
784+
video::ITexture *pressed_texture = style.getTexture(StyleSpec::BGIMG_PRESSED, tsrc, texture);
785+
786+
const core::position2di buttonCenter(AbsoluteRect.getCenter());
787+
core::position2d<s32> geom(buttonCenter);
788+
789+
setImage(guiScalingImageButton(
790+
Environment->getVideoDriver(), texture, geom.X, geom.Y));
791+
setHoveredImage(guiScalingImageButton(
792+
Environment->getVideoDriver(), hovered_texture, geom.X, geom.Y));
793+
setPressedImage(guiScalingImageButton(
794+
Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));
795+
setScaleImage(true);
796+
}
797+
}
725798
// END PATCH

0 commit comments

Comments
 (0)
Please sign in to comment.