Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Refactor to centralize GUIButton styling/rendering code (#9090)
  • Loading branch information
Df458 authored and rubenwardy committed Dec 9, 2019
1 parent a462181 commit 9284313
Show file tree
Hide file tree
Showing 18 changed files with 522 additions and 145 deletions.
2 changes: 2 additions & 0 deletions build/android/jni/Android.mk
Expand Up @@ -181,6 +181,8 @@ LOCAL_SRC_FILES := \
jni/src/gui/guiBackgroundImage.cpp \
jni/src/gui/guiBox.cpp \
jni/src/gui/guiButton.cpp \
jni/src/gui/guiButtonImage.cpp \
jni/src/gui/guiButtonItemImage.cpp \
jni/src/gui/guiChatConsole.cpp \
jni/src/gui/guiConfirmRegistration.cpp \
jni/src/gui/guiEditBoxWithScrollbar.cpp \
Expand Down
22 changes: 10 additions & 12 deletions doc/lua_api.txt
Expand Up @@ -2541,20 +2541,20 @@ Some types may inherit styles from parent types.
* label
* vertlabel, inherits from field
* image_button
* item_image_button, inherits from image_button
* item_image_button
* tabheader


### Valid Properties

* button, button_exit
* button, button_exit, image_button, item_image_button
* alpha - boolean, whether to draw alpha in bgimg. Default true.
* bgcolor - color, sets button tint.
* bgcolor_hovered - color when hovered. Defaults to a lighter bgcolor when not provided.
* bgcolor_pressed - color when pressed. Defaults to a darker bgcolor when not provided.
* bgimg - standard image. Defaults to none.
* bgimg_hovered - image when hovered. Defaults to bgimg when not provided.
* bgimg_pressed - image when pressed. Defaults to bgimg when not provided.
* bgimg - standard background image. Defaults to none.
* bgimg_hovered - background image when hovered. Defaults to bgimg when not provided.
* bgimg_pressed - background image when pressed. Defaults to bgimg when not provided.
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* textcolor - color, default white.
Expand All @@ -2572,13 +2572,11 @@ Some types may inherit styles from parent types.
* textcolor - color. Default white.
* label, vertlabel
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* image_button
* alpha - boolean, whether to draw alpha in bgimg. Default true.
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default false.
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* item_image_button
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default false.
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* image_button (additional properties)
* fgimg - standard image. Defaults to none.
* fgimg_hovered - image when hovered. Defaults to fgimg when not provided.
* fgimg_pressed - image when pressed. Defaults to fgimg when not provided.
* NOTE: The parameters of any given image_button will take precedence over fgimg/fgimg_pressed
* tabheader
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
* textcolor - color. Default white.
Expand Down
7 changes: 7 additions & 0 deletions games/minimal/mods/test/formspec.lua
Expand Up @@ -70,6 +70,13 @@ local style_fs = [[
style[one_btn13;border=false]
item_image_button[1.25,8.35;1,1;default:sword_steel;one_btn13;NoBor]
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]
image_button[0,9.6;1,1;bubble.png;one_btn14;Bg]
style[one_btn15;border=false;bgimg=test_bg.png;bgimg_hovered=test_bg_hovered.png;bgimg_pressed=test_bg_pressed.png]
item_image_button[1.25,9.6;1,1;default:sword_steel;one_btn15;Bg]
container[2.75,0]
Expand Down
Binary file added games/minimal/mods/test/textures/test_bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added games/minimal/mods/test/textures/test_bg_hovered.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added games/minimal/mods/test/textures/test_bg_pressed.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -2,6 +2,8 @@ set(gui_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/guiBackgroundImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiBox.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiButton.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp
Expand Down
34 changes: 34 additions & 0 deletions src/gui/StyleSpec.h
Expand Up @@ -17,7 +17,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "client/tile.h" // ITextureSource
#include "irrlichttypes_extrabloated.h"
#include "util/string.h"
#include <array>

#pragma once
Expand All @@ -36,6 +38,9 @@ class StyleSpec
BGIMG,
BGIMG_HOVERED,
BGIMG_PRESSED,
FGIMG,
FGIMG_HOVERED,
FGIMG_PRESSED,
ALPHA,
NUM_PROPERTIES,
NONE
Expand Down Expand Up @@ -66,6 +71,12 @@ class StyleSpec
return BGIMG_HOVERED;
} else if (name == "bgimg_pressed") {
return BGIMG_PRESSED;
} else if (name == "fgimg") {
return FGIMG;
} else if (name == "fgimg_hovered") {
return FGIMG_HOVERED;
} else if (name == "fgimg_pressed") {
return FGIMG_PRESSED;
} else if (name == "alpha") {
return ALPHA;
} else {
Expand Down Expand Up @@ -106,6 +117,29 @@ class StyleSpec
return color;
}

video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc,
video::ITexture *def) const
{
const auto &val = properties[prop];
if (val.empty()) {
return def;
}

video::ITexture *texture = tsrc->getTexture(val);

return texture;
}

video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc) const
{
const auto &val = properties[prop];
FATAL_ERROR_IF(val.empty(), "Unexpected missing property");

video::ITexture *texture = tsrc->getTexture(val);

return texture;
}

bool getBool(Property prop, bool def) const
{
const auto &val = properties[prop];
Expand Down
115 changes: 94 additions & 21 deletions src/gui/guiButton.cpp
Expand Up @@ -5,11 +5,15 @@
#include "guiButton.h"


#include "client/guiscalingfilter.h"
#include "client/tile.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "IGUIFont.h"
#include "irrlicht_changes/static_text.h"
#include "porting.h"
#include "StyleSpec.h"

using namespace irr;
using namespace gui;
Expand Down Expand Up @@ -49,6 +53,9 @@ GUIButton::GUIButton(IGUIEnvironment* environment, IGUIElement* parent,
core::clamp<u32>(Colors[i].getGreen() * COLOR_PRESSED_MOD, 0, 255),
core::clamp<u32>(Colors[i].getBlue() * COLOR_PRESSED_MOD, 0, 255));
}

StaticText = gui::StaticText::add(Environment, Text.c_str(), core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()), false, false, this, id);
StaticText->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
// END PATCH
}

Expand Down Expand Up @@ -262,7 +269,7 @@ void GUIButton::draw()
{
// PATCH
skin->drawColored3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect,
Environment->getHovered() == this ? HoveredColors : Colors);
isHovered() ? HoveredColors : Colors);
// END PATCH
}
else
Expand Down Expand Up @@ -318,7 +325,7 @@ void GUIButton::draw()
drawSprite(state, FocusTime, pos);

// mouse over / off animation
state = Environment->getHovered() == this ? EGBS_BUTTON_MOUSE_OVER : EGBS_BUTTON_MOUSE_OFF;
state = isHovered() ? EGBS_BUTTON_MOUSE_OVER : EGBS_BUTTON_MOUSE_OFF;
drawSprite(state, HoverTime, pos);
}
else
Expand All @@ -328,23 +335,6 @@ void GUIButton::draw()
}
}

if (Text.size())
{
IGUIFont* font = getActiveFont();

core::rect<s32> rect = AbsoluteRect;
if (Pressed)
{
rect.UpperLeftCorner.X += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_X);
rect.UpperLeftCorner.Y += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y);
}

if (font)
font->draw(Text.c_str(), rect,
OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT),
true, true, &AbsoluteClippingRect);
}

IGUIElement::draw();
}

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

EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed) const
{
// PATCH
return getImageState(pressed, ButtonImages);
// END PATCH
}

EGUI_BUTTON_IMAGE_STATE GUIButton::getImageState(bool pressed, const ButtonImage* images) const
{
// figure state we should have
EGUI_BUTTON_IMAGE_STATE state = EGBIS_IMAGE_DISABLED;
bool focused = Environment->hasFocus((IGUIElement*)this);
bool mouseOver = static_cast<const IGUIElement*>(Environment->getHovered()) == this; // (static cast for Borland)
bool mouseOver = isHovered();
if (isEnabled())
{
if ( pressed )
Expand Down Expand Up @@ -403,7 +400,7 @@ 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 )
while ( state != EGBIS_IMAGE_UP && !images[(u32)state].Texture )
{
// PATCH
switch ( state )
Expand Down Expand Up @@ -451,6 +448,8 @@ void GUIButton::setOverrideFont(IGUIFont* font)

if (OverrideFont)
OverrideFont->grab();

StaticText->setOverrideFont(font);
}

//! Gets the override font (if any)
Expand All @@ -475,6 +474,8 @@ void GUIButton::setOverrideColor(video::SColor color)
{
OverrideColor = color;
OverrideColorEnabled = true;

StaticText->setOverrideColor(color);
}

video::SColor GUIButton::getOverrideColor() const
Expand Down Expand Up @@ -540,6 +541,14 @@ void GUIButton::setHoveredImage(video::ITexture* image, const core::rect<s32>& p
setImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image, pos);
setImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image, pos);
}

//! Sets the text displayed by the button
void GUIButton::setText(const wchar_t* text)
{
StaticText->setText(text);

IGUIButton::setText(text);
}
// END PATCH

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

// PATCH
//! Returns if this element (or one of its direct children) is hovered
bool GUIButton::isHovered() const
{
IGUIElement *hovered = Environment->getHovered();
return hovered == this || (hovered != nullptr && hovered->getParent() == this);
}
// END PATCH

//! Sets the pressed state of the button if this is a pushbutton
void GUIButton::setPressed(bool pressed)
Expand All @@ -565,6 +582,24 @@ void GUIButton::setPressed(bool pressed)
{
ClickTime = porting::getTimeMs();
Pressed = pressed;

GUISkin* skin = dynamic_cast<GUISkin*>(Environment->getSkin());

for(IGUIElement *child : getChildren())
{
core::rect<s32> originalRect = child->getRelativePosition();
if (Pressed) {
child->setRelativePosition(originalRect +
core::dimension2d<s32>(
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y)));
} else {
child->setRelativePosition(originalRect -
core::dimension2d<s32>(
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y)));
}
}
}
}

Expand Down Expand Up @@ -722,4 +757,42 @@ void GUIButton::setPressedColor(video::SColor color)
PressedColors[i] = base.getInterpolated(color, d);
}
}

//! Set element properties from a StyleSpec
void GUIButton::setFromStyle(const StyleSpec& style, ISimpleTextureSource *tsrc)
{
if (style.isNotDefault(StyleSpec::BGCOLOR)) {
setColor(style.getColor(StyleSpec::BGCOLOR));
}
if (style.isNotDefault(StyleSpec::BGCOLOR_HOVERED)) {
setHoveredColor(style.getColor(StyleSpec::BGCOLOR_HOVERED));
}
if (style.isNotDefault(StyleSpec::BGCOLOR_PRESSED)) {
setPressedColor(style.getColor(StyleSpec::BGCOLOR_PRESSED));
}

if (style.isNotDefault(StyleSpec::TEXTCOLOR)) {
setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR));
}
setNotClipped(style.getBool(StyleSpec::NOCLIP, isNotClipped()));
setDrawBorder(style.getBool(StyleSpec::BORDER, DrawBorder));
setUseAlphaChannel(style.getBool(StyleSpec::ALPHA, true));

if (style.isNotDefault(StyleSpec::BGIMG)) {
video::ITexture *texture = style.getTexture(StyleSpec::BGIMG, tsrc);
video::ITexture *hovered_texture = style.getTexture(StyleSpec::BGIMG_HOVERED, tsrc, texture);
video::ITexture *pressed_texture = style.getTexture(StyleSpec::BGIMG_PRESSED, tsrc, texture);

const core::position2di buttonCenter(AbsoluteRect.getCenter());
core::position2d<s32> geom(buttonCenter);

setImage(guiScalingImageButton(
Environment->getVideoDriver(), texture, geom.X, geom.Y));
setHoveredImage(guiScalingImageButton(
Environment->getVideoDriver(), hovered_texture, geom.X, geom.Y));
setPressedImage(guiScalingImageButton(
Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));
setScaleImage(true);
}
}
// END PATCH

0 comments on commit 9284313

Please sign in to comment.