Commit 5b156c1d authored by cutealien's avatar cutealien

Buttons can now now have 7 more image-states, 1 more sprite-state and the...

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-e03cc46cb475
parent 88581a4c
--------------------------
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.
- 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)
......
......@@ -20,11 +20,16 @@ namespace gui
class IGUIFont;
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
{
//! The button is not pressed
//! The button is not pressed.
EGBS_BUTTON_UP=0,
//! The button is currently pressed down
//! The button is currently pressed down.
EGBS_BUTTON_DOWN,
//! The mouse cursor is over the button
EGBS_BUTTON_MOUSE_OVER,
......@@ -34,12 +39,14 @@ namespace gui
EGBS_BUTTON_FOCUSED,
//! The button doesn't have the focus
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
EGBS_COUNT
};
//! Names for gui button state icons
const c8* const GUIButtonStateNames[] =
const c8* const GUIButtonStateNames[EGBS_COUNT+1] =
{
"buttonUp",
"buttonDown",
......@@ -47,8 +54,52 @@ namespace gui
"buttonMouseOff",
"buttonFocused",
"buttonNotFocused",
0,
0,
"buttonDisabled",
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.
......@@ -77,38 +128,71 @@ namespace gui
font of the active skin otherwise */
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.
/** \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;
//! Sets a background image for the button when it is in normal state.
/** \param image: Texture containing the image to be displayed
\param pos: Position in the texture, where the image is located */
virtual void setImage(video::ITexture* image, const core::rect<s32>& pos) = 0;
/** This is identical to calling setImage(EGBIS_IMAGE_UP, image, sourceRect); and might be deprecated in future revisions.
\param image: Texture containing the image to be displayed
\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.
/** 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.
\param image: Image to be displayed */
virtual void setPressedImage(video::ITexture* image=0) = 0;
//! 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
\param pos: Position in the texture, where the image is located */
virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) = 0;
/** This is identical to calling setImage(EGBIS_IMAGE_DOWN, image, sourceRect); and might be deprecated in future revisions.
\param image: Texture containing the image to be displayed
\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
/** 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;
//! 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 index: The sprite number from the current sprite bank
\param color: The color of the sprite
\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,
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.
/** 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,
//! maximal space to reserve for messagebox 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,
//! 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,
//! 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,
//! 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,
//! 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
//! available.
......@@ -222,6 +226,8 @@ namespace gui
"ButtonPressedImageOffsetY"
"ButtonPressedTextOffsetX",
"ButtonPressedTextOffsetY",
"ButtonPressedSpriteOffsetX",
"ButtonPressedSpriteOffsetY",
0
};
......
This diff is collapsed.
......@@ -10,6 +10,7 @@
#include "IGUIButton.h"
#include "IGUISpriteBank.h"
#include "ITexture.h"
#include "SColor.h"
namespace irr
......@@ -43,17 +44,32 @@ namespace gui
//! Get the font which is used right now for drawing
virtual IGUIFont* getActiveFont() const _IRR_OVERRIDE_;
//! Sets an image which should be displayed on the button when it is in the given state.
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.
virtual void setImage(video::ITexture* image=0) _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_;
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.
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.
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
virtual void setSpriteBank(IGUISpriteBank* bank=0) _IRR_OVERRIDE_;
......@@ -65,7 +81,20 @@ namespace gui
\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) _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
//! can be in two states: Normal or Pressed. With a click on the button,
......@@ -105,25 +134,75 @@ namespace gui
//! Reads attributes of the element
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:
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[EGBS_COUNT];
IGUISpriteBank* SpriteBank;
IGUIFont* OverrideFont;
video::ITexture* Image;
video::ITexture* PressedImage;
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();
}
core::rect<s32> ImageRect;
core::rect<s32> PressedImageRect;
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;
u32 ClickTime, HoverTime, FocusTime;
......
......@@ -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_TEXT_OFFSET_X] = 0;
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_CANCEL] = L"Cancel";
......@@ -970,9 +972,7 @@ void CGUISkin::draw2DRectangle(IGUIElement* element,
}
//! Writes attributes of the object.
//! Implement this to expose the attributes of your scene node animator for
//! scripting languages, editors, debuggers or xml serialization purposes.
//! Writes attributes of the skin
void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
u32 i;
......@@ -990,25 +990,21 @@ void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWrite
}
//! Reads attributes of the object.
//! Implement this to set the attributes of your scene node animator for
//! scripting languages, editors, debuggers or xml deserialization purposes.
//! Reads attributes of the skikn
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;
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)
Sizes[i] = in->getAttributeAsInt(GUISkinSizeNames[i]);
Sizes[i] = in->getAttributeAsInt(GUISkinSizeNames[i], Sizes[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)
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
virtual EGUI_SKIN_TYPE getType() const _IRR_OVERRIDE_;
//! Writes attributes of the object.
//! Implement this to expose the attributes of your scene node animator for
//! scripting languages, editors, debuggers or xml serialization purposes.
//! Writes attributes of the skin
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const _IRR_OVERRIDE_;
//! Reads attributes of the object.
//! Implement this to set the attributes of your scene node animator for
//! scripting languages, editors, debuggers or xml deserialization purposes.
//! Reads attributes of the skin
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;
private:
......
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