Buttons can now now have 7 more image-states, 1 more sprite-state and the sprites are now scaleable.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4756 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
88581a4c42
commit
5b156c1dca
|
@ -1,6 +1,7 @@
|
||||||
--------------------------
|
--------------------------
|
||||||
Changes in 1.9 (not yet released)
|
Changes in 1.9 (not yet released)
|
||||||
|
|
||||||
|
- Buttons can now now have 7 more image-states, 1 more sprite-state and the sprites are now scaleable.
|
||||||
- Spritebanks can now draw scaled sprites and are a little easier to use.
|
- Spritebanks can now draw scaled sprites and are a little easier to use.
|
||||||
- Improved i18n key input for X11 (languages like cyrillic work now).
|
- Improved i18n key input for X11 (languages like cyrillic work now).
|
||||||
- Fix bug that ListBox would not allow to 'tab' to the next element (thx @ FlavourBoat for reporting)
|
- Fix bug that ListBox would not allow to 'tab' to the next element (thx @ FlavourBoat for reporting)
|
||||||
|
|
|
@ -20,11 +20,16 @@ namespace gui
|
||||||
class IGUIFont;
|
class IGUIFont;
|
||||||
class IGUISpriteBank;
|
class IGUISpriteBank;
|
||||||
|
|
||||||
|
//! Current state of buttons used for drawing sprites.
|
||||||
|
//! Note that up to 3 states can be active at the same time:
|
||||||
|
//! EGBS_BUTTON_UP or EGBS_BUTTON_DOWN
|
||||||
|
//! EGBS_BUTTON_MOUSE_OVER or EGBS_BUTTON_MOUSE_OFF
|
||||||
|
//! EGBS_BUTTON_FOCUSED or EGBS_BUTTON_NOT_FOCUSED
|
||||||
enum EGUI_BUTTON_STATE
|
enum EGUI_BUTTON_STATE
|
||||||
{
|
{
|
||||||
//! The button is not pressed
|
//! The button is not pressed.
|
||||||
EGBS_BUTTON_UP=0,
|
EGBS_BUTTON_UP=0,
|
||||||
//! The button is currently pressed down
|
//! The button is currently pressed down.
|
||||||
EGBS_BUTTON_DOWN,
|
EGBS_BUTTON_DOWN,
|
||||||
//! The mouse cursor is over the button
|
//! The mouse cursor is over the button
|
||||||
EGBS_BUTTON_MOUSE_OVER,
|
EGBS_BUTTON_MOUSE_OVER,
|
||||||
|
@ -34,12 +39,14 @@ namespace gui
|
||||||
EGBS_BUTTON_FOCUSED,
|
EGBS_BUTTON_FOCUSED,
|
||||||
//! The button doesn't have the focus
|
//! The button doesn't have the focus
|
||||||
EGBS_BUTTON_NOT_FOCUSED,
|
EGBS_BUTTON_NOT_FOCUSED,
|
||||||
|
//! The button is disabled All other states are ignored in that case.
|
||||||
|
EGBS_BUTTON_DISABLED,
|
||||||
//! not used, counts the number of enumerated items
|
//! not used, counts the number of enumerated items
|
||||||
EGBS_COUNT
|
EGBS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Names for gui button state icons
|
//! Names for gui button state icons
|
||||||
const c8* const GUIButtonStateNames[] =
|
const c8* const GUIButtonStateNames[EGBS_COUNT+1] =
|
||||||
{
|
{
|
||||||
"buttonUp",
|
"buttonUp",
|
||||||
"buttonDown",
|
"buttonDown",
|
||||||
|
@ -47,8 +54,52 @@ namespace gui
|
||||||
"buttonMouseOff",
|
"buttonMouseOff",
|
||||||
"buttonFocused",
|
"buttonFocused",
|
||||||
"buttonNotFocused",
|
"buttonNotFocused",
|
||||||
0,
|
"buttonDisabled",
|
||||||
0,
|
0 // count
|
||||||
|
};
|
||||||
|
|
||||||
|
//! State of buttons used for drawing texture images.
|
||||||
|
//! Note that only a single state is active at a time
|
||||||
|
//! Also when no image is defined for a state it will use images from another state
|
||||||
|
//! and if that state is not set from the replacement for that,etc.
|
||||||
|
//! So in many cases setting EGBIS_IMAGE_UP and EGBIS_IMAGE_DOWN is sufficient.
|
||||||
|
enum EGUI_BUTTON_IMAGE_STATE
|
||||||
|
{
|
||||||
|
//! When no other states have images they will all use this one.
|
||||||
|
EGBIS_IMAGE_UP,
|
||||||
|
//! When not set EGBIS_IMAGE_UP is used.
|
||||||
|
EGBIS_IMAGE_UP_MOUSEOVER,
|
||||||
|
//! When not set EGBIS_IMAGE_UP_MOUSEOVER is used.
|
||||||
|
EGBIS_IMAGE_UP_FOCUSED,
|
||||||
|
//! When not set EGBIS_IMAGE_UP_FOCUSED is used.
|
||||||
|
EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER,
|
||||||
|
//! When not set EGBIS_IMAGE_UP is used.
|
||||||
|
EGBIS_IMAGE_DOWN,
|
||||||
|
//! When not set EGBIS_IMAGE_DOWN is used.
|
||||||
|
EGBIS_IMAGE_DOWN_MOUSEOVER,
|
||||||
|
//! When not set EGBIS_IMAGE_DOWN_MOUSEOVER is used.
|
||||||
|
EGBIS_IMAGE_DOWN_FOCUSED,
|
||||||
|
//! When not set EGBIS_IMAGE_DOWN_FOCUSED is used.
|
||||||
|
EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER,
|
||||||
|
//! When not set EGBIS_IMAGE_UP or EGBIS_IMAGE_DOWN are used (depending on button state).
|
||||||
|
EGBIS_IMAGE_DISABLED,
|
||||||
|
//! not used, counts the number of enumerated items
|
||||||
|
EGBIS_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Names for gui button image states
|
||||||
|
const c8* const GUIButtonImageStateNames[EGBIS_COUNT+1] =
|
||||||
|
{
|
||||||
|
"Image", // not "ImageUp" as it otherwise breaks serialization of old files
|
||||||
|
"ImageUpOver",
|
||||||
|
"ImageUpFocused",
|
||||||
|
"ImageUpFocusedOver",
|
||||||
|
"PressedImage", // not "ImageDown" as it otherwise breaks serialization of old files
|
||||||
|
"ImageDownOver",
|
||||||
|
"ImageDownFocused",
|
||||||
|
"ImageDownFocusedOver",
|
||||||
|
"ImageDisabled",
|
||||||
|
0 // count
|
||||||
};
|
};
|
||||||
|
|
||||||
//! GUI Button interface.
|
//! GUI Button interface.
|
||||||
|
@ -77,38 +128,71 @@ namespace gui
|
||||||
font of the active skin otherwise */
|
font of the active skin otherwise */
|
||||||
virtual IGUIFont* getActiveFont() const = 0;
|
virtual IGUIFont* getActiveFont() const = 0;
|
||||||
|
|
||||||
|
//! Sets an image which should be displayed on the button when it is in the given state.
|
||||||
|
/** Only one image-state can be active at a time. Images are drawn below sprites.
|
||||||
|
If a state is without image it will try to use images from other states as described
|
||||||
|
in ::EGUI_BUTTON_IMAGE_STATE.
|
||||||
|
Images are a little less flexible than sprites, but easier to use.
|
||||||
|
\param state: One of ::EGUI_BUTTON_IMAGE_STATE
|
||||||
|
\param image: Image to be displayed or NULL to remove the image
|
||||||
|
\param sourceRect: Source rectangle on the image texture. When width or height are 0 then the full texture-size is used (default). */
|
||||||
|
virtual void setImage(EGUI_BUTTON_IMAGE_STATE state, video::ITexture* image=0, const core::rect<s32>& sourceRect=core::rect<s32>(0,0,0,0)) = 0;
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in normal state.
|
//! Sets an image which should be displayed on the button when it is in normal state.
|
||||||
/** \param image: Image to be displayed */
|
/** This is identical to calling setImage(EGBIS_IMAGE_UP, image); and might be deprecated in future revisions.
|
||||||
|
\param image: Image to be displayed */
|
||||||
virtual void setImage(video::ITexture* image=0) = 0;
|
virtual void setImage(video::ITexture* image=0) = 0;
|
||||||
|
|
||||||
//! Sets a background image for the button when it is in normal state.
|
//! Sets a background image for the button when it is in normal state.
|
||||||
/** \param image: Texture containing the image to be displayed
|
/** This is identical to calling setImage(EGBIS_IMAGE_UP, image, sourceRect); and might be deprecated in future revisions.
|
||||||
\param pos: Position in the texture, where the image is located */
|
\param image: Texture containing the image to be displayed
|
||||||
virtual void setImage(video::ITexture* image, const core::rect<s32>& pos) = 0;
|
\param sourceRect: Position in the texture, where the image is located.
|
||||||
|
When width or height are 0 then the full texture-size is used */
|
||||||
|
virtual void setImage(video::ITexture* image, const core::rect<s32>& sourceRect) = 0;
|
||||||
|
|
||||||
//! Sets a background image for the button when it is in pressed state.
|
//! Sets a background image for the button when it is in pressed state.
|
||||||
/** If no images is specified for the pressed state via
|
/** This is identical to calling setImage(EGBIS_IMAGE_DOWN, image); and might be deprecated in future revisions.
|
||||||
|
If no images is specified for the pressed state via
|
||||||
setPressedImage(), this image is also drawn in pressed state.
|
setPressedImage(), this image is also drawn in pressed state.
|
||||||
\param image: Image to be displayed */
|
\param image: Image to be displayed */
|
||||||
virtual void setPressedImage(video::ITexture* image=0) = 0;
|
virtual void setPressedImage(video::ITexture* image=0) = 0;
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in pressed state.
|
//! Sets an image which should be displayed on the button when it is in pressed state.
|
||||||
/** \param image: Texture containing the image to be displayed
|
/** This is identical to calling setImage(EGBIS_IMAGE_DOWN, image, sourceRect); and might be deprecated in future revisions.
|
||||||
\param pos: Position in the texture, where the image is located */
|
\param image: Texture containing the image to be displayed
|
||||||
virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) = 0;
|
\param sourceRect: Position in the texture, where the image is located */
|
||||||
|
virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& sourceRect) = 0;
|
||||||
|
|
||||||
|
|
||||||
//! Sets the sprite bank used by the button
|
//! Sets the sprite bank used by the button
|
||||||
|
/** NOTE: The spritebank itself is _not_ serialized so far. The sprites are serialized.
|
||||||
|
Which means after loading the gui you still have to set the spritebank manually. */
|
||||||
virtual void setSpriteBank(IGUISpriteBank* bank=0) = 0;
|
virtual void setSpriteBank(IGUISpriteBank* bank=0) = 0;
|
||||||
|
|
||||||
//! Sets the animated sprite for a specific button state
|
//! Sets the animated sprite for a specific button state
|
||||||
/** \param index: Number of the sprite within the sprite bank, use -1 for no sprite
|
/** Several sprites can be drawn at the same time.
|
||||||
|
Sprites can be animated.
|
||||||
|
Sprites are drawn above the images.
|
||||||
|
\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 state: State of the button to set the sprite for
|
||||||
\param index: The sprite number from the current sprite bank
|
\param index: The sprite number from the current sprite bank
|
||||||
\param color: The color of the sprite
|
\param color: The color of the sprite
|
||||||
\param loop: True if the animation should loop, false if not
|
\param loop: True if the animation should loop, false if not
|
||||||
*/
|
\param scale: True if the sprite should scale to button size, false if not */
|
||||||
virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
|
virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
|
||||||
video::SColor color=video::SColor(255,255,255,255), bool loop=false) = 0;
|
video::SColor color=video::SColor(255,255,255,255), bool loop=false, bool scale=false) = 0;
|
||||||
|
|
||||||
|
//! Get the sprite-index for the given state or -1 when no sprite is set
|
||||||
|
virtual s32 getSpriteIndex(EGUI_BUTTON_STATE state) const = 0;
|
||||||
|
|
||||||
|
//! Get the sprite color for the given state. Color is only used when a sprite is set.
|
||||||
|
virtual video::SColor getSpriteColor(EGUI_BUTTON_STATE state) const = 0;
|
||||||
|
|
||||||
|
//! Returns if the sprite in the given state does loop
|
||||||
|
virtual bool getSpriteLoop(EGUI_BUTTON_STATE state) const = 0;
|
||||||
|
|
||||||
|
//! Returns if the sprite in the given state is scaled
|
||||||
|
virtual bool getSpriteScale(EGUI_BUTTON_STATE state) const = 0;
|
||||||
|
|
||||||
//! Sets if the button should behave like a push button.
|
//! 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,
|
/** Which means it can be in two states: Normal or Pressed. With a click on the button,
|
||||||
|
|
|
@ -183,14 +183,18 @@ namespace gui
|
||||||
EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT,
|
EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT,
|
||||||
//! maximal space to reserve for messagebox text-height
|
//! maximal space to reserve for messagebox text-height
|
||||||
EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT,
|
EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT,
|
||||||
//! pixels to move the button image to the right when a pushbutton is pressed
|
//! pixels to move an unscaled button image to the right when a button is pressed and the unpressed image looks identical
|
||||||
EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X,
|
EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X,
|
||||||
//! pixels to move the button image down when a pushbutton is pressed
|
//! pixels to move an unscaled button image down when a button is pressed and the unpressed image looks identical
|
||||||
EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y,
|
EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y,
|
||||||
//! pixels to move the button text to the right when a pushbutton is pressed
|
//! pixels to move the button text to the right when a button is pressed
|
||||||
EGDS_BUTTON_PRESSED_TEXT_OFFSET_X,
|
EGDS_BUTTON_PRESSED_TEXT_OFFSET_X,
|
||||||
//! pixels to move the button text down when a pushbutton is pressed
|
//! pixels to move the button text down when a button is pressed
|
||||||
EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y,
|
EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y,
|
||||||
|
//! pixels to move an unscaled button sprite to the right when a button is pressed
|
||||||
|
EGDS_BUTTON_PRESSED_SPRITE_OFFSET_X,
|
||||||
|
//! pixels to move an unscaled button sprite down when a button is pressed
|
||||||
|
EGDS_BUTTON_PRESSED_SPRITE_OFFSET_Y,
|
||||||
|
|
||||||
//! this value is not used, it only specifies the amount of default sizes
|
//! this value is not used, it only specifies the amount of default sizes
|
||||||
//! available.
|
//! available.
|
||||||
|
@ -222,6 +226,8 @@ namespace gui
|
||||||
"ButtonPressedImageOffsetY"
|
"ButtonPressedImageOffsetY"
|
||||||
"ButtonPressedTextOffsetX",
|
"ButtonPressedTextOffsetX",
|
||||||
"ButtonPressedTextOffsetY",
|
"ButtonPressedTextOffsetY",
|
||||||
|
"ButtonPressedSpriteOffsetX",
|
||||||
|
"ButtonPressedSpriteOffsetY",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace gui
|
||||||
CGUIButton::CGUIButton(IGUIEnvironment* environment, IGUIElement* parent,
|
CGUIButton::CGUIButton(IGUIEnvironment* environment, IGUIElement* parent,
|
||||||
s32 id, core::rect<s32> rectangle, bool noclip)
|
s32 id, core::rect<s32> rectangle, bool noclip)
|
||||||
: IGUIButton(environment, parent, id, rectangle),
|
: IGUIButton(environment, parent, id, rectangle),
|
||||||
SpriteBank(0), OverrideFont(0), Image(0), PressedImage(0),
|
SpriteBank(0), OverrideFont(0),
|
||||||
ClickTime(0), HoverTime(0), FocusTime(0),
|
ClickTime(0), HoverTime(0), FocusTime(0),
|
||||||
IsPushButton(false), Pressed(false),
|
IsPushButton(false), Pressed(false),
|
||||||
UseAlphaChannel(false), DrawBorder(true), ScaleImage(false)
|
UseAlphaChannel(false), DrawBorder(true), ScaleImage(false)
|
||||||
|
@ -30,10 +30,6 @@ CGUIButton::CGUIButton(IGUIEnvironment* environment, IGUIElement* parent,
|
||||||
#endif
|
#endif
|
||||||
setNotClipped(noclip);
|
setNotClipped(noclip);
|
||||||
|
|
||||||
// Initialize the sprites.
|
|
||||||
for (u32 i=0; i<EGBS_COUNT; ++i)
|
|
||||||
ButtonSprites[i].Index = -1;
|
|
||||||
|
|
||||||
// This element can be tabbed.
|
// This element can be tabbed.
|
||||||
setTabStop(true);
|
setTabStop(true);
|
||||||
setTabOrder(-1);
|
setTabOrder(-1);
|
||||||
|
@ -46,12 +42,6 @@ CGUIButton::~CGUIButton()
|
||||||
if (OverrideFont)
|
if (OverrideFont)
|
||||||
OverrideFont->drop();
|
OverrideFont->drop();
|
||||||
|
|
||||||
if (Image)
|
|
||||||
Image->drop();
|
|
||||||
|
|
||||||
if (PressedImage)
|
|
||||||
PressedImage->drop();
|
|
||||||
|
|
||||||
if (SpriteBank)
|
if (SpriteBank)
|
||||||
SpriteBank->drop();
|
SpriteBank->drop();
|
||||||
}
|
}
|
||||||
|
@ -91,20 +81,37 @@ void CGUIButton::setSpriteBank(IGUISpriteBank* sprites)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CGUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop)
|
void CGUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop, bool scale)
|
||||||
{
|
{
|
||||||
if (SpriteBank)
|
|
||||||
{
|
|
||||||
ButtonSprites[(u32)state].Index = index;
|
ButtonSprites[(u32)state].Index = index;
|
||||||
ButtonSprites[(u32)state].Color = color;
|
ButtonSprites[(u32)state].Color = color;
|
||||||
ButtonSprites[(u32)state].Loop = loop;
|
ButtonSprites[(u32)state].Loop = loop;
|
||||||
}
|
ButtonSprites[(u32)state].Scale = scale;
|
||||||
else
|
|
||||||
{
|
|
||||||
ButtonSprites[(u32)state].Index = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Get the sprite-index for the given state or -1 when no sprite is set
|
||||||
|
s32 CGUIButton::getSpriteIndex(EGUI_BUTTON_STATE state) const
|
||||||
|
{
|
||||||
|
return ButtonSprites[(u32)state].Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get the sprite color for the given state. Color is only used when a sprite is set.
|
||||||
|
video::SColor CGUIButton::getSpriteColor(EGUI_BUTTON_STATE state) const
|
||||||
|
{
|
||||||
|
return ButtonSprites[(u32)state].Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns if the sprite in the given state does loop
|
||||||
|
bool CGUIButton::getSpriteLoop(EGUI_BUTTON_STATE state) const
|
||||||
|
{
|
||||||
|
return ButtonSprites[(u32)state].Loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns if the sprite in the given state is scaled
|
||||||
|
bool CGUIButton::getSpriteScale(EGUI_BUTTON_STATE state) const
|
||||||
|
{
|
||||||
|
return ButtonSprites[(u32)state].Scale;
|
||||||
|
}
|
||||||
|
|
||||||
//! called if an event happened.
|
//! called if an event happened.
|
||||||
bool CGUIButton::OnEvent(const SEvent& event)
|
bool CGUIButton::OnEvent(const SEvent& event)
|
||||||
|
@ -235,94 +242,77 @@ void CGUIButton::draw()
|
||||||
IGUISkin* skin = Environment->getSkin();
|
IGUISkin* skin = Environment->getSkin();
|
||||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||||
|
|
||||||
// todo: move sprite up and text down if the pressed state has a sprite
|
if (DrawBorder)
|
||||||
const core::position2di spritePos = AbsoluteRect.getCenter();
|
{
|
||||||
|
|
||||||
if (!Pressed)
|
if (!Pressed)
|
||||||
{
|
{
|
||||||
if (DrawBorder)
|
|
||||||
skin->draw3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect);
|
skin->draw3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect);
|
||||||
|
|
||||||
if (Image)
|
|
||||||
{
|
|
||||||
core::position2d<s32> pos = spritePos;
|
|
||||||
pos.X -= ImageRect.getWidth() / 2;
|
|
||||||
pos.Y -= ImageRect.getHeight() / 2;
|
|
||||||
|
|
||||||
driver->draw2DImage(Image,
|
|
||||||
ScaleImage? AbsoluteRect :
|
|
||||||
core::recti(pos, ImageRect.getSize()),
|
|
||||||
ImageRect, &AbsoluteClippingRect,
|
|
||||||
0, UseAlphaChannel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (DrawBorder)
|
|
||||||
skin->draw3DButtonPanePressed(this, AbsoluteRect, &AbsoluteClippingRect);
|
skin->draw3DButtonPanePressed(this, AbsoluteRect, &AbsoluteClippingRect);
|
||||||
|
|
||||||
video::ITexture * imgPressed = PressedImage;
|
|
||||||
core::rect<s32> rectPressed(PressedImageRect);
|
|
||||||
bool movePos = false; // pressed-down effect by moving the image
|
|
||||||
if (!imgPressed && Image)
|
|
||||||
{
|
|
||||||
imgPressed = Image;
|
|
||||||
rectPressed = ImageRect;
|
|
||||||
movePos = true;
|
|
||||||
}
|
}
|
||||||
else if (Image == PressedImage && PressedImageRect == ImageRect)
|
|
||||||
{
|
|
||||||
movePos = true;
|
|
||||||
}
|
}
|
||||||
if (imgPressed)
|
|
||||||
{
|
|
||||||
core::position2d<s32> pos = spritePos;
|
|
||||||
pos.X -= rectPressed.getWidth() / 2;
|
|
||||||
pos.Y -= rectPressed.getHeight() / 2;
|
|
||||||
|
|
||||||
if (movePos)
|
|
||||||
|
const core::position2di buttonCenter(AbsoluteRect.getCenter());
|
||||||
|
|
||||||
|
EGUI_BUTTON_IMAGE_STATE imageState = getImageState(Pressed);
|
||||||
|
if ( ButtonImages[(u32)imageState].Texture )
|
||||||
|
{
|
||||||
|
core::position2d<s32> pos(buttonCenter);
|
||||||
|
core::rect<s32> sourceRect(ButtonImages[(u32)imageState].SourceRect);
|
||||||
|
if ( sourceRect.getWidth() == 0 && sourceRect.getHeight() == 0 )
|
||||||
|
sourceRect = core::rect<s32>(core::position2di(0,0), ButtonImages[(u32)imageState].Texture->getOriginalSize());
|
||||||
|
|
||||||
|
pos.X -= sourceRect.getWidth() / 2;
|
||||||
|
pos.Y -= sourceRect.getHeight() / 2;
|
||||||
|
|
||||||
|
if ( Pressed )
|
||||||
|
{
|
||||||
|
// Create a pressed-down effect by moving the image when it looks identical to the unpressed state image
|
||||||
|
EGUI_BUTTON_IMAGE_STATE unpressedState = getImageState(false);
|
||||||
|
if ( unpressedState == imageState || ButtonImages[(u32)imageState] == ButtonImages[(u32)unpressedState] )
|
||||||
{
|
{
|
||||||
pos.X += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X);
|
pos.X += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X);
|
||||||
pos.Y += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y);
|
pos.Y += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y);
|
||||||
}
|
}
|
||||||
driver->draw2DImage(imgPressed,
|
|
||||||
ScaleImage? AbsoluteRect :
|
|
||||||
core::recti(pos, rectPressed.getSize()),
|
|
||||||
rectPressed, &AbsoluteClippingRect,
|
|
||||||
0, UseAlphaChannel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
driver->draw2DImage(ButtonImages[(u32)imageState].Texture,
|
||||||
|
ScaleImage? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()),
|
||||||
|
sourceRect, &AbsoluteClippingRect,
|
||||||
|
0, UseAlphaChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SpriteBank)
|
if (SpriteBank)
|
||||||
{
|
{
|
||||||
// pressed / unpressed animation
|
core::position2di pos(buttonCenter);
|
||||||
u32 state = Pressed ? (u32)EGBS_BUTTON_DOWN : (u32)EGBS_BUTTON_UP;
|
if ( Pressed )
|
||||||
if (ButtonSprites[state].Index != -1)
|
|
||||||
{
|
{
|
||||||
SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos,
|
IGUISkin* skin = Environment->getSkin();
|
||||||
&AbsoluteClippingRect, ButtonSprites[state].Color, ClickTime, os::Timer::getTime(),
|
pos.X += skin->getSize(EGDS_BUTTON_PRESSED_SPRITE_OFFSET_X);
|
||||||
ButtonSprites[state].Loop, true);
|
pos.Y += skin->getSize(EGDS_BUTTON_PRESSED_SPRITE_OFFSET_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// focused / unfocused animation
|
|
||||||
state = Environment->hasFocus(this) ? (u32)EGBS_BUTTON_FOCUSED : (u32)EGBS_BUTTON_NOT_FOCUSED;
|
|
||||||
if (ButtonSprites[state].Index != -1)
|
|
||||||
{
|
|
||||||
SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos,
|
|
||||||
&AbsoluteClippingRect, ButtonSprites[state].Color, FocusTime, os::Timer::getTime(),
|
|
||||||
ButtonSprites[state].Loop, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// mouse over / off animation
|
|
||||||
if (isEnabled())
|
if (isEnabled())
|
||||||
{
|
{
|
||||||
state = Environment->getHovered() == this ? (u32)EGBS_BUTTON_MOUSE_OVER : (u32)EGBS_BUTTON_MOUSE_OFF;
|
// pressed / unpressed animation
|
||||||
if (ButtonSprites[state].Index != -1)
|
EGUI_BUTTON_STATE state = Pressed ? EGBS_BUTTON_DOWN : EGBS_BUTTON_UP;
|
||||||
{
|
drawSprite(state, ClickTime, pos);
|
||||||
SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos,
|
|
||||||
&AbsoluteClippingRect, ButtonSprites[state].Color, HoverTime, os::Timer::getTime(),
|
// focused / unfocused animation
|
||||||
ButtonSprites[state].Loop, true);
|
state = Environment->hasFocus(this) ? EGBS_BUTTON_FOCUSED : EGBS_BUTTON_NOT_FOCUSED;
|
||||||
|
drawSprite(state, FocusTime, pos);
|
||||||
|
|
||||||
|
// mouse over / off animation
|
||||||
|
state = Environment->getHovered() == this ? EGBS_BUTTON_MOUSE_OVER : EGBS_BUTTON_MOUSE_OFF;
|
||||||
|
drawSprite(state, HoverTime, pos);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// draw disabled
|
||||||
|
drawSprite(EGBS_BUTTON_DISABLED, 0, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,6 +336,93 @@ void CGUIButton::draw()
|
||||||
IGUIElement::draw();
|
IGUIElement::draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGUIButton::drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center)
|
||||||
|
{
|
||||||
|
u32 stateIdx = (u32)state;
|
||||||
|
|
||||||
|
if (ButtonSprites[stateIdx].Index != -1)
|
||||||
|
{
|
||||||
|
if ( ButtonSprites[stateIdx].Scale )
|
||||||
|
{
|
||||||
|
const video::SColor colors[] = {ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color,ButtonSprites[stateIdx].Color};
|
||||||
|
SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, AbsoluteRect,
|
||||||
|
&AbsoluteClippingRect, colors,
|
||||||
|
os::Timer::getTime()-startTime, ButtonSprites[stateIdx].Loop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpriteBank->draw2DSprite(ButtonSprites[stateIdx].Index, center,
|
||||||
|
&AbsoluteClippingRect, ButtonSprites[stateIdx].Color, startTime, os::Timer::getTime(),
|
||||||
|
ButtonSprites[stateIdx].Loop, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EGUI_BUTTON_IMAGE_STATE CGUIButton::getImageState(bool pressed) const
|
||||||
|
{
|
||||||
|
// figure state we should have
|
||||||
|
EGUI_BUTTON_IMAGE_STATE state = EGBIS_IMAGE_DISABLED;
|
||||||
|
bool focused = Environment->hasFocus(this);
|
||||||
|
bool mouseOver = Environment->getHovered() == this;
|
||||||
|
if (isEnabled())
|
||||||
|
{
|
||||||
|
if ( pressed )
|
||||||
|
{
|
||||||
|
if ( focused && mouseOver )
|
||||||
|
state = EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER;
|
||||||
|
else if ( focused )
|
||||||
|
state = EGBIS_IMAGE_DOWN_FOCUSED;
|
||||||
|
else if ( mouseOver )
|
||||||
|
state = EGBIS_IMAGE_DOWN_MOUSEOVER;
|
||||||
|
else
|
||||||
|
state = EGBIS_IMAGE_DOWN;
|
||||||
|
}
|
||||||
|
else // !pressed
|
||||||
|
{
|
||||||
|
if ( focused && mouseOver )
|
||||||
|
state = EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER;
|
||||||
|
else if ( focused )
|
||||||
|
state = EGBIS_IMAGE_UP_FOCUSED;
|
||||||
|
else if ( mouseOver )
|
||||||
|
state = EGBIS_IMAGE_UP_MOUSEOVER;
|
||||||
|
else
|
||||||
|
state = EGBIS_IMAGE_UP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a compatible state that has images
|
||||||
|
while ( state != EGBIS_IMAGE_UP && !ButtonImages[(u32)state].Texture )
|
||||||
|
{
|
||||||
|
switch ( state )
|
||||||
|
{
|
||||||
|
case EGBIS_IMAGE_UP_FOCUSED:
|
||||||
|
state = EGBIS_IMAGE_UP_MOUSEOVER;
|
||||||
|
break;
|
||||||
|
case EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER:
|
||||||
|
state = EGBIS_IMAGE_UP_FOCUSED;
|
||||||
|
break;
|
||||||
|
case EGBIS_IMAGE_DOWN_MOUSEOVER:
|
||||||
|
state = EGBIS_IMAGE_DOWN;
|
||||||
|
break;
|
||||||
|
case EGBIS_IMAGE_DOWN_FOCUSED:
|
||||||
|
state = EGBIS_IMAGE_DOWN_MOUSEOVER;
|
||||||
|
break;
|
||||||
|
case EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER:
|
||||||
|
state = EGBIS_IMAGE_DOWN_FOCUSED;
|
||||||
|
break;
|
||||||
|
case EGBIS_IMAGE_DISABLED:
|
||||||
|
if ( pressed )
|
||||||
|
state = EGBIS_IMAGE_DOWN;
|
||||||
|
else
|
||||||
|
state = EGBIS_IMAGE_UP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = EGBIS_IMAGE_UP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
//! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
|
//! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
|
||||||
void CGUIButton::setOverrideFont(IGUIFont* font)
|
void CGUIButton::setOverrideFont(IGUIFont* font)
|
||||||
|
@ -379,51 +456,22 @@ IGUIFont* CGUIButton::getActiveFont() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in normal state.
|
void CGUIButton::setImage(EGUI_BUTTON_IMAGE_STATE state, video::ITexture* image, const core::rect<s32>& sourceRect)
|
||||||
void CGUIButton::setImage(video::ITexture* image)
|
|
||||||
{
|
{
|
||||||
if (image)
|
if ( state >= EGBIS_COUNT )
|
||||||
image->grab();
|
return;
|
||||||
if (Image)
|
|
||||||
Image->drop();
|
|
||||||
|
|
||||||
Image = image;
|
if ( image )
|
||||||
if (image)
|
|
||||||
ImageRect = 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 normal state.
|
|
||||||
void CGUIButton::setImage(video::ITexture* image, const core::rect<s32>& pos)
|
|
||||||
{
|
|
||||||
setImage(image);
|
|
||||||
ImageRect = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in pressed state.
|
|
||||||
void CGUIButton::setPressedImage(video::ITexture* image)
|
|
||||||
{
|
|
||||||
if (image)
|
|
||||||
image->grab();
|
image->grab();
|
||||||
|
|
||||||
if (PressedImage)
|
u32 stateIdx = (u32)state;
|
||||||
PressedImage->drop();
|
if ( ButtonImages[stateIdx].Texture )
|
||||||
|
ButtonImages[stateIdx].Texture->drop();
|
||||||
|
|
||||||
PressedImage = image;
|
ButtonImages[stateIdx].Texture = image;
|
||||||
if (image)
|
ButtonImages[stateIdx].SourceRect = sourceRect;
|
||||||
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 CGUIButton::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
|
//! 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,
|
//! can be in two states: Normal or Pressed. With a click on the button,
|
||||||
//! the user can change the state of the button.
|
//! the user can change the state of the button.
|
||||||
|
@ -491,14 +539,42 @@ void CGUIButton::serializeAttributes(io::IAttributes* out, io::SAttributeReadWri
|
||||||
if (IsPushButton)
|
if (IsPushButton)
|
||||||
out->addBool("Pressed", Pressed);
|
out->addBool("Pressed", Pressed);
|
||||||
|
|
||||||
out->addTexture ("Image", Image);
|
for ( u32 i=0; i<(u32)EGBIS_COUNT; ++i )
|
||||||
out->addRect ("ImageRect", ImageRect);
|
{
|
||||||
out->addTexture ("PressedImage", PressedImage);
|
if ( ButtonImages[i].Texture )
|
||||||
out->addRect ("PressedImageRect", PressedImageRect);
|
{
|
||||||
|
core::stringc name( GUIButtonImageStateNames[i] );
|
||||||
|
out->addTexture(name.c_str(), ButtonImages[i].Texture);
|
||||||
|
name += "Rect";
|
||||||
|
out->addRect(name.c_str(), ButtonImages[i].SourceRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out->addBool ("UseAlphaChannel", isAlphaChannelUsed());
|
out->addBool ("UseAlphaChannel", UseAlphaChannel);
|
||||||
out->addBool ("Border", isDrawingBorder());
|
out->addBool ("Border", DrawBorder);
|
||||||
out->addBool ("ScaleImage", isScalingImage());
|
out->addBool ("ScaleImage", ScaleImage);
|
||||||
|
|
||||||
|
for ( u32 i=0; i<(u32)EGBS_COUNT; ++i )
|
||||||
|
{
|
||||||
|
if ( ButtonSprites[i].Index >= 0 )
|
||||||
|
{
|
||||||
|
core::stringc nameIndex( GUIButtonStateNames[i] );
|
||||||
|
nameIndex += "Index";
|
||||||
|
out->addInt(nameIndex.c_str(), ButtonSprites[i].Index );
|
||||||
|
|
||||||
|
core::stringc nameColor( GUIButtonStateNames[i] );
|
||||||
|
nameColor += "Color";
|
||||||
|
out->addColor(nameColor.c_str(), ButtonSprites[i].Color );
|
||||||
|
|
||||||
|
core::stringc nameLoop( GUIButtonStateNames[i] );
|
||||||
|
nameLoop += "Loop";
|
||||||
|
out->addBool(nameLoop.c_str(), ButtonSprites[i].Loop );
|
||||||
|
|
||||||
|
core::stringc nameScale( GUIButtonStateNames[i] );
|
||||||
|
nameScale += "Scale";
|
||||||
|
out->addBool(nameScale.c_str(), ButtonSprites[i].Scale );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// out->addString ("OverrideFont", OverrideFont);
|
// out->addString ("OverrideFont", OverrideFont);
|
||||||
}
|
}
|
||||||
|
@ -509,24 +585,41 @@ void CGUIButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWr
|
||||||
{
|
{
|
||||||
IGUIButton::deserializeAttributes(in,options);
|
IGUIButton::deserializeAttributes(in,options);
|
||||||
|
|
||||||
IsPushButton = in->getAttributeAsBool("PushButton");
|
IsPushButton = in->getAttributeAsBool("PushButton", IsPushButton);
|
||||||
Pressed = IsPushButton ? in->getAttributeAsBool("Pressed") : false;
|
Pressed = IsPushButton ? in->getAttributeAsBool("Pressed", Pressed) : false;
|
||||||
|
|
||||||
core::rect<s32> rec = in->getAttributeAsRect("ImageRect");
|
for ( u32 i=0; i<(u32)EGBIS_COUNT; ++i )
|
||||||
if (rec.isValid())
|
{
|
||||||
setImage( in->getAttributeAsTexture("Image"), rec);
|
core::stringc nameRect( GUIButtonImageStateNames[i] );
|
||||||
else
|
nameRect += "Rect";
|
||||||
setImage( in->getAttributeAsTexture("Image") );
|
|
||||||
|
|
||||||
rec = in->getAttributeAsRect("PressedImageRect");
|
setImage((EGUI_BUTTON_IMAGE_STATE)i,
|
||||||
if (rec.isValid())
|
in->getAttributeAsTexture(GUIButtonImageStateNames[i], ButtonImages[i].Texture),
|
||||||
setPressedImage( in->getAttributeAsTexture("PressedImage"), rec);
|
in->getAttributeAsRect(nameRect.c_str(), ButtonImages[i].SourceRect) );
|
||||||
else
|
}
|
||||||
setPressedImage( in->getAttributeAsTexture("PressedImage") );
|
|
||||||
|
|
||||||
setDrawBorder(in->getAttributeAsBool("Border"));
|
setDrawBorder(in->getAttributeAsBool("Border", DrawBorder));
|
||||||
setUseAlphaChannel(in->getAttributeAsBool("UseAlphaChannel"));
|
setUseAlphaChannel(in->getAttributeAsBool("UseAlphaChannel", UseAlphaChannel));
|
||||||
setScaleImage(in->getAttributeAsBool("ScaleImage"));
|
setScaleImage(in->getAttributeAsBool("ScaleImage", ScaleImage));
|
||||||
|
|
||||||
|
for ( u32 i=0; i<(u32)EGBS_COUNT; ++i )
|
||||||
|
{
|
||||||
|
core::stringc nameIndex( GUIButtonStateNames[i] );
|
||||||
|
nameIndex += "Index";
|
||||||
|
ButtonSprites[i].Index = in->getAttributeAsInt(nameIndex.c_str(), ButtonSprites[i].Index );
|
||||||
|
|
||||||
|
core::stringc nameColor( GUIButtonStateNames[i] );
|
||||||
|
nameColor += "Color";
|
||||||
|
ButtonSprites[i].Color = in->getAttributeAsColor(nameColor.c_str(), ButtonSprites[i].Color );
|
||||||
|
|
||||||
|
core::stringc nameLoop( GUIButtonStateNames[i] );
|
||||||
|
nameLoop += "Loop";
|
||||||
|
ButtonSprites[i].Loop = in->getAttributeAsBool(nameLoop.c_str(), ButtonSprites[i].Loop );
|
||||||
|
|
||||||
|
core::stringc nameScale( GUIButtonStateNames[i] );
|
||||||
|
nameScale += "Scale";
|
||||||
|
ButtonSprites[i].Scale = in->getAttributeAsBool(nameScale.c_str(), ButtonSprites[i].Scale );
|
||||||
|
}
|
||||||
|
|
||||||
// setOverrideFont(in->getAttributeAsString("OverrideFont"));
|
// setOverrideFont(in->getAttributeAsString("OverrideFont"));
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "IGUIButton.h"
|
#include "IGUIButton.h"
|
||||||
#include "IGUISpriteBank.h"
|
#include "IGUISpriteBank.h"
|
||||||
|
#include "ITexture.h"
|
||||||
#include "SColor.h"
|
#include "SColor.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
|
@ -43,17 +44,32 @@ namespace gui
|
||||||
//! Get the font which is used right now for drawing
|
//! Get the font which is used right now for drawing
|
||||||
virtual IGUIFont* getActiveFont() const _IRR_OVERRIDE_;
|
virtual IGUIFont* getActiveFont() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in normal state.
|
//! Sets an image which should be displayed on the button when it is in the given state.
|
||||||
virtual void setImage(video::ITexture* image=0) _IRR_OVERRIDE_;
|
virtual void setImage(EGUI_BUTTON_IMAGE_STATE state, video::ITexture* image=0, const core::rect<s32>& sourceRect=core::rect<s32>(0,0,0,0)) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in normal state.
|
//! 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) _IRR_OVERRIDE_;
|
virtual void setImage(video::ITexture* image=0) _IRR_OVERRIDE_
|
||||||
|
{
|
||||||
|
setImage(EGBIS_IMAGE_UP, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! 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) _IRR_OVERRIDE_
|
||||||
|
{
|
||||||
|
setImage(EGBIS_IMAGE_UP, image, pos);
|
||||||
|
}
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in pressed state.
|
//! Sets an image which should be displayed on the button when it is in pressed state.
|
||||||
virtual void setPressedImage(video::ITexture* image=0) _IRR_OVERRIDE_;
|
virtual void setPressedImage(video::ITexture* image=0) _IRR_OVERRIDE_
|
||||||
|
{
|
||||||
|
setImage(EGBIS_IMAGE_DOWN, image);
|
||||||
|
}
|
||||||
|
|
||||||
//! Sets an image which should be displayed on the button when it is in pressed state.
|
//! 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) _IRR_OVERRIDE_;
|
virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) _IRR_OVERRIDE_
|
||||||
|
{
|
||||||
|
setImage(EGBIS_IMAGE_DOWN, image, pos);
|
||||||
|
}
|
||||||
|
|
||||||
//! Sets the sprite bank used by the button
|
//! Sets the sprite bank used by the button
|
||||||
virtual void setSpriteBank(IGUISpriteBank* bank=0) _IRR_OVERRIDE_;
|
virtual void setSpriteBank(IGUISpriteBank* bank=0) _IRR_OVERRIDE_;
|
||||||
|
@ -65,7 +81,20 @@ namespace gui
|
||||||
\param color: The color of the sprite
|
\param color: The color of the sprite
|
||||||
*/
|
*/
|
||||||
virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
|
virtual void setSprite(EGUI_BUTTON_STATE state, s32 index,
|
||||||
video::SColor color=video::SColor(255,255,255,255), bool loop=false) _IRR_OVERRIDE_;
|
video::SColor color=video::SColor(255,255,255,255),
|
||||||
|
bool loop=false, bool scale=false) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Get the sprite-index for the given state or -1 when no sprite is set
|
||||||
|
virtual s32 getSpriteIndex(EGUI_BUTTON_STATE state) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Get the sprite color for the given state. Color is only used when a sprite is set.
|
||||||
|
virtual video::SColor getSpriteColor(EGUI_BUTTON_STATE state) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Returns if the sprite in the given state does loop
|
||||||
|
virtual bool getSpriteLoop(EGUI_BUTTON_STATE state) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
//! Returns if the sprite in the given state is scaled
|
||||||
|
virtual bool getSpriteScale(EGUI_BUTTON_STATE state) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Sets if the button should behave like a push button. Which means it
|
//! 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,
|
//! can be in two states: Normal or Pressed. With a click on the button,
|
||||||
|
@ -105,26 +134,76 @@ namespace gui
|
||||||
//! Reads attributes of the element
|
//! Reads attributes of the element
|
||||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) _IRR_OVERRIDE_;
|
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawSprite(EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center);
|
||||||
|
EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct ButtonSprite
|
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;
|
s32 Index;
|
||||||
video::SColor Color;
|
video::SColor Color;
|
||||||
bool Loop;
|
bool Loop;
|
||||||
|
bool Scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
ButtonSprite ButtonSprites[EGBS_COUNT];
|
ButtonSprite ButtonSprites[EGBS_COUNT];
|
||||||
|
|
||||||
IGUISpriteBank* SpriteBank;
|
IGUISpriteBank* SpriteBank;
|
||||||
|
|
||||||
|
struct ButtonImage
|
||||||
|
{
|
||||||
|
ButtonImage() : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonImage(const ButtonImage& other) : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ButtonImage()
|
||||||
|
{
|
||||||
|
if ( Texture )
|
||||||
|
Texture->drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonImage& operator=(const ButtonImage& other)
|
||||||
|
{
|
||||||
|
if ( this == &other )
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
if (other.Texture)
|
||||||
|
other.Texture->grab();
|
||||||
|
if ( Texture )
|
||||||
|
Texture->drop();
|
||||||
|
Texture = other.Texture;
|
||||||
|
SourceRect = other.SourceRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ButtonImage& other) const
|
||||||
|
{
|
||||||
|
return Texture == other.Texture && SourceRect == other.SourceRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
video::ITexture* Texture;
|
||||||
|
core::rect<s32> SourceRect;
|
||||||
|
};
|
||||||
|
|
||||||
|
ButtonImage ButtonImages[EGBIS_COUNT];
|
||||||
|
|
||||||
IGUIFont* OverrideFont;
|
IGUIFont* OverrideFont;
|
||||||
|
|
||||||
video::ITexture* Image;
|
|
||||||
video::ITexture* PressedImage;
|
|
||||||
|
|
||||||
core::rect<s32> ImageRect;
|
|
||||||
core::rect<s32> PressedImageRect;
|
|
||||||
|
|
||||||
u32 ClickTime, HoverTime, FocusTime;
|
u32 ClickTime, HoverTime, FocusTime;
|
||||||
|
|
||||||
bool IsPushButton;
|
bool IsPushButton;
|
||||||
|
|
|
@ -123,6 +123,8 @@ CGUISkin::CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver)
|
||||||
Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y] = 1;
|
Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y] = 1;
|
||||||
Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_X] = 0;
|
Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_X] = 0;
|
||||||
Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y] = 2;
|
Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y] = 2;
|
||||||
|
Sizes[EGDS_BUTTON_PRESSED_SPRITE_OFFSET_X] = 0;
|
||||||
|
Sizes[EGDS_BUTTON_PRESSED_SPRITE_OFFSET_Y] = 0;
|
||||||
|
|
||||||
Texts[EGDT_MSG_BOX_OK] = L"OK";
|
Texts[EGDT_MSG_BOX_OK] = L"OK";
|
||||||
Texts[EGDT_MSG_BOX_CANCEL] = L"Cancel";
|
Texts[EGDT_MSG_BOX_CANCEL] = L"Cancel";
|
||||||
|
@ -970,9 +972,7 @@ void CGUISkin::draw2DRectangle(IGUIElement* element,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Writes attributes of the object.
|
//! Writes attributes of the skin
|
||||||
//! Implement this to expose the attributes of your scene node animator for
|
|
||||||
//! scripting languages, editors, debuggers or xml serialization purposes.
|
|
||||||
void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
|
void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
|
@ -990,25 +990,21 @@ void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Reads attributes of the object.
|
//! Reads attributes of the skikn
|
||||||
//! Implement this to set the attributes of your scene node animator for
|
|
||||||
//! scripting languages, editors, debuggers or xml deserialization purposes.
|
|
||||||
void CGUISkin::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
|
void CGUISkin::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
|
||||||
{
|
{
|
||||||
// TODO: This is not nice code for downward compatibility, whenever new values are added and users
|
|
||||||
// load an old skin the corresponding values will be set to 0.
|
|
||||||
u32 i;
|
u32 i;
|
||||||
for (i=0; i<EGDC_COUNT; ++i)
|
for (i=0; i<EGDC_COUNT; ++i)
|
||||||
Colors[i] = in->getAttributeAsColor(GUISkinColorNames[i]);
|
Colors[i] = in->getAttributeAsColor(GUISkinColorNames[i], Colors[i]);
|
||||||
|
|
||||||
for (i=0; i<EGDS_COUNT; ++i)
|
for (i=0; i<EGDS_COUNT; ++i)
|
||||||
Sizes[i] = in->getAttributeAsInt(GUISkinSizeNames[i]);
|
Sizes[i] = in->getAttributeAsInt(GUISkinSizeNames[i], Sizes[i]);
|
||||||
|
|
||||||
for (i=0; i<EGDT_COUNT; ++i)
|
for (i=0; i<EGDT_COUNT; ++i)
|
||||||
Texts[i] = in->getAttributeAsStringW(GUISkinTextNames[i]);
|
Texts[i] = in->getAttributeAsStringW(GUISkinTextNames[i], Texts[i]);
|
||||||
|
|
||||||
for (i=0; i<EGDI_COUNT; ++i)
|
for (i=0; i<EGDI_COUNT; ++i)
|
||||||
Icons[i] = in->getAttributeAsInt(GUISkinIconNames[i]);
|
Icons[i] = in->getAttributeAsInt(GUISkinIconNames[i], Icons[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -216,14 +216,10 @@ namespace gui
|
||||||
//! get the type of this skin
|
//! get the type of this skin
|
||||||
virtual EGUI_SKIN_TYPE getType() const _IRR_OVERRIDE_;
|
virtual EGUI_SKIN_TYPE getType() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Writes attributes of the object.
|
//! Writes attributes of the skin
|
||||||
//! Implement this to expose the attributes of your scene node animator for
|
|
||||||
//! scripting languages, editors, debuggers or xml serialization purposes.
|
|
||||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const _IRR_OVERRIDE_;
|
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! Reads attributes of the object.
|
//! Reads attributes of the skin
|
||||||
//! Implement this to set the attributes of your scene node animator for
|
|
||||||
//! scripting languages, editors, debuggers or xml deserialization purposes.
|
|
||||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;
|
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue