diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index 018323d81..278817772 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -1512,13 +1512,13 @@ void Skin::drawIconButton(const core::recti &rect, Widget* widget, SColor(100,255,255,255), SColor(100,255,255,255) }; core::recti r(0,0,icon_widget->m_texture_w, icon_widget->m_texture_h); - draw2DImage(icon_widget->m_texture, sized_rect, + draw2DImage(icon_widget->getTexture(), sized_rect, r, 0 /* no clipping */, colors, true /* alpha */); } else { - video::ITexture* t = icon_widget->m_texture; + const video::ITexture* t = icon_widget->getTexture(); const bool mouseInside = rect.isPointInside(irr_driver->getDevice()->getCursorControl() diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index ade962bb0..368a23ad1 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -41,8 +41,12 @@ IconButtonWidget::IconButtonWidget(ScaleMode scale_mode, const bool tab_stop, m_label = NULL; m_texture = NULL; m_highlight_texture = NULL; + m_deactivated_texture = NULL; m_custom_aspect_ratio = 1.0f; + m_texture_w = 0; + m_texture_h = 0; + m_tab_stop = tab_stop; m_focusable = focusable; m_scale_mode = scale_mode; @@ -57,12 +61,12 @@ void IconButtonWidget::add() { if (m_icon_path_type == ICON_PATH_TYPE_ABSOLUTE) { - m_texture = irr_driver->getTexture(m_properties[PROP_ICON]); + setTexture(irr_driver->getTexture(m_properties[PROP_ICON])); } else if (m_icon_path_type == ICON_PATH_TYPE_RELATIVE) { std::string file = file_manager->getAsset(m_properties[PROP_ICON]); - m_texture = irr_driver->getTexture(file); + setTexture(irr_driver->getTexture(file)); } } @@ -72,13 +76,11 @@ void IconButtonWidget::add() "add() : error, cannot find texture '%s'.", m_properties[PROP_ICON].c_str()); std::string file = file_manager->getAsset(FileManager::GUI,"main_help.png"); - m_texture = irr_driver->getTexture(file); + setTexture(irr_driver->getTexture(file)); if(!m_texture) Log::fatal("IconButtonWidget", "Can't find fallback texture 'gui/main_help.png, aborting."); } - m_texture_w = m_texture->getSize().Width; - m_texture_h = m_texture->getSize().Height; if (m_properties[PROP_FOCUS_ICON].size() > 0) { @@ -207,12 +209,12 @@ void IconButtonWidget::setImage(const char* path_to_texture, IconPathType pathTy if (m_icon_path_type == ICON_PATH_TYPE_ABSOLUTE) { - m_texture = irr_driver->getTexture(m_properties[PROP_ICON]); + setTexture(irr_driver->getTexture(m_properties[PROP_ICON])); } else if (m_icon_path_type == ICON_PATH_TYPE_RELATIVE) { std::string file = file_manager->getAsset(m_properties[PROP_ICON]); - m_texture = irr_driver->getTexture(file); + setTexture(irr_driver->getTexture(file)); } if (!m_texture) @@ -220,11 +222,8 @@ void IconButtonWidget::setImage(const char* path_to_texture, IconPathType pathTy Log::error("icon_button", "Texture '%s' not found!\n", m_properties[PROP_ICON].c_str()); std::string file = file_manager->getAsset(FileManager::GUI,"main_help.png"); - m_texture = irr_driver->getTexture(file); + setTexture(irr_driver->getTexture(file)); } - - m_texture_w = m_texture->getSize().Width; - m_texture_h = m_texture->getSize().Height; } // ----------------------------------------------------------------------------- @@ -233,21 +232,18 @@ void IconButtonWidget::setImage(ITexture* texture) { if (texture != NULL) { - m_texture = texture; - - m_texture_w = m_texture->getSize().Width; - m_texture_h = m_texture->getSize().Height; + setTexture(texture); } else { Log::error("icon_button", "setImage invoked with NULL image pointer\n"); std::string file = file_manager->getAsset(FileManager::GUI,"main_help.png"); - m_texture = irr_driver->getTexture(file); + setTexture(irr_driver->getTexture(file)); } } // ----------------------------------------------------------------------------- -void IconButtonWidget::setLabel(stringw new_label) +void IconButtonWidget::setLabel(const stringw& new_label) { if (m_label == NULL) return; @@ -288,4 +284,52 @@ void IconButtonWidget::unfocused(const int playerID, Widget* new_focus) } } +// ----------------------------------------------------------------------------- +video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture) +{ + SColor c; + u32 g; + video::IVideoDriver* driver = irr_driver->getVideoDriver(); + video::IImage* image = driver->createImageFromData (texture->getColorFormat(), + texture->getSize(), texture->lock(), false); + texture->unlock(); + + //Turn the image into grayscale + for (u32 x = 0; x < image->getDimension().Width; x++) + { + for (u32 y = 0; y < image->getDimension().Height; y++) + { + c = image->getPixel(x, y); + g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3); + c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g); + image->setPixel(x, y, c); + } + } + + texture = driver->addTexture(texture->getName().getPath() + "_disabled", image); + texture->grab(); + + return texture; +} + +// ----------------------------------------------------------------------------- +void IconButtonWidget::setTexture(video::ITexture* texture) +{ + m_texture = texture; + if (texture == NULL) + { + if (m_deactivated_texture != NULL) + m_deactivated_texture->drop(); + + m_deactivated_texture = NULL; + m_texture_w = 0; + m_texture_h = 0; + } + else + { + m_deactivated_texture = getDeactivatedTexture(texture); + m_texture_w = texture->getSize().Width; + m_texture_h = texture->getSize().Height; + } +} diff --git a/src/guiengine/widgets/icon_button_widget.hpp b/src/guiengine/widgets/icon_button_widget.hpp index b64375a34..11af6572f 100644 --- a/src/guiengine/widgets/icon_button_widget.hpp +++ b/src/guiengine/widgets/icon_button_widget.hpp @@ -29,7 +29,6 @@ namespace irr #include "guiengine/widget.hpp" #include "utils/leak_check.hpp" -#include "utils/ptr_vector.hpp" namespace GUIEngine { @@ -38,6 +37,14 @@ namespace GUIEngine */ class IconButtonWidget : public Widget { + private: + irr::video::ITexture* m_texture; + irr::video::ITexture* m_highlight_texture; + irr::video::ITexture* m_deactivated_texture; + int m_texture_w, m_texture_h; + + video::ITexture* getDeactivatedTexture(video::ITexture* texture); + public: enum ScaleMode { @@ -54,42 +61,40 @@ namespace GUIEngine * the path type as it currently is */ ICON_PATH_TYPE_NO_CHANGE }; - - protected: - - IconPathType m_icon_path_type; - - friend class Skin; - - irr::gui::IGUIStaticText* m_label; - irr::video::ITexture* m_texture; - irr::video::ITexture* m_highlight_texture; - int m_texture_w, m_texture_h; - + protected: + + IconPathType m_icon_path_type; + + friend class Skin; + + irr::gui::IGUIStaticText* m_label; + ScaleMode m_scale_mode; float m_custom_aspect_ratio; - + + void setTexture(video::ITexture* texture); + public: LEAK_CHECK() - + /** Whether to make the widget included in keyboard navigation order when adding */ bool m_tab_stop; IconButtonWidget(ScaleMode scale_mode=SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, const bool tab_stop=true, const bool focusable=true, IconPathType pathType=ICON_PATH_TYPE_RELATIVE); virtual ~IconButtonWidget() {} - + /** \brief Implement callback from base class Widget */ virtual void add(); - + /** * \brief Call this if scale mode is SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO. * \param custom_aspect_ratio The width/height aspect ratio */ void setCustomAspectRatio(float custom_aspect_ratio) { m_custom_aspect_ratio = custom_aspect_ratio; } - + /** * \brief Temporarily change the text label if there is a label (next time this screen is * visited, the previous label will be back. For a permanent change, edit the 'text' @@ -98,8 +103,8 @@ namespace GUIEngine * \pre Must be called after this widget is add()ed to have any effect * \note Calling this method on a button without label will have no effect */ - void setLabel(irr::core::stringw new_label); - + void setLabel(const irr::core::stringw& new_label); + /** * Change the texture used for this icon. * \pre At the moment, the new texture must have the same aspct ratio @@ -109,7 +114,7 @@ namespace GUIEngine */ void setImage(const char* path_to_texture, IconPathType path_type=ICON_PATH_TYPE_NO_CHANGE); - // -------------------------------------------------------------------- + // -------------------------------------------------------------------- /** Convenience function taking std::string. */ void setImage(const std::string &path_to_texture, IconPathType path_type=ICON_PATH_TYPE_NO_CHANGE) @@ -126,23 +131,24 @@ namespace GUIEngine * \note May safely be called no matter if the widget is add()ed or not */ void setImage(irr::video::ITexture* texture); - + // -------------------------------------------------------------------- void setHighlightedImage(irr::video::ITexture* texture) { m_highlight_texture = texture; } - + // -------------------------------------------------------------------- /** \brief override from base class */ virtual EventPropagation focused(const int playerID); - + // -------------------------------------------------------------------- /** \brief override from base class */ virtual void unfocused(const int playerID, Widget* new_focus); // -------------------------------------------------------------------- /** Returns the texture of this button. */ - const video::ITexture* getTexture() const { return m_texture; } + const video::ITexture* getTexture() const { + return (Widget::isActivated() ? m_texture : m_deactivated_texture); } }; }