guiButton.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #pragma once
  5. #include "IrrCompileConfig.h"
  6. #include <IGUIStaticText.h>
  7. #include "irrlicht_changes/static_text.h"
  8. #include "IGUIButton.h"
  9. #include "IGUISpriteBank.h"
  10. #include "ITexture.h"
  11. #include "SColor.h"
  12. #include "guiSkin.h"
  13. #include "StyleSpec.h"
  14. using namespace irr;
  15. #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8)
  16. namespace irr { namespace gui {
  17. //! State of buttons used for drawing texture images.
  18. //! Note that only a single state is active at a time
  19. //! Also when no image is defined for a state it will use images from another state
  20. //! and if that state is not set from the replacement for that,etc.
  21. //! So in many cases setting EGBIS_IMAGE_UP and EGBIS_IMAGE_DOWN is sufficient.
  22. enum EGUI_BUTTON_IMAGE_STATE {
  23. //! When no other states have images they will all use this one.
  24. EGBIS_IMAGE_UP,
  25. //! When not set EGBIS_IMAGE_UP is used.
  26. EGBIS_IMAGE_UP_MOUSEOVER,
  27. //! When not set EGBIS_IMAGE_UP_MOUSEOVER is used.
  28. EGBIS_IMAGE_UP_FOCUSED,
  29. //! When not set EGBIS_IMAGE_UP_FOCUSED is used.
  30. EGBIS_IMAGE_UP_FOCUSED_MOUSEOVER,
  31. //! When not set EGBIS_IMAGE_UP is used.
  32. EGBIS_IMAGE_DOWN,
  33. //! When not set EGBIS_IMAGE_DOWN is used.
  34. EGBIS_IMAGE_DOWN_MOUSEOVER,
  35. //! When not set EGBIS_IMAGE_DOWN_MOUSEOVER is used.
  36. EGBIS_IMAGE_DOWN_FOCUSED,
  37. //! When not set EGBIS_IMAGE_DOWN_FOCUSED is used.
  38. EGBIS_IMAGE_DOWN_FOCUSED_MOUSEOVER,
  39. //! When not set EGBIS_IMAGE_UP or EGBIS_IMAGE_DOWN are used (depending on button state).
  40. EGBIS_IMAGE_DISABLED,
  41. //! not used, counts the number of enumerated items
  42. EGBIS_COUNT
  43. };
  44. //! Names for gui button image states
  45. const c8 *const GUIButtonImageStateNames[EGBIS_COUNT + 1] =
  46. {
  47. "Image", // not "ImageUp" as it otherwise breaks serialization of old files
  48. "ImageUpOver",
  49. "ImageUpFocused",
  50. "ImageUpFocusedOver",
  51. "PressedImage", // not "ImageDown" as it otherwise breaks serialization of old files
  52. "ImageDownOver",
  53. "ImageDownFocused",
  54. "ImageDownFocusedOver",
  55. "ImageDisabled",
  56. 0 // count
  57. };
  58. }}
  59. #endif
  60. class ISimpleTextureSource;
  61. #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8)
  62. #define OVERRIDE_19
  63. #else
  64. #define OVERRIDE_19 override
  65. #endif
  66. class GUIButton : public gui::IGUIButton
  67. {
  68. public:
  69. //! constructor
  70. GUIButton(gui::IGUIEnvironment* environment, gui::IGUIElement* parent,
  71. s32 id, core::rect<s32> rectangle, ISimpleTextureSource *tsrc,
  72. bool noclip=false);
  73. //! destructor
  74. virtual ~GUIButton();
  75. //! called if an event happened.
  76. virtual bool OnEvent(const SEvent& event) override;
  77. //! draws the element and its children
  78. virtual void draw() override;
  79. //! sets another skin independent font. if this is set to zero, the button uses the font of the skin.
  80. virtual void setOverrideFont(gui::IGUIFont* font=0) override;
  81. //! Gets the override font (if any)
  82. virtual gui::IGUIFont* getOverrideFont() const override;
  83. //! Get the font which is used right now for drawing
  84. virtual gui::IGUIFont* getActiveFont() const override;
  85. //! Sets another color for the button text.
  86. virtual void setOverrideColor(video::SColor color) OVERRIDE_19;
  87. //! Gets the override color
  88. virtual video::SColor getOverrideColor(void) const OVERRIDE_19;
  89. #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
  90. //! Gets the currently used text color
  91. virtual video::SColor getActiveColor() const override;
  92. #endif
  93. //! Sets if the button text should use the override color or the color in the gui skin.
  94. virtual void enableOverrideColor(bool enable) OVERRIDE_19;
  95. //! Checks if an override color is enabled
  96. virtual bool isOverrideColorEnabled(void) const OVERRIDE_19;
  97. // PATCH
  98. //! Sets an image which should be displayed on the button when it is in the given state.
  99. virtual void setImage(gui::EGUI_BUTTON_IMAGE_STATE state,
  100. video::ITexture* image=nullptr,
  101. const core::rect<s32>& sourceRect=core::rect<s32>(0,0,0,0)) OVERRIDE_19;
  102. //! Sets an image which should be displayed on the button when it is in normal state.
  103. virtual void setImage(video::ITexture* image=nullptr) override;
  104. //! Sets an image which should be displayed on the button when it is in normal state.
  105. virtual void setImage(video::ITexture* image, const core::rect<s32>& pos) override;
  106. //! Sets an image which should be displayed on the button when it is in pressed state.
  107. virtual void setPressedImage(video::ITexture* image=nullptr) override;
  108. //! Sets an image which should be displayed on the button when it is in pressed state.
  109. virtual void setPressedImage(video::ITexture* image, const core::rect<s32>& pos) override;
  110. //! Sets the text displayed by the button
  111. virtual void setText(const wchar_t* text) override;
  112. // END PATCH
  113. //! Sets the sprite bank used by the button
  114. virtual void setSpriteBank(gui::IGUISpriteBank* bank=0) override;
  115. //! Sets the animated sprite for a specific button state
  116. /** \param index: Number of the sprite within the sprite bank, use -1 for no sprite
  117. \param state: State of the button to set the sprite for
  118. \param index: The sprite number from the current sprite bank
  119. \param color: The color of the sprite
  120. */
  121. virtual void setSprite(gui::EGUI_BUTTON_STATE state, s32 index,
  122. video::SColor color=video::SColor(255,255,255,255),
  123. bool loop=false, bool scale=false) OVERRIDE_19;
  124. #if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8)
  125. void setSprite(gui::EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop) override {
  126. setSprite(state, index, color, loop, false);
  127. }
  128. #endif
  129. //! Get the sprite-index for the given state or -1 when no sprite is set
  130. virtual s32 getSpriteIndex(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19;
  131. //! Get the sprite color for the given state. Color is only used when a sprite is set.
  132. virtual video::SColor getSpriteColor(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19;
  133. //! Returns if the sprite in the given state does loop
  134. virtual bool getSpriteLoop(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19;
  135. //! Returns if the sprite in the given state is scaled
  136. virtual bool getSpriteScale(gui::EGUI_BUTTON_STATE state) const OVERRIDE_19;
  137. //! Sets if the button should behave like a push button. Which means it
  138. //! can be in two states: Normal or Pressed. With a click on the button,
  139. //! the user can change the state of the button.
  140. virtual void setIsPushButton(bool isPushButton=true) override;
  141. //! Checks whether the button is a push button
  142. virtual bool isPushButton() const override;
  143. //! Sets the pressed state of the button if this is a pushbutton
  144. virtual void setPressed(bool pressed=true) override;
  145. //! Returns if the button is currently pressed
  146. virtual bool isPressed() const override;
  147. // PATCH
  148. //! Returns if this element (or one of its direct children) is hovered
  149. bool isHovered() const;
  150. // END PATCH
  151. //! Sets if the button should use the skin to draw its border
  152. virtual void setDrawBorder(bool border=true) override;
  153. //! Checks if the button face and border are being drawn
  154. virtual bool isDrawingBorder() const override;
  155. //! Sets if the alpha channel should be used for drawing images on the button (default is false)
  156. virtual void setUseAlphaChannel(bool useAlphaChannel=true) override;
  157. //! Checks if the alpha channel should be used for drawing images on the button
  158. virtual bool isAlphaChannelUsed() const override;
  159. //! Sets if the button should scale the button images to fit
  160. virtual void setScaleImage(bool scaleImage=true) override;
  161. //! Checks whether the button scales the used images
  162. virtual bool isScalingImage() const override;
  163. //! Get if the shift key was pressed in last EGET_BUTTON_CLICKED event
  164. virtual bool getClickShiftState() const OVERRIDE_19
  165. {
  166. return ClickShiftState;
  167. }
  168. //! Get if the control key was pressed in last EGET_BUTTON_CLICKED event
  169. virtual bool getClickControlState() const OVERRIDE_19
  170. {
  171. return ClickControlState;
  172. }
  173. void setColor(video::SColor color);
  174. // PATCH
  175. //! Set element properties from a StyleSpec corresponding to the button state
  176. void setFromState();
  177. //! Set element properties from a StyleSpec
  178. virtual void setFromStyle(const StyleSpec& style);
  179. //! Set the styles used for each state
  180. void setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES>& styles);
  181. // END PATCH
  182. //! Do not drop returned handle
  183. static GUIButton* addButton(gui::IGUIEnvironment *environment,
  184. const core::rect<s32>& rectangle, ISimpleTextureSource *tsrc,
  185. IGUIElement* parent, s32 id, const wchar_t* text,
  186. const wchar_t *tooltiptext=L"");
  187. protected:
  188. void drawSprite(gui::EGUI_BUTTON_STATE state, u32 startTime, const core::position2di& center);
  189. gui::EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed) const;
  190. ISimpleTextureSource *getTextureSource() { return TSrc; }
  191. struct ButtonImage
  192. {
  193. ButtonImage() : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
  194. {
  195. }
  196. ButtonImage(const ButtonImage& other) : Texture(0), SourceRect(core::rect<s32>(0,0,0,0))
  197. {
  198. *this = other;
  199. }
  200. ~ButtonImage()
  201. {
  202. if ( Texture )
  203. Texture->drop();
  204. }
  205. ButtonImage& operator=(const ButtonImage& other)
  206. {
  207. if ( this == &other )
  208. return *this;
  209. if (other.Texture)
  210. other.Texture->grab();
  211. if ( Texture )
  212. Texture->drop();
  213. Texture = other.Texture;
  214. SourceRect = other.SourceRect;
  215. return *this;
  216. }
  217. bool operator==(const ButtonImage& other) const
  218. {
  219. return Texture == other.Texture && SourceRect == other.SourceRect;
  220. }
  221. video::ITexture* Texture;
  222. core::rect<s32> SourceRect;
  223. };
  224. gui::EGUI_BUTTON_IMAGE_STATE getImageState(bool pressed, const ButtonImage* images) const;
  225. private:
  226. struct ButtonSprite
  227. {
  228. ButtonSprite() : Index(-1), Loop(false), Scale(false)
  229. {
  230. }
  231. bool operator==(const ButtonSprite& other) const
  232. {
  233. return Index == other.Index && Color == other.Color && Loop == other.Loop && Scale == other.Scale;
  234. }
  235. s32 Index;
  236. video::SColor Color;
  237. bool Loop;
  238. bool Scale;
  239. };
  240. ButtonSprite ButtonSprites[gui::EGBS_COUNT];
  241. gui::IGUISpriteBank* SpriteBank;
  242. ButtonImage ButtonImages[gui::EGBIS_COUNT];
  243. std::array<StyleSpec, StyleSpec::NUM_STATES> Styles;
  244. gui::IGUIFont* OverrideFont;
  245. bool OverrideColorEnabled;
  246. video::SColor OverrideColor;
  247. u32 ClickTime, HoverTime, FocusTime;
  248. bool ClickShiftState;
  249. bool ClickControlState;
  250. bool IsPushButton;
  251. bool Pressed;
  252. bool UseAlphaChannel;
  253. bool DrawBorder;
  254. bool ScaleImage;
  255. video::SColor Colors[4];
  256. // PATCH
  257. bool WasHovered = false;
  258. ISimpleTextureSource *TSrc;
  259. gui::IGUIStaticText *StaticText;
  260. core::rect<s32> BgMiddle;
  261. core::rect<s32> Padding;
  262. core::vector2d<s32> ContentOffset;
  263. video::SColor BgColor;
  264. // END PATCH
  265. };