]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/gui/guiButton.cpp
This is the last try for lint...
[dragonfireclient.git] / src / gui / guiButton.cpp
index 4c16ee2376a79a189b81b3e9aa8571c666c8dcd6..e0d6337cdadca382224e41b09e6edaa7128b74b5 100644 (file)
@@ -14,6 +14,7 @@
 #include "irrlicht_changes/static_text.h"\r
 #include "porting.h"\r
 #include "StyleSpec.h"\r
+#include "util/numeric.h"\r
 \r
 using namespace irr;\r
 using namespace gui;\r
@@ -26,14 +27,15 @@ using namespace gui;
 \r
 //! constructor\r
 GUIButton::GUIButton(IGUIEnvironment* environment, IGUIElement* parent,\r
-                       s32 id, core::rect<s32> rectangle, bool noclip)\r
+                       s32 id, core::rect<s32> rectangle, ISimpleTextureSource *tsrc,\r
+                       bool noclip)\r
 : IGUIButton(environment, parent, id, rectangle),\r
        SpriteBank(0), OverrideFont(0),\r
        OverrideColorEnabled(false), OverrideColor(video::SColor(101,255,255,255)),\r
        ClickTime(0), HoverTime(0), FocusTime(0),\r
        ClickShiftState(false), ClickControlState(false),\r
        IsPushButton(false), Pressed(false),\r
-       UseAlphaChannel(false), DrawBorder(true), ScaleImage(false)\r
+       UseAlphaChannel(false), DrawBorder(true), ScaleImage(false), TSrc(tsrc)\r
 {\r
        setNotClipped(noclip);\r
 \r
@@ -44,14 +46,6 @@ GUIButton::GUIButton(IGUIEnvironment* environment, IGUIElement* parent,
        // PATCH\r
        for (size_t i = 0; i < 4; i++) {\r
                Colors[i] = Environment->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);\r
-               HoveredColors[i] = irr::video::SColor(Colors[i].getAlpha(),\r
-                       core::clamp<u32>(Colors[i].getRed() * COLOR_HOVERED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getGreen() * COLOR_HOVERED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getBlue() * COLOR_HOVERED_MOD, 0, 255));\r
-               PressedColors[i] = irr::video::SColor(Colors[i].getAlpha(),\r
-                       core::clamp<u32>(Colors[i].getRed() * COLOR_PRESSED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getGreen() * COLOR_PRESSED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getBlue() * COLOR_PRESSED_MOD, 0, 255));\r
        }\r
        StaticText = gui::StaticText::add(Environment, Text.c_str(), core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()), false, false, this, id);\r
        StaticText->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);\r
@@ -262,6 +256,13 @@ void GUIButton::draw()
                return;\r
 \r
        // PATCH\r
+       // Track hovered state, if it has changed then we need to update the style.\r
+       bool hovered = isHovered();\r
+       if (hovered != WasHovered) {\r
+               WasHovered = hovered;\r
+               setFromState();\r
+       }\r
+\r
        GUISkin* skin = dynamic_cast<GUISkin*>(Environment->getSkin());\r
        video::IVideoDriver* driver = Environment->getVideoDriver();\r
        // END PATCH\r
@@ -271,21 +272,24 @@ void GUIButton::draw()
                if (!Pressed)\r
                {\r
                        // PATCH\r
-                       skin->drawColored3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect,\r
-                               isHovered() ? HoveredColors : Colors);\r
+                       skin->drawColored3DButtonPaneStandard(this, AbsoluteRect,\r
+                                       &AbsoluteClippingRect, Colors);\r
                        // END PATCH\r
                }\r
                else\r
                {\r
                        // PATCH\r
-                       skin->drawColored3DButtonPanePressed(this,\r
-                                       AbsoluteRect, &AbsoluteClippingRect, PressedColors);\r
+                       skin->drawColored3DButtonPanePressed(this, AbsoluteRect,\r
+                                       &AbsoluteClippingRect, Colors);\r
                        // END PATCH\r
                }\r
        }\r
 \r
        const core::position2di buttonCenter(AbsoluteRect.getCenter());\r
-       EGUI_BUTTON_IMAGE_STATE imageState = getImageState(Pressed);\r
+       // PATCH\r
+       // The image changes based on the state, so we use the default every time.\r
+       EGUI_BUTTON_IMAGE_STATE imageState = EGBIS_IMAGE_UP;\r
+       // END PATCH\r
        if ( ButtonImages[(u32)imageState].Texture )\r
        {\r
                core::position2d<s32> pos(buttonCenter);\r
@@ -548,18 +552,6 @@ void GUIButton::setPressedImage(video::ITexture* image, const core::rect<s32>& p
        setImage(gui::EGBIS_IMAGE_DOWN, image, pos);\r
 }\r
 \r
-void GUIButton::setHoveredImage(video::ITexture* image)\r
-{\r
-       setImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image);\r
-       setImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image);\r
-}\r
-\r
-void GUIButton::setHoveredImage(video::ITexture* image, const core::rect<s32>& pos)\r
-{\r
-       setImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image, pos);\r
-       setImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image, pos);\r
-}\r
-\r
 //! Sets the text displayed by the button\r
 void GUIButton::setText(const wchar_t* text)\r
 {\r
@@ -600,24 +592,7 @@ void GUIButton::setPressed(bool pressed)
        {\r
                ClickTime = porting::getTimeMs();\r
                Pressed = pressed;\r
-\r
-               GUISkin* skin = dynamic_cast<GUISkin*>(Environment->getSkin());\r
-\r
-               for(IGUIElement *child : getChildren())\r
-               {\r
-                       core::rect<s32> originalRect = child->getRelativePosition();\r
-                       if (Pressed) {\r
-                               child->setRelativePosition(originalRect +\r
-                                               core::dimension2d<s32>(\r
-                                                       skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),\r
-                                                       skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y)));\r
-                       } else {\r
-                               child->setRelativePosition(originalRect -\r
-                                               core::dimension2d<s32>(\r
-                                                       skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),\r
-                                                       skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y)));\r
-                       }\r
-               }\r
+               setFromState();\r
        }\r
 }\r
 \r
@@ -729,10 +704,12 @@ void GUIButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWri
 }\r
 \r
 // PATCH\r
-GUIButton* GUIButton::addButton(IGUIEnvironment *environment, const core::rect<s32>& rectangle,\r
-                                                               IGUIElement* parent, s32 id, const wchar_t* text, const wchar_t *tooltiptext)\r
+GUIButton* GUIButton::addButton(IGUIEnvironment *environment,\r
+               const core::rect<s32>& rectangle, ISimpleTextureSource *tsrc,\r
+               IGUIElement* parent, s32 id, const wchar_t* text,\r
+               const wchar_t *tooltiptext)\r
 {\r
-       GUIButton* button = new GUIButton(environment, parent ? parent : environment->getRootGUIElement(), id, rectangle);\r
+       GUIButton* button = new GUIButton(environment, parent ? parent : environment->getRootGUIElement(), id, rectangle, tsrc);\r
        if (text)\r
                button->setText(text);\r
 \r
@@ -749,76 +726,112 @@ void GUIButton::setColor(video::SColor color)
        for (size_t i = 0; i < 4; i++) {\r
                video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);\r
                Colors[i] = base.getInterpolated(color, d);\r
-               HoveredColors[i] = irr::video::SColor(Colors[i].getAlpha(),\r
-                       core::clamp<u32>(Colors[i].getRed() * COLOR_HOVERED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getGreen() * COLOR_HOVERED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getBlue() * COLOR_HOVERED_MOD, 0, 255));\r
-               PressedColors[i] = irr::video::SColor(Colors[i].getAlpha(),\r
-                       core::clamp<u32>(Colors[i].getRed() * COLOR_PRESSED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getGreen() * COLOR_PRESSED_MOD, 0, 255),\r
-                       core::clamp<u32>(Colors[i].getBlue() * COLOR_PRESSED_MOD, 0, 255));\r
        }\r
 }\r
-void GUIButton::setHoveredColor(video::SColor color)\r
-{\r
-       float d = 0.65f;\r
-       for (size_t i = 0; i < 4; i++) {\r
-               video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);\r
-               HoveredColors[i] = base.getInterpolated(color, d);\r
-       }\r
-}\r
-void GUIButton::setPressedColor(video::SColor color)\r
+\r
+//! Set element properties from a StyleSpec corresponding to the button state\r
+void GUIButton::setFromState()\r
 {\r
-       float d = 0.65f;\r
-       for (size_t i = 0; i < 4; i++) {\r
-               video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);\r
-               PressedColors[i] = base.getInterpolated(color, d);\r
-       }\r
+       StyleSpec::State state = StyleSpec::STATE_DEFAULT;\r
+\r
+       if (isPressed())\r
+               state = static_cast<StyleSpec::State>(state | StyleSpec::STATE_PRESSED);\r
+\r
+       if (isHovered())\r
+               state = static_cast<StyleSpec::State>(state | StyleSpec::STATE_HOVERED);\r
+\r
+       setFromStyle(StyleSpec::getStyleFromStatePropagation(Styles, state));\r
 }\r
 \r
 //! Set element properties from a StyleSpec\r
-void GUIButton::setFromStyle(const StyleSpec& style, ISimpleTextureSource *tsrc)\r
+void GUIButton::setFromStyle(const StyleSpec& style)\r
 {\r
+       bool hovered = (style.getState() & StyleSpec::STATE_HOVERED) != 0;\r
+       bool pressed = (style.getState() & StyleSpec::STATE_PRESSED) != 0;\r
+\r
        if (style.isNotDefault(StyleSpec::BGCOLOR)) {\r
+\r
                setColor(style.getColor(StyleSpec::BGCOLOR));\r
-       }\r
-       if (style.isNotDefault(StyleSpec::BGCOLOR_HOVERED)) {\r
-               setHoveredColor(style.getColor(StyleSpec::BGCOLOR_HOVERED));\r
-       }\r
-       if (style.isNotDefault(StyleSpec::BGCOLOR_PRESSED)) {\r
-               setPressedColor(style.getColor(StyleSpec::BGCOLOR_PRESSED));\r
+\r
+               // If we have a propagated hover/press color, we need to automatically\r
+               // lighten/darken it\r
+               if (!Styles[style.getState()].isNotDefault(StyleSpec::BGCOLOR)) {\r
+                       for (size_t i = 0; i < 4; i++) {\r
+                               if (pressed) {\r
+                                       Colors[i] = multiplyColorValue(Colors[i], COLOR_PRESSED_MOD);\r
+                               } else if (hovered) {\r
+                                       Colors[i] = multiplyColorValue(Colors[i], COLOR_HOVERED_MOD);\r
+                               }\r
+                       }\r
+               }\r
+\r
+       } else {\r
+               for (size_t i = 0; i < 4; i++) {\r
+                       video::SColor base =\r
+                                       Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);\r
+                       if (pressed) {\r
+                               Colors[i] = multiplyColorValue(base, COLOR_PRESSED_MOD);\r
+                       } else if (hovered) {\r
+                               Colors[i] = multiplyColorValue(base, COLOR_HOVERED_MOD);\r
+                       } else {\r
+                               Colors[i] = base;\r
+                       }\r
+               }\r
        }\r
 \r
        if (style.isNotDefault(StyleSpec::TEXTCOLOR)) {\r
                setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR));\r
+       } else {\r
+               setOverrideColor(video::SColor(255,255,255,255));\r
+               OverrideColorEnabled = false;\r
        }\r
-       setNotClipped(style.getBool(StyleSpec::NOCLIP, isNotClipped()));\r
-       setDrawBorder(style.getBool(StyleSpec::BORDER, DrawBorder));\r
+       setNotClipped(style.getBool(StyleSpec::NOCLIP, false));\r
+       setDrawBorder(style.getBool(StyleSpec::BORDER, true));\r
        setUseAlphaChannel(style.getBool(StyleSpec::ALPHA, true));\r
+       setOverrideFont(style.getFont());\r
 \r
-       const core::position2di buttonCenter(AbsoluteRect.getCenter());\r
-       core::position2d<s32> geom(buttonCenter);\r
        if (style.isNotDefault(StyleSpec::BGIMG)) {\r
-               video::ITexture *texture = style.getTexture(StyleSpec::BGIMG, tsrc);\r
-\r
+               video::ITexture *texture = style.getTexture(StyleSpec::BGIMG,\r
+                               getTextureSource());\r
                setImage(guiScalingImageButton(\r
-                                       Environment->getVideoDriver(), texture, geom.X, geom.Y));\r
+                               Environment->getVideoDriver(), texture,\r
+                                               AbsoluteRect.getWidth(), AbsoluteRect.getHeight()));\r
                setScaleImage(true);\r
+       } else {\r
+               setImage(nullptr);\r
        }\r
-       if (style.isNotDefault(StyleSpec::BGIMG_HOVERED)) {\r
-               video::ITexture *hovered_texture = style.getTexture(StyleSpec::BGIMG_HOVERED, tsrc);\r
 \r
-               setHoveredImage(guiScalingImageButton(\r
-                                       Environment->getVideoDriver(), hovered_texture, geom.X, geom.Y));\r
-               setScaleImage(true);\r
-       }\r
-       if (style.isNotDefault(StyleSpec::BGIMG_PRESSED)) {\r
-               video::ITexture *pressed_texture = style.getTexture(StyleSpec::BGIMG_PRESSED, tsrc);\r
+       BgMiddle = style.getRect(StyleSpec::BGIMG_MIDDLE, BgMiddle);\r
 \r
-               setPressedImage(guiScalingImageButton(\r
-                                       Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));\r
-               setScaleImage(true);\r
+       // Child padding and offset\r
+       Padding = style.getRect(StyleSpec::PADDING, core::rect<s32>());\r
+       Padding = core::rect<s32>(\r
+                       Padding.UpperLeftCorner + BgMiddle.UpperLeftCorner,\r
+                       Padding.LowerRightCorner + BgMiddle.LowerRightCorner);\r
+\r
+       GUISkin* skin = dynamic_cast<GUISkin*>(Environment->getSkin());\r
+       core::vector2d<s32> defaultPressOffset(\r
+                       skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),\r
+                       skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y));\r
+       ContentOffset = style.getVector2i(StyleSpec::CONTENT_OFFSET, isPressed()\r
+                       ? defaultPressOffset\r
+                       : core::vector2d<s32>(0));\r
+\r
+       core::rect<s32> childBounds(\r
+                               Padding.UpperLeftCorner.X + ContentOffset.X,\r
+                               Padding.UpperLeftCorner.Y + ContentOffset.Y,\r
+                               AbsoluteRect.getWidth() + Padding.LowerRightCorner.X + ContentOffset.X,\r
+                               AbsoluteRect.getHeight() + Padding.LowerRightCorner.Y + ContentOffset.Y);\r
+\r
+       for (IGUIElement *child : getChildren()) {\r
+               child->setRelativePosition(childBounds);\r
        }\r
-       BgMiddle = style.getRect(StyleSpec::BGIMG_MIDDLE, BgMiddle);\r
+}\r
+\r
+//! Set the styles used for each state\r
+void GUIButton::setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES>& styles)\r
+{\r
+       Styles = styles;\r
+       setFromState();\r
 }\r
 // END PATCH\r