guiImageButtonCtrl.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _GUIIMAGEBUTTON_H_
  23. #include "2d/gui/guiImageButtonCtrl.h"
  24. #endif
  25. #ifndef _RENDER_PROXY_H_
  26. #include "2d/core/RenderProxy.h"
  27. #endif
  28. #ifndef _DGL_H_
  29. #include "graphics/dgl.h"
  30. #endif
  31. #ifndef _CONSOLE_H_
  32. #include "console/console.h"
  33. #endif
  34. #ifndef _CONSOLETYPES_H_
  35. #include "console/consoleTypes.h"
  36. #endif
  37. #ifndef _GUICANVAS_H_
  38. #include "gui/guiCanvas.h"
  39. #endif
  40. #ifndef _H_GUIDEFAULTCONTROLRENDER_
  41. #include "gui/guiDefaultControlRender.h"
  42. #endif
  43. /// Script bindings.
  44. #include "guiImageButtonCtrl_ScriptBindings.h"
  45. //-----------------------------------------------------------------------------
  46. IMPLEMENT_CONOBJECT(GuiImageButtonCtrl);
  47. //-----------------------------------------------------------------------------
  48. GuiImageButtonCtrl::GuiImageButtonCtrl() :
  49. mNormalAssetId( StringTable->EmptyString ),
  50. mHoverAssetId( StringTable->EmptyString ),
  51. mDownAssetId( StringTable->EmptyString ),
  52. mInactiveAssetId( StringTable->EmptyString )
  53. {
  54. mBounds.extent.set(140, 30);
  55. }
  56. //-----------------------------------------------------------------------------
  57. void GuiImageButtonCtrl::initPersistFields()
  58. {
  59. // Call parent.
  60. Parent::initPersistFields();
  61. addProtectedField("NormalImage", TypeAssetId, Offset(mNormalAssetId, GuiImageButtonCtrl), &setNormalImage, &getNormalImage, "The image asset Id used for the normal button state.");
  62. addProtectedField("HoverImage", TypeAssetId, Offset(mHoverAssetId, GuiImageButtonCtrl), &setHoverImage, &getHoverImage, "The image asset Id used for the hover button state.");
  63. addProtectedField("DownImage", TypeAssetId, Offset(mDownAssetId, GuiImageButtonCtrl), &setDownImage, &getDownImage, "The image asset Id used for the Down button state.");
  64. addProtectedField("InactiveImage", TypeAssetId, Offset(mInactiveAssetId, GuiImageButtonCtrl), &setInactiveImage, &getInactiveImage, "The image asset Id used for the inactive button state.");
  65. }
  66. //-----------------------------------------------------------------------------
  67. bool GuiImageButtonCtrl::onWake()
  68. {
  69. // Call parent.
  70. if (!Parent::onWake())
  71. return false;
  72. // Is only the "normal" image specified?
  73. if ( mNormalAssetId != StringTable->EmptyString &&
  74. mHoverAssetId == StringTable->EmptyString &&
  75. mDownAssetId == StringTable->EmptyString &&
  76. mInactiveAssetId == StringTable->EmptyString )
  77. {
  78. // Yes, so use it for all states.
  79. mImageNormalAsset = mNormalAssetId;
  80. mImageHoverAsset = mNormalAssetId;
  81. mImageDownAsset = mNormalAssetId;
  82. mImageInactiveAsset = mNormalAssetId;
  83. }
  84. else
  85. {
  86. // No, so assign individual states.
  87. mImageNormalAsset = mNormalAssetId;
  88. mImageHoverAsset = mHoverAssetId;
  89. mImageDownAsset = mDownAssetId;
  90. mImageInactiveAsset = mInactiveAssetId;
  91. }
  92. return true;
  93. }
  94. //-----------------------------------------------------------------------------
  95. void GuiImageButtonCtrl::onSleep()
  96. {
  97. // Clear assets.
  98. mImageNormalAsset.clear();
  99. mImageHoverAsset.clear();
  100. mImageDownAsset.clear();
  101. mImageInactiveAsset.clear();
  102. // Call parent.
  103. Parent::onSleep();
  104. }
  105. //-----------------------------------------------------------------------------
  106. void GuiImageButtonCtrl::setNormalImage( const char* pImageAssetId )
  107. {
  108. // Sanity!
  109. AssertFatal( pImageAssetId != NULL, "Cannot use a NULL asset Id." );
  110. // Fetch the asset Id.
  111. mNormalAssetId = StringTable->insert(pImageAssetId);
  112. // Assign asset if awake.
  113. if ( isAwake() )
  114. mImageNormalAsset = mNormalAssetId;
  115. // Update control.
  116. setUpdate();
  117. }
  118. //-----------------------------------------------------------------------------
  119. void GuiImageButtonCtrl::setHoverImage( const char* pImageAssetId )
  120. {
  121. // Sanity!
  122. AssertFatal( pImageAssetId != NULL, "Cannot use a NULL asset Id." );
  123. // Fetch the asset Id.
  124. mHoverAssetId = StringTable->insert(pImageAssetId);
  125. // Assign asset if awake.
  126. if ( isAwake() )
  127. mImageHoverAsset = mHoverAssetId;
  128. // Update control.
  129. setUpdate();
  130. }
  131. //-----------------------------------------------------------------------------
  132. void GuiImageButtonCtrl::setDownImage( const char* pImageAssetId )
  133. {
  134. // Sanity!
  135. AssertFatal( pImageAssetId != NULL, "Cannot use a NULL asset Id." );
  136. // Fetch the asset Id.
  137. mDownAssetId = StringTable->insert(pImageAssetId);
  138. // Assign asset if awake.
  139. if ( isAwake() )
  140. mImageDownAsset = mDownAssetId;
  141. // Update control.
  142. setUpdate();
  143. }
  144. //-----------------------------------------------------------------------------
  145. void GuiImageButtonCtrl::setInactiveImage( const char* pImageAssetId )
  146. {
  147. // Sanity!
  148. AssertFatal( pImageAssetId != NULL, "Cannot use a NULL asset Id." );
  149. // Fetch the asset Id.
  150. mInactiveAssetId = StringTable->insert(pImageAssetId);
  151. // Assign asset if awake.
  152. if ( isAwake() )
  153. mImageInactiveAsset = mInactiveAssetId;
  154. // Update control.
  155. setUpdate();
  156. }
  157. //-----------------------------------------------------------------------------
  158. void GuiImageButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
  159. {
  160. // Reset button state.
  161. ButtonState state = NORMAL;
  162. // Calculate button state.
  163. if ( mActive )
  164. {
  165. if ( mMouseOver )
  166. state = HOVER;
  167. if ( mDepressed || mStateOn )
  168. state = DOWN;
  169. }
  170. else
  171. {
  172. state = INACTIVE;
  173. }
  174. switch (state)
  175. {
  176. case NORMAL:
  177. {
  178. // Render the "normal" asset.
  179. renderButton(mImageNormalAsset, 0, offset, updateRect);
  180. } break;
  181. case HOVER:
  182. {
  183. // Render the "hover" asset.
  184. renderButton(mImageHoverAsset, 0, offset, updateRect);
  185. } break;
  186. case DOWN:
  187. {
  188. // Render the "down" asset.
  189. renderButton(mImageDownAsset, 0, offset, updateRect);
  190. } break;
  191. case INACTIVE:
  192. {
  193. // Render the "inactive" asset.
  194. renderButton(mImageInactiveAsset, 0, offset, updateRect);
  195. } break;
  196. }
  197. }
  198. //------------------------------------------------------------------------------
  199. void GuiImageButtonCtrl::renderButton( ImageAsset* pImageAsset, const U32 frame, Point2I &offset, const RectI& updateRect )
  200. {
  201. // Ignore an invalid datablock.
  202. if ( pImageAsset == NULL )
  203. return;
  204. // Is the asset valid and has the specified frame?
  205. if ( pImageAsset->isAssetValid() && frame < pImageAsset->getFrameCount() )
  206. {
  207. // Yes, so calculate the source region.
  208. const ImageAsset::FrameArea::PixelArea& pixelArea = pImageAsset->getImageFrameArea( frame ).mPixelArea;
  209. RectI sourceRegion( pixelArea.mPixelOffset, Point2I(pixelArea.mPixelWidth, pixelArea.mPixelHeight) );
  210. // Calculate destination region.
  211. RectI destinationRegion(offset, mBounds.extent);
  212. // Render image.
  213. dglSetBitmapModulation( mProfile->mFillColor );
  214. dglDrawBitmapStretchSR( pImageAsset->getImageTexture(), destinationRegion, sourceRegion );
  215. dglClearBitmapModulation();
  216. renderChildControls( offset, updateRect);
  217. }
  218. else
  219. {
  220. // No, so fetch the 'cannot render' proxy.
  221. RenderProxy* pNoImageRenderProxy = Sim::findObject<RenderProxy>( CANNOT_RENDER_PROXY_NAME );
  222. // Finish if no render proxy available or it can't render.
  223. if ( pNoImageRenderProxy == NULL || !pNoImageRenderProxy->validRender() )
  224. return;
  225. // Render using render-proxy..
  226. pNoImageRenderProxy->renderGui( *this, offset, updateRect );
  227. }
  228. // Update the control.
  229. setUpdate();
  230. }