64 changes: 42 additions & 22 deletions src/gui/guiButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "IrrCompileConfig.h"

#include <IGUIStaticText.h>
#include "irrlicht_changes/static_text.h"
#include "IGUIButton.h"
#include "IGUISpriteBank.h"
#include "ITexture.h"
Expand Down Expand Up @@ -64,6 +66,9 @@ using namespace irr;

#endif

class ISimpleTextureSource;
class StyleSpec;

class GUIButton : public gui::IGUIButton
{
public:
Expand Down Expand Up @@ -122,6 +127,9 @@ class GUIButton : public gui::IGUIButton

//! Sets an image which should be displayed on the button when it is in hovered state.
virtual void setHoveredImage(video::ITexture* image=nullptr);

//! Sets the text displayed by the button
virtual void setText(const wchar_t* text) override;
// END PATCH

//! Sets an image which should be displayed on the button when it is in hovered state.
Expand Down Expand Up @@ -172,6 +180,11 @@ class GUIButton : public gui::IGUIButton
//! Returns if the button is currently pressed
virtual bool isPressed() const override;

// PATCH
//! Returns if this element (or one of its direct children) is hovered
bool isHovered() const;
// END PATCH

//! Sets if the button should use the skin to draw its border
virtual void setDrawBorder(bool border=true) override;

Expand Down Expand Up @@ -214,6 +227,9 @@ class GUIButton : public gui::IGUIButton
// PATCH
void setHoveredColor(video::SColor color);
void setPressedColor(video::SColor color);

//! Set element properties from a StyleSpec
virtual void setFromStyle(const StyleSpec& style, ISimpleTextureSource *tsrc);
// END PATCH


Expand All @@ -225,28 +241,6 @@ class GUIButton : public gui::IGUIButton
void drawSprite(gui::EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center);
gui::EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed) const;

private:

struct ButtonSprite
{
ButtonSprite() : Index(-1), Loop(false), Scale(false)
{
}

bool operator==(const ButtonSprite& other) const
{
return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale;
}

s32 Index;
video::SColor Color;
bool Loop;
bool Scale;
};

ButtonSprite ButtonSprites[gui::EGBS_COUNT];
gui::IGUISpriteBank* SpriteBank;

struct ButtonImage
{
ButtonImage() : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
Expand Down Expand Up @@ -288,6 +282,30 @@ class GUIButton : public gui::IGUIButton
core::rect<s32> SourceRect;
};

gui::EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed, const ButtonImage* images) const;

private:

struct ButtonSprite
{
ButtonSprite() : Index(-1), Loop(false), Scale(false)
{
}

bool operator==(const ButtonSprite& other) const
{
return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale;
}

s32 Index;
video::SColor Color;
bool Loop;
bool Scale;
};

ButtonSprite ButtonSprites[gui::EGBS_COUNT];
gui::IGUISpriteBank* SpriteBank;

ButtonImage ButtonImages[gui::EGBIS_COUNT];

gui::IGUIFont* OverrideFont;
Expand All @@ -310,5 +328,7 @@ class GUIButton : public gui::IGUIButton
// PATCH
video::SColor HoveredColors[4];
video::SColor PressedColors[4];

gui::IGUIStaticText *StaticText;
// END PATCH
};
149 changes: 149 additions & 0 deletions src/gui/guiButtonImage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "guiButtonImage.h"

#include "client/guiscalingfilter.h"
#include "debug.h"
#include "IGUIEnvironment.h"
#include "IGUIImage.h"
#include "IVideoDriver.h"
#include "StyleSpec.h"

using namespace irr;
using namespace gui;

GUIButtonImage::GUIButtonImage(gui::IGUIEnvironment *environment,
gui::IGUIElement *parent, s32 id, core::rect<s32> rectangle, bool noclip)
: GUIButton (environment, parent, id, rectangle, noclip)
{
m_image = Environment->addImage(
core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()), this);
m_image->setScaleImage(isScalingImage());
sendToBack(m_image);
}

bool GUIButtonImage::OnEvent(const SEvent& event)
{
bool result = GUIButton::OnEvent(event);

EGUI_BUTTON_IMAGE_STATE imageState = getImageState(isPressed(), m_foreground_images);
video::ITexture *texture = m_foreground_images[(u32)imageState].Texture;
if (texture != nullptr)
m_image->setImage(texture);

return result;
}

void GUIButtonImage::setForegroundImage(EGUI_BUTTON_IMAGE_STATE state,
video::ITexture *image, const core::rect<s32> &sourceRect)
{
if (state >= EGBIS_COUNT)
return;

if (image)
image->grab();

u32 stateIdx = (u32)state;
if (m_foreground_images[stateIdx].Texture)
m_foreground_images[stateIdx].Texture->drop();

m_foreground_images[stateIdx].Texture = image;
m_foreground_images[stateIdx].SourceRect = sourceRect;

EGUI_BUTTON_IMAGE_STATE imageState = getImageState(isPressed(), m_foreground_images);
if (imageState == stateIdx)
m_image->setImage(image);
}

void GUIButtonImage::setForegroundImage(video::ITexture *image)
{
setForegroundImage(gui::EGBIS_IMAGE_UP, image);
}

void GUIButtonImage::setForegroundImage(video::ITexture *image, const core::rect<s32> &pos)
{
setForegroundImage(gui::EGBIS_IMAGE_UP, image, pos);
}

void GUIButtonImage::setPressedForegroundImage(video::ITexture *image)
{
setForegroundImage(gui::EGBIS_IMAGE_DOWN, image);
}

void GUIButtonImage::setPressedForegroundImage(video::ITexture *image, const core::rect<s32> &pos)
{
setForegroundImage(gui::EGBIS_IMAGE_DOWN, image, pos);
}

void GUIButtonImage::setHoveredForegroundImage(video::ITexture *image)
{
setForegroundImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image);
setForegroundImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image);
}

void GUIButtonImage::setHoveredForegroundImage(video::ITexture *image, const core::rect<s32> &pos)
{
setForegroundImage(gui::EGBIS_IMAGE_UP_MOUSEOVER, image, pos);
setForegroundImage(gui::EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER, image, pos);
}

void GUIButtonImage::setFromStyle(const StyleSpec &style, ISimpleTextureSource *tsrc)
{
GUIButton::setFromStyle(style, tsrc);

video::IVideoDriver *driver = Environment->getVideoDriver();

if (style.isNotDefault(StyleSpec::FGIMG)) {
video::ITexture *texture = style.getTexture(StyleSpec::FGIMG, tsrc);
video::ITexture *hovered_texture = style.getTexture(StyleSpec::FGIMG_HOVERED, tsrc, texture);
video::ITexture *pressed_texture = style.getTexture(StyleSpec::FGIMG_PRESSED, tsrc, texture);

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

setForegroundImage(guiScalingImageButton(driver, texture, geom.X, geom.Y));
setHoveredForegroundImage(guiScalingImageButton(driver, hovered_texture, geom.X, geom.Y));
setPressedForegroundImage(guiScalingImageButton(driver, pressed_texture, geom.X, geom.Y));
setScaleImage(true);
}
}

void GUIButtonImage::setScaleImage(bool scaleImage)
{
GUIButton::setScaleImage(scaleImage);
m_image->setScaleImage(scaleImage);
}

GUIButtonImage *GUIButtonImage::addButton(IGUIEnvironment *environment,
const core::rect<s32> &rectangle, IGUIElement *parent, s32 id,
const wchar_t *text, const wchar_t *tooltiptext)
{
GUIButtonImage *button = new GUIButtonImage(environment,
parent ? parent : environment->getRootGUIElement(), id, rectangle);

if (text)
button->setText(text);

if (tooltiptext)
button->setToolTipText(tooltiptext);

button->drop();
return button;
}
59 changes: 59 additions & 0 deletions src/gui/guiButtonImage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "guiButton.h"
#include "IGUIButton.h"

using namespace irr;

class GUIButtonImage : public GUIButton
{
public:
//! constructor
GUIButtonImage(gui::IGUIEnvironment *environment, gui::IGUIElement *parent,
s32 id, core::rect<s32> rectangle, bool noclip = false);

virtual bool OnEvent(const SEvent& event) override;

void setForegroundImage(gui::EGUI_BUTTON_IMAGE_STATE state,
video::ITexture *image = nullptr,
const core::rect<s32> &sourceRect = core::rect<s32>(0, 0, 0, 0));

void setForegroundImage(video::ITexture *image = nullptr);
void setForegroundImage(video::ITexture *image, const core::rect<s32> &pos);

void setPressedForegroundImage(video::ITexture *image = nullptr);
void setPressedForegroundImage(video::ITexture *image, const core::rect<s32> &pos);

void setHoveredForegroundImage(video::ITexture *image = nullptr);
void setHoveredForegroundImage(video::ITexture *image, const core::rect<s32> &pos);

virtual void setFromStyle(const StyleSpec &style, ISimpleTextureSource *tsrc) override;

virtual void setScaleImage(bool scaleImage=true) override;

//! Do not drop returned handle
static GUIButtonImage *addButton(gui::IGUIEnvironment *environment,
const core::rect<s32> &rectangle, IGUIElement *parent, s32 id,
const wchar_t *text, const wchar_t *tooltiptext = L"");

private:
ButtonImage m_foreground_images[gui::EGBIS_COUNT];
gui::IGUIImage *m_image;
};
57 changes: 57 additions & 0 deletions src/gui/guiButtonItemImage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "guiButtonItemImage.h"

#include "client/client.h"
#include "client/hud.h" // drawItemStack
#include "guiItemImage.h"
#include "IGUIEnvironment.h"
#include "itemdef.h"

using namespace irr;
using namespace gui;

GUIButtonItemImage::GUIButtonItemImage(gui::IGUIEnvironment *environment, gui::IGUIElement *parent,
s32 id, core::rect<s32> rectangle, std::string item, Client *client, bool noclip)
: GUIButton (environment, parent, id, rectangle, noclip)
{
m_image = new GUIItemImage(environment, this, id,
core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()),
item, getActiveFont(), client);
sendToBack(m_image);

m_item_name = item;
m_client = client;
}

GUIButtonItemImage *GUIButtonItemImage::addButton(IGUIEnvironment *environment,
const core::rect<s32> &rectangle, IGUIElement *parent, s32 id,
const wchar_t *text, std::string item, Client *client)
{
GUIButtonItemImage *button = new GUIButtonItemImage(environment,
parent ? parent : environment->getRootGUIElement(),
id, rectangle, item, client);

if (text)
button->setText(text);

button->drop();
return button;
}
45 changes: 45 additions & 0 deletions src/gui/guiButtonItemImage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "guiButton.h"
#include "IGUIButton.h"

using namespace irr;

class Client;
class GUIItemImage;

class GUIButtonItemImage : public GUIButton
{
public:
//! constructor
GUIButtonItemImage(gui::IGUIEnvironment *environment, gui::IGUIElement *parent,
s32 id, core::rect<s32> rectangle, std::string item,
Client *client, bool noclip = false);

//! Do not drop returned handle
static GUIButtonItemImage *addButton(gui::IGUIEnvironment *environment,
const core::rect<s32> &rectangle, IGUIElement *parent, s32 id,
const wchar_t *text, std::string item, Client *client);

private:
std::string m_item_name;
Client *m_client;
GUIItemImage *m_image;
};
93 changes: 16 additions & 77 deletions src/gui/guiFormSpecMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiBackgroundImage.h"
#include "guiBox.h"
#include "guiButton.h"
#include "guiButtonImage.h"
#include "guiButtonItemImage.h"
#include "guiEditBoxWithScrollbar.h"
#include "guiItemImage.h"
#include "guiScrollBar.h"
Expand Down Expand Up @@ -879,49 +881,7 @@ void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element,
GUIButton *e = GUIButton::addButton(Environment, rect, this, spec.fid, spec.flabel.c_str());

auto style = getStyleForElement(type, name, (type != "button") ? "button" : "");
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));
}
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
e->setDrawBorder(style.getBool(StyleSpec::BORDER, true));

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
pressed_texture = texture;

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);
}
e->setFromStyle(style, m_tsrc);

if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
Expand Down Expand Up @@ -1876,33 +1836,31 @@ void GUIFormSpecMenu::parseImageButton(parserData* data, const std::string &elem
spec.is_exit = true;

video::ITexture *texture = 0;
video::ITexture *pressed_texture = 0;
texture = m_tsrc->getTexture(image_name);
if (!pressed_image_name.empty())
pressed_texture = m_tsrc->getTexture(pressed_image_name);
else
pressed_texture = texture;

GUIButton *e = GUIButton::addButton(Environment, rect, this, spec.fid, spec.flabel.c_str());
GUIButtonImage *e = GUIButtonImage::addButton(Environment, rect, this, spec.fid, spec.flabel.c_str());

if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}

auto style = getStyleForElement("image_button", spec.fname);
e->setFromStyle(style, m_tsrc);

e->setUseAlphaChannel(style.getBool(StyleSpec::ALPHA, true));
e->setImage(guiScalingImageButton(
// We explicitly handle these arguments *after* the style properties in
// order to override them if they are provided
e->setForegroundImage(guiScalingImageButton(
Environment->getVideoDriver(), texture, geom.X, geom.Y));
e->setPressedImage(guiScalingImageButton(
Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));
if (!pressed_image_name.empty()) {
video::ITexture *pressed_texture = m_tsrc->getTexture(pressed_image_name);
e->setPressedForegroundImage(guiScalingImageButton(
Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y));
}
e->setScaleImage(true);

if (parts.size() >= 7) {
e->setNotClipped(noclip);
e->setDrawBorder(drawborder);
} else {
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
e->setDrawBorder(style.getBool(StyleSpec::BORDER, true));
}

m_fields.push_back(spec);
Expand Down Expand Up @@ -2083,11 +2041,10 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &
2
);

gui::IGUIButton *e_btn = GUIButton::addButton(Environment, rect, this, spec_btn.fid, L"");
GUIButtonItemImage *e_btn = GUIButtonItemImage::addButton(Environment, rect, this, spec_btn.fid, spec_btn.flabel.c_str(), item_name, m_client);

auto style = getStyleForElement("item_image_button", spec_btn.fname, "image_button");
e_btn->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
e_btn->setDrawBorder(style.getBool(StyleSpec::BORDER, true));
e_btn->setFromStyle(style, m_tsrc);

if (spec_btn.fname == data->focused_fieldname) {
Environment->setFocus(e_btn);
Expand All @@ -2097,24 +2054,6 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &
rect += data->basepos-padding;
spec_btn.rect = rect;
m_fields.push_back(spec_btn);

// the spec for the item-image
FieldSpec spec_img(
name,
L"",
L"",
258 + m_fields.size(),
2
);

GUIItemImage *e_img = new GUIItemImage(Environment, e_btn, spec_img.fid,
core::rect<s32>(0, 0, geom.X, geom.Y), item_name, m_font, m_client);

e_img->setText(utf8_to_wide(label).c_str());

e_img->drop();

m_fields.push_back(spec_img);
return;
}
errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl;
Expand Down
12 changes: 0 additions & 12 deletions src/gui/guiItemImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,6 @@ void GUIItemImage::draw()
item.deSerialize(m_item_name, idef);
// Viewport rectangle on screen
core::rect<s32> rect = core::rect<s32>(AbsoluteRect);
if (Parent->getType() == gui::EGUIET_BUTTON &&
((irr::gui::IGUIButton *)Parent)->isPressed()) {
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
rect += core::dimension2d<s32>(0.05 * (float)rect.getWidth(),
0.05 * (float)rect.getHeight());
#else
gui::IGUISkin *skin = Environment->getSkin();
rect += core::dimension2d<s32>(
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X),
skin->getSize(irr::gui::EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y));
#endif
}
drawItemStack(Environment->getVideoDriver(), m_font, item, rect,
&AbsoluteClippingRect, m_client, IT_ROT_NONE);
video::SColor color(255, 255, 255, 255);
Expand Down
2 changes: 1 addition & 1 deletion src/irrlicht_changes/static_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void StaticText::draw()
#if USE_FREETYPE
if (font->getType() == irr::gui::EGFT_CUSTOM) {
irr::gui::CGUITTFont *tmp = static_cast<irr::gui::CGUITTFont*>(font);
tmp->draw(cText, frameRect,
tmp->draw(Text, frameRect,
OverrideColorEnabled ? OverrideColor :
skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT),
HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER,
Expand Down
4 changes: 4 additions & 0 deletions util/travis/clang-format-whitelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ src/gui/guiBox.cpp
src/gui/guiBox.h
src/gui/guiButton.cpp
src/gui/guiButton.h
src/gui/guiButtonImage.cpp
src/gui/guiButtonImage.h
src/gui/guiButtonItemImage.cpp
src/gui/guiButtonItemImage.h
src/gui/guiChatConsole.cpp
src/gui/guiChatConsole.h
src/gui/guiConfirmRegistration.cpp
Expand Down