Commit d2c5bc2f authored by Chen Bill's avatar Chen Bill Committed by GitHub

CGUIImageButton inherit from IGUIButton (#2666)

* update the header file of CGUIImageButton

* CGUIImageButton inherit from IGUIButton

* copy implementation from irrlicht 1.8.5

* remove ClickTime, HoverTime, FocusTime

only used in CGUIButton::draw

* remove CGUIButton.h
parent c5650a69
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_GUI_BUTTON_H_INCLUDED__
#define __C_GUI_BUTTON_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_GUI_
#include "IGUIButton.h"
#include "IGUISpriteBank.h"
#include "SColor.h"
namespace irr
{
namespace gui
{
class CGUIButton : public IGUIButton
{
public:
//! constructor
CGUIButton(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool noclip=false);
//! destructor
virtual ~CGUIButton();
//! called if an event happened.
virtual bool OnEvent(const SEvent& event);
//! draws the element and its children
virtual void draw();
//! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
virtual void setOverrideFont(IGUIFont* font=0);
//! Gets the override font (if any)
virtual IGUIFont* getOverrideFont() const;
//! Get the font which is used right now for drawing
virtual IGUIFont* getActiveFont() const;
//! Sets an image which should be displayed on the button when it is in normal state.
virtual void setImage(video::ITexture* image=0);
//! Sets an image which should be displayed on the button when it is in normal state.
virtual void setImage(video::ITexture* image, const core::rect<s32>& pos);
//! Sets an image which should be displayed on the button when it is in pressed state.
virtual void setPressedImage(video::ITexture* image=0);
//! Sets an image which should be displayed on the button when it is in pressed state.
virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos);
//! Sets the sprite bank used by the button
virtual void setSpriteBank(IGUISpriteBank* bank=0);
//! Sets the animated sprite for a specific button state
/** \param index: Number of the sprite within the sprite bank, use -1 for no sprite
\param state: State of the button to set the sprite for
\param index: The sprite number from the current sprite bank
\param color: The color of the sprite
*/
virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
video::SColor color=video::SColor(255,255,255,255), bool loop=false);
//! Sets if the button should behave like a push button. Which means it
//! can be in two states: Normal or Pressed. With a click on the button,
//! the user can change the state of the button.
virtual void setIsPushButton(bool isPushButton=true);
//! Checks whether the button is a push button
virtual bool isPushButton() const;
//! Sets the pressed state of the button if this is a pushbutton
virtual void setPressed(bool pressed=true);
//! Returns if the button is currently pressed
virtual bool isPressed() const;
//! Sets if the button should use the skin to draw its border
virtual void setDrawBorder(bool border=true);
//! Checks if the button face and border are being drawn
virtual bool isDrawingBorder() const;
//! Sets if the alpha channel should be used for drawing images on the button (default is false)
virtual void setUseAlphaChannel(bool useAlphaChannel=true);
//! Checks if the alpha channel should be used for drawing images on the button
virtual bool isAlphaChannelUsed() const;
//! Sets if the button should scale the button images to fit
virtual void setScaleImage(bool scaleImage=true);
//! Checks whether the button scales the used images
virtual bool isScalingImage() const;
//! Writes attributes of the element.
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
//! Reads attributes of the element
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
protected:
struct ButtonSprite
{
s32 Index;
video::SColor Color;
bool Loop;
};
ButtonSprite ButtonSprites[EGBS_COUNT];
IGUISpriteBank* SpriteBank;
IGUIFont* OverrideFont;
video::ITexture* Image;
video::ITexture* PressedImage;
core::rect<s32> ImageRect;
core::rect<s32> PressedImageRect;
u32 ClickTime, HoverTime, FocusTime;
bool IsPushButton;
bool Pressed;
bool UseAlphaChannel;
bool DrawBorder;
bool ScaleImage;
};
} // end namespace gui
} // end namespace irr
#endif // _IRR_COMPILE_WITH_GUI_
#endif // __C_GUI_BUTTON_H_INCLUDED__
#ifdef _MSC_VER // Copyright (C) 2002-2012 Nikolaus Gebhardt
#pragma warning(disable: 4244) // This file is part of the "Irrlicht Engine".
#endif // For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CGUIImageButton.h" #include "CGUIImageButton.h"
#ifdef _IRR_COMPILE_WITH_GUI_
#include <IGUISpriteBank.h>
#include <IGUISkin.h>
#include <IGUIEnvironment.h>
#include <IVideoDriver.h>
#include <IGUIFont.h>
namespace irr { namespace irr {
namespace gui { namespace gui {
...@@ -94,19 +101,213 @@ void Draw2DImageQuad(video::IVideoDriver* driver, video::ITexture* image, core:: ...@@ -94,19 +101,213 @@ void Draw2DImageQuad(video::IVideoDriver* driver, video::ITexture* image, core::
driver->setTransform(irr::video::ETS_PROJECTION, oldProjMat); driver->setTransform(irr::video::ETS_PROJECTION, oldProjMat);
driver->setTransform(irr::video::ETS_VIEW, oldViewMat); driver->setTransform(irr::video::ETS_VIEW, oldViewMat);
} }
CGUIImageButton::CGUIImageButton(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle) CGUIImageButton* CGUIImageButton::addImageButton(IGUIEnvironment *env, const core::rect<s32>& rectangle, IGUIElement* parent, s32 id) {
: CGUIButton(environment, parent, id, rectangle) { CGUIImageButton* button = new CGUIImageButton(env, parent ? parent : 0, id, rectangle);
button->drop();
return button;
}
//! constructor
CGUIImageButton::CGUIImageButton(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle, bool noclip)
: IGUIButton(environment, parent, id, rectangle),
SpriteBank(0), OverrideFont(0), Image(0), PressedImage(0),
IsPushButton(false), Pressed(false),
UseAlphaChannel(false), DrawBorder(true), ScaleImage(false) {
#ifdef _DEBUG
setDebugName("CGUIImageButton");
#endif
setNotClipped(noclip);
// Initialize the sprites.
for (u32 i = 0; i < EGBS_COUNT; ++i)
ButtonSprites[i].Index = -1;
// This element can be tabbed.
setTabStop(true);
setTabOrder(-1);
isDrawImage = true; isDrawImage = true;
isFixedSize = false; isFixedSize = false;
imageRotation = 0.0f; imageRotation = 0.0f;
imageScale = core::vector2df(1.0f, 1.0f); imageScale = core::vector2df(1.0f, 1.0f);
imageSize = core::dimension2di(rectangle.getWidth(), rectangle.getHeight()); imageSize = core::dimension2di(rectangle.getWidth(), rectangle.getHeight());
} }
CGUIImageButton* CGUIImageButton::addImageButton(IGUIEnvironment *env, const core::rect<s32>& rectangle, IGUIElement* parent, s32 id) { //! destructor
CGUIImageButton* button = new CGUIImageButton(env, parent ? parent : 0, id, rectangle); CGUIImageButton::~CGUIImageButton()
button->drop(); {
return button; if (OverrideFont)
OverrideFont->drop();
if (Image)
Image->drop();
if (PressedImage)
PressedImage->drop();
if (SpriteBank)
SpriteBank->drop();
}
//! Sets if the images should be scaled to fit the button
void CGUIImageButton::setScaleImage(bool scaleImage)
{
ScaleImage = scaleImage;
}
//! Returns whether the button scale the used images
bool CGUIImageButton::isScalingImage() const
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return ScaleImage;
}
//! Sets if the button should use the skin to draw its border
void CGUIImageButton::setDrawBorder(bool border)
{
DrawBorder = border;
}
void CGUIImageButton::setSpriteBank(IGUISpriteBank* sprites)
{
if (sprites)
sprites->grab();
if (SpriteBank)
SpriteBank->drop();
SpriteBank = sprites;
}
void CGUIImageButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop)
{
if (SpriteBank)
{
ButtonSprites[(u32)state].Index = index;
ButtonSprites[(u32)state].Color = color;
ButtonSprites[(u32)state].Loop = loop;
}
else
{
ButtonSprites[(u32)state].Index = -1;
}
}
//! called if an event happened.
bool CGUIImageButton::OnEvent(const SEvent& event)
{
if (!isEnabled())
return IGUIElement::OnEvent(event);
switch (event.EventType)
{
case EET_KEY_INPUT_EVENT:
if (event.KeyInput.PressedDown &&
(event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE))
{
if (!IsPushButton)
setPressed(true);
else
setPressed(!Pressed);
return true;
}
if (Pressed && !IsPushButton && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE)
{
setPressed(false);
return true;
}
else
if (!event.KeyInput.PressedDown && Pressed &&
(event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE))
{
if (!IsPushButton)
setPressed(false);
if (Parent)
{
SEvent newEvent;
newEvent.EventType = EET_GUI_EVENT;
newEvent.GUIEvent.Caller = this;
newEvent.GUIEvent.Element = 0;
newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED;
Parent->OnEvent(newEvent);
}
return true;
}
break;
case EET_GUI_EVENT:
if (event.GUIEvent.Caller == this)
{
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
if (!IsPushButton)
setPressed(false);
}
}
break;
case EET_MOUSE_INPUT_EVENT:
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
if (Environment->hasFocus(this) &&
!AbsoluteClippingRect.isPointInside(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y)))
{
Environment->removeFocus(this);
return false;
}
if (!IsPushButton)
setPressed(true);
Environment->setFocus(this);
return true;
}
else
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
{
bool wasPressed = Pressed;
if (!AbsoluteClippingRect.isPointInside(core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y)))
{
if (!IsPushButton)
setPressed(false);
return true;
}
if (!IsPushButton)
setPressed(false);
else
{
setPressed(!Pressed);
}
if ((!IsPushButton && wasPressed && Parent) ||
(IsPushButton && wasPressed != Pressed))
{
SEvent newEvent;
newEvent.EventType = EET_GUI_EVENT;
newEvent.GUIEvent.Caller = this;
newEvent.GUIEvent.Element = 0;
newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED;
Parent->OnEvent(newEvent);
}
return true;
}
break;
default:
break;
}
return Parent ? Parent->OnEvent(event) : false;
} }
void CGUIImageButton::draw() { void CGUIImageButton::draw() {
if (!IsVisible) if (!IsVisible)
return; return;
...@@ -148,6 +349,14 @@ void CGUIImageButton::setImage(video::ITexture* image) ...@@ -148,6 +349,14 @@ void CGUIImageButton::setImage(video::ITexture* image)
if(!PressedImage) if(!PressedImage)
setPressedImage(Image); setPressedImage(Image);
} }
//! Sets the image which should be displayed on the button when it is in its normal state.
void CGUIImageButton::setImage(video::ITexture* image, const core::rect<s32>& pos)
{
setImage(image);
ImageRect = pos;
}
void CGUIImageButton::setDrawImage(bool b) { void CGUIImageButton::setDrawImage(bool b) {
isDrawImage = b; isDrawImage = b;
} }
...@@ -162,6 +371,21 @@ void CGUIImageButton::setImageSize(core::dimension2di s) { ...@@ -162,6 +371,21 @@ void CGUIImageButton::setImageSize(core::dimension2di s) {
imageSize = s; imageSize = s;
} }
//! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
void CGUIImageButton::setOverrideFont(IGUIFont* font)
{
if (OverrideFont == font)
return;
if (OverrideFont)
OverrideFont->drop();
OverrideFont = font;
if (OverrideFont)
OverrideFont->grab();
}
IGUIFont* CGUIImageButton::getOverrideFont( void ) const IGUIFont* CGUIImageButton::getOverrideFont( void ) const
{ {
IGUISkin* skin = Environment->getSkin(); IGUISkin* skin = Environment->getSkin();
...@@ -178,5 +402,137 @@ IGUIFont* CGUIImageButton::getActiveFont() const ...@@ -178,5 +402,137 @@ IGUIFont* CGUIImageButton::getActiveFont() const
return skin->getFont(); return skin->getFont();
} }
//! Sets an image which should be displayed on the button when it is in pressed state.
void CGUIImageButton::setPressedImage(video::ITexture* image)
{
if (image)
image->grab();
if (PressedImage)
PressedImage->drop();
PressedImage = image;
if (image)
PressedImageRect = core::rect<s32>(core::position2d<s32>(0, 0), image->getOriginalSize());
}
//! Sets the image which should be displayed on the button when it is in its pressed state.
void CGUIImageButton::setPressedImage(video::ITexture* image, const core::rect<s32>& pos)
{
setPressedImage(image);
PressedImageRect = pos;
}
//! Sets if the button should behave like a push button. Which means it
//! can be in two states: Normal or Pressed. With a click on the button,
//! the user can change the state of the button.
void CGUIImageButton::setIsPushButton(bool isPushButton)
{
IsPushButton = isPushButton;
}
//! Returns if the button is currently pressed
bool CGUIImageButton::isPressed() const
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return Pressed;
}
//! Sets the pressed state of the button if this is a pushbutton
void CGUIImageButton::setPressed(bool pressed)
{
if (Pressed != pressed)
{
Pressed = pressed;
}
} }
//! Returns whether the button is a push button
bool CGUIImageButton::isPushButton() const
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return IsPushButton;
} }
//! Sets if the alpha channel should be used for drawing images on the button (default is false)
void CGUIImageButton::setUseAlphaChannel(bool useAlphaChannel)
{
UseAlphaChannel = useAlphaChannel;
}
//! Returns if the alpha channel should be used for drawing images on the button
bool CGUIImageButton::isAlphaChannelUsed() const
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return UseAlphaChannel;
}
bool CGUIImageButton::isDrawingBorder() const
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return DrawBorder;
}
//! Writes attributes of the element.
void CGUIImageButton::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options = 0) const
{
IGUIButton::serializeAttributes(out, options);
out->addBool("PushButton", IsPushButton);
if (IsPushButton)
out->addBool("Pressed", Pressed);
out->addTexture("Image", Image);
out->addRect("ImageRect", ImageRect);
out->addTexture("PressedImage", PressedImage);
out->addRect("PressedImageRect", PressedImageRect);
out->addBool("UseAlphaChannel", isAlphaChannelUsed());
out->addBool("Border", isDrawingBorder());
out->addBool("ScaleImage", isScalingImage());
// out->addString ("OverrideFont", OverrideFont);
}
//! Reads attributes of the element
void CGUIImageButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options = 0)
{
IGUIButton::deserializeAttributes(in, options);
IsPushButton = in->getAttributeAsBool("PushButton");
Pressed = IsPushButton ? in->getAttributeAsBool("Pressed") : false;
core::rect<s32> rec = in->getAttributeAsRect("ImageRect");
if (rec.isValid())
setImage(in->getAttributeAsTexture("Image"), rec);
else
setImage(in->getAttributeAsTexture("Image"));
rec = in->getAttributeAsRect("PressedImageRect");
if (rec.isValid())
setPressedImage(in->getAttributeAsTexture("PressedImage"), rec);
else
setPressedImage(in->getAttributeAsTexture("PressedImage"));
setDrawBorder(in->getAttributeAsBool("Border"));
setUseAlphaChannel(in->getAttributeAsBool("UseAlphaChannel"));
setScaleImage(in->getAttributeAsBool("ScaleImage"));
// setOverrideFont(in->getAttributeAsString("OverrideFont"));
updateAbsolutePosition();
}
} // end namespace gui
} // end namespace irr
#endif // _IRR_COMPILE_WITH_GUI_
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef _C_GUI_IMAGE_BUTTON_H_ #ifndef _C_GUI_IMAGE_BUTTON_H_
#define _C_GUI_IMAGE_BUTTON_H_ #define _C_GUI_IMAGE_BUTTON_H_
#include <irrlicht.h> #include <IrrCompileConfig.h>
#include "CGUIButton.h" #ifdef _IRR_COMPILE_WITH_GUI_
#include <IGUIButton.h>
#include <SColor.h>
namespace irr { namespace irr {
namespace video {
class IVideoDriver;
class ITexture;
}
namespace gui { namespace gui {
class IGUISpriteBank;
void Draw2DImageRotation(video::IVideoDriver* driver, video::ITexture* image, core::rect<s32> sourceRect, void Draw2DImageRotation(video::IVideoDriver* driver, video::ITexture* image, core::rect<s32> sourceRect,
core::position2d<s32> position, core::position2d<s32> rotationPoint, f32 rotation = 0.0f, core::position2d<s32> position, core::position2d<s32> rotationPoint, f32 rotation = 0.0f,
core::vector2df scale = core::vector2df(1.0, 1.0), bool useAlphaChannel = true, video::SColor color = 0xffffffff); core::vector2df scale = core::vector2df(1.0, 1.0), bool useAlphaChannel = true, video::SColor color = 0xffffffff);
void Draw2DImageQuad(video::IVideoDriver* driver, video::ITexture* image, core::rect<s32> sourceRect, void Draw2DImageQuad(video::IVideoDriver* driver, video::ITexture* image, core::rect<s32> sourceRect,
core::position2d<s32> corner[4], bool useAlphaChannel = true, video::SColor color = 0xffffffff); core::position2d<s32> corner[4], bool useAlphaChannel = true, video::SColor color = 0xffffffff);
class CGUIImageButton : public CGUIButton {
class CGUIImageButton : public IGUIButton {
public: public:
CGUIImageButton(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle); static CGUIImageButton* addImageButton(IGUIEnvironment* env, const core::rect<s32>& rectangle, IGUIElement* parent, s32 id);
static CGUIImageButton* addImageButton(IGUIEnvironment *env, const core::rect<s32>& rectangle, IGUIElement* parent, s32 id);
virtual void draw(); //! constructor
virtual void setImage(video::ITexture* image = 0); CGUIImageButton(IGUIEnvironment* environment, IGUIElement* parent,
virtual void setDrawImage(bool b); s32 id, core::rect<s32> rectangle, bool noclip = false);
virtual void setImageRotation(f32 r);
virtual void setImageScale(core::vector2df s); //! destructor
virtual void setImageSize(core::dimension2di s); ~CGUIImageButton() override;
virtual IGUIFont* getOverrideFont(void) const;
virtual IGUIFont* getActiveFont() const; //! called if an event happened.
bool OnEvent(const SEvent& event) override;
private:
//! draws the element and its children
void draw() override;
//! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
void setOverrideFont(IGUIFont* font = 0) override;
//! Gets the override font (if any)
IGUIFont* getOverrideFont() const override;
//! Get the font which is used right now for drawing
IGUIFont* getActiveFont() const override;
//! Sets an image which should be displayed on the button when it is in normal state.
void setImage(video::ITexture* image = 0) override;
//! Sets an image which should be displayed on the button when it is in normal state.
void setImage(video::ITexture* image, const core::rect<s32>& pos) override;
//! Sets an image which should be displayed on the button when it is in pressed state.
void setPressedImage(video::ITexture* image = 0) override;
//! Sets an image which should be displayed on the button when it is in pressed state.
void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) override;
//! Sets the sprite bank used by the button
void setSpriteBank(IGUISpriteBank* bank = 0) override;
//! Sets the animated sprite for a specific button state
/** \param index: Number of the sprite within the sprite bank, use -1 for no sprite
\param state: State of the button to set the sprite for
\param index: The sprite number from the current sprite bank
\param color: The color of the sprite
*/
void setSprite(EGUI_BUTTON_STATE state, s32 index,
video::SColor color = video::SColor(255, 255, 255, 255), bool loop = false) override;
//! Sets if the button should behave like a push button. Which means it
//! can be in two states: Normal or Pressed. With a click on the button,
//! the user can change the state of the button.
void setIsPushButton(bool isPushButton = true) override;
//! Checks whether the button is a push button
bool isPushButton() const override;
//! Sets the pressed state of the button if this is a pushbutton
void setPressed(bool pressed = true) override;
//! Returns if the button is currently pressed
bool isPressed() const override;
//! Sets if the button should use the skin to draw its border
void setDrawBorder(bool border = true) override;
//! Checks if the button face and border are being drawn
bool isDrawingBorder() const override;
//! Sets if the alpha channel should be used for drawing images on the button (default is false)
void setUseAlphaChannel(bool useAlphaChannel = true) override;
//! Checks if the alpha channel should be used for drawing images on the button
bool isAlphaChannelUsed() const override;
//! Sets if the button should scale the button images to fit
void setScaleImage(bool scaleImage = true) override;
//! Checks whether the button scales the used images
bool isScalingImage() const override;
//! Writes attributes of the element.
void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const override;
//! Reads attributes of the element
void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) override;
// from ygopro
void setDrawImage(bool b);
void setImageRotation(f32 r);
void setImageScale(core::vector2df s);
void setImageSize(core::dimension2di s);
protected:
struct ButtonSprite
{
s32 Index;
video::SColor Color;
bool Loop;
};
ButtonSprite ButtonSprites[EGBS_COUNT];
IGUISpriteBank* SpriteBank;
IGUIFont* OverrideFont;
video::ITexture* Image;
video::ITexture* PressedImage;
core::rect<s32> ImageRect;
core::rect<s32> PressedImageRect;
bool IsPushButton;
bool Pressed;
bool UseAlphaChannel;
bool DrawBorder;
bool ScaleImage;
// from ygopro
bool isDrawImage; bool isDrawImage;
bool isFixedSize; bool isFixedSize;
f32 imageRotation; f32 imageRotation;
...@@ -36,4 +155,6 @@ private: ...@@ -36,4 +155,6 @@ private:
} }
} }
#endif // _IRR_COMPILE_WITH_GUI_
#endif //_C_GUI_IMAGE_BUTTON_H_ #endif //_C_GUI_IMAGE_BUTTON_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment