guiProgressBitmapCtrl.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 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. #include "platform/platform.h"
  23. #include "gui/game/guiProgressBitmapCtrl.h"
  24. #include "console/console.h"
  25. #include "console/consoleTypes.h"
  26. #include "console/engineAPI.h"
  27. #include "gfx/gfxDrawUtil.h"
  28. IMPLEMENT_CONOBJECT( GuiProgressBitmapCtrl );
  29. ConsoleDocClass( GuiProgressBitmapCtrl,
  30. "@brief A horizontal progress bar rendered from a repeating image.\n\n"
  31. "This class is used give progress feedback to the user. Unlike GuiProgressCtrl which simply "
  32. "renders a filled rectangle, GuiProgressBitmapCtrl renders the bar using a bitmap.\n\n"
  33. "This bitmap can either be simple, plain image which is then stretched into the current extents of the bar "
  34. "as it fills up or it can be a bitmap array with three entries. In the case of a bitmap array, the "
  35. "first entry in the array is used to render the left cap of the bar and the third entry in the array "
  36. "is used to render the right cap of the bar. The second entry is streched in-between the two caps.\n\n"
  37. "@tsexample\n"
  38. "// This example shows one way to break down a long-running computation into phases\n"
  39. "// and incrementally update a progress bar between the phases.\n"
  40. "\n"
  41. "new GuiProgressBitmapCtrl( Progress )\n"
  42. "{\n"
  43. " bitmap = \"core/art/gui/images/loading\";\n"
  44. " extent = \"300 50\";\n"
  45. " position = \"100 100\";\n"
  46. "};\n"
  47. "\n"
  48. "// Put the control on the canvas.\n"
  49. "%wrapper = new GuiControl();\n"
  50. "%wrapper.addObject( Progress );\n"
  51. "Canvas.pushDialog( %wrapper );\n"
  52. "\n"
  53. "// Start the computation.\n"
  54. "schedule( 1, 0, \"phase1\" );\n"
  55. "\n"
  56. "function phase1()\n"
  57. "{\n"
  58. " Progress.setValue( 0 );\n"
  59. "\n"
  60. " // Perform some computation.\n"
  61. " //...\n"
  62. "\n"
  63. " // Update progress.\n"
  64. " Progress.setValue( 0.25 );\n"
  65. "\n"
  66. " // Schedule next phase. Don't call directly so engine gets a change to run refresh.\n"
  67. " schedule( 1, 0, \"phase2\" );\n"
  68. "}\n"
  69. "\n"
  70. "function phase2()\n"
  71. "{\n"
  72. " // Perform some computation.\n"
  73. " //...\n"
  74. "\n"
  75. " // Update progress.\n"
  76. " Progress.setValue( 0.7 );\n"
  77. "\n"
  78. " // Schedule next phase. Don't call directly so engine gets a change to run refresh.\n"
  79. " schedule( 1, 0, \"phase3\" );\n"
  80. "}\n"
  81. "\n"
  82. "function phase3()\n"
  83. "{\n"
  84. " // Perform some computation.\n"
  85. " //...\n"
  86. "\n"
  87. " // Update progress.\n"
  88. " Progress.setValue( 0.9 );\n"
  89. "\n"
  90. " // Schedule next phase. Don't call directly so engine gets a change to run refresh.\n"
  91. " schedule( 1, 0, \"phase4\" );\n"
  92. "}\n"
  93. "\n"
  94. "function phase4()\n"
  95. "{\n"
  96. " // Perform some computation.\n"
  97. " //...\n"
  98. "\n"
  99. " // Final update of progress.\n"
  100. " Progress.setValue( 1.0 );\n"
  101. "}\n"
  102. "@endtsexample\n\n"
  103. "@see GuiProgressCtrl\n\n"
  104. "@ingroup GuiValues"
  105. );
  106. //-----------------------------------------------------------------------------
  107. GuiProgressBitmapCtrl::GuiProgressBitmapCtrl()
  108. : mProgress( 0.f ),
  109. mBitmapName( StringTable->EmptyString() ),
  110. mUseVariable( false ),
  111. mTile( false ),
  112. mNumberOfBitmaps(0),
  113. mDim(0)
  114. {
  115. }
  116. //-----------------------------------------------------------------------------
  117. void GuiProgressBitmapCtrl::initPersistFields()
  118. {
  119. addProtectedField( "bitmap", TypeFilename, Offset( mBitmapName, GuiProgressBitmapCtrl ),
  120. _setBitmap, defaultProtectedGetFn,
  121. "~Path to the bitmap file to use for rendering the progress bar.\n\n"
  122. "If the profile assigned to the control already has a bitmap assigned, this property need not be "
  123. "set in which case the bitmap from the profile is used."
  124. );
  125. Parent::initPersistFields();
  126. }
  127. //-----------------------------------------------------------------------------
  128. void GuiProgressBitmapCtrl::setBitmap( const char* name )
  129. {
  130. bool awake = mAwake;
  131. if( awake )
  132. onSleep();
  133. mBitmapName = StringTable->insert( name );
  134. if( awake )
  135. onWake();
  136. setUpdate();
  137. }
  138. //-----------------------------------------------------------------------------
  139. const char* GuiProgressBitmapCtrl::getScriptValue()
  140. {
  141. static const U32 bufSize = 64;
  142. char * ret = Con::getReturnBuffer(bufSize);
  143. dSprintf(ret, bufSize, "%g", mProgress);
  144. return ret;
  145. }
  146. //-----------------------------------------------------------------------------
  147. void GuiProgressBitmapCtrl::setScriptValue(const char *value)
  148. {
  149. //set the value
  150. if (! value)
  151. mProgress = 0.0f;
  152. else
  153. mProgress = dAtof(value);
  154. //validate the value
  155. mProgress = mClampF(mProgress, 0.f, 1.f);
  156. setUpdate();
  157. }
  158. //-----------------------------------------------------------------------------
  159. void GuiProgressBitmapCtrl::onPreRender()
  160. {
  161. const char * var = getVariable();
  162. if(var)
  163. {
  164. F32 value = mClampF(dAtof(var), 0.f, 1.f);
  165. if(value != mProgress)
  166. {
  167. mProgress = value;
  168. setUpdate();
  169. }
  170. }
  171. }
  172. //-----------------------------------------------------------------------------
  173. void GuiProgressBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
  174. {
  175. RectI ctrlRect(offset, getExtent());
  176. //grab lowest dimension
  177. if(getHeight() <= getWidth())
  178. mDim = getHeight();
  179. else
  180. mDim = getWidth();
  181. GFXDrawUtil* drawUtil = GFX->getDrawUtil();
  182. drawUtil->clearBitmapModulation();
  183. if(mNumberOfBitmaps == 1)
  184. {
  185. //draw the progress with image
  186. S32 width = (S32)((F32)(getWidth()) * mProgress);
  187. if (width > 0)
  188. {
  189. //drawing stretch bitmap
  190. RectI progressRect = ctrlRect;
  191. progressRect.extent.x = width;
  192. drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRect, mProfile->mBitmapArrayRects[0]);
  193. }
  194. }
  195. else if(mNumberOfBitmaps >= 3)
  196. {
  197. //drawing left-end bitmap
  198. RectI progressRectLeft(ctrlRect.point.x, ctrlRect.point.y, mDim, mDim);
  199. drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRectLeft, mProfile->mBitmapArrayRects[0]);
  200. //draw the progress with image
  201. S32 width = (S32)((F32)(getWidth()) * mProgress);
  202. if (width > mDim)
  203. {
  204. //drawing stretch bitmap
  205. RectI progressRect = ctrlRect;
  206. progressRect.point.x += mDim;
  207. progressRect.extent.x = (width - mDim - mDim);
  208. if (progressRect.extent.x < 0)
  209. progressRect.extent.x = 0;
  210. drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRect, mProfile->mBitmapArrayRects[1]);
  211. //drawing right-end bitmap
  212. RectI progressRectRight(progressRect.point.x + progressRect.extent.x, ctrlRect.point.y, mDim, mDim );
  213. drawUtil->drawBitmapStretchSR(mProfile->mTextureObject, progressRectRight, mProfile->mBitmapArrayRects[2]);
  214. }
  215. }
  216. else
  217. Con::warnf("guiProgressBitmapCtrl only processes an array of bitmaps == 1 or >= 3");
  218. //if there's a border, draw it
  219. if (mProfile->mBorder)
  220. drawUtil->drawRect(ctrlRect, mProfile->mBorderColor);
  221. Parent::onRender( offset, updateRect );
  222. //render the children
  223. renderChildControls(offset, updateRect);
  224. }
  225. //-----------------------------------------------------------------------------
  226. bool GuiProgressBitmapCtrl::onWake()
  227. {
  228. if(!Parent::onWake())
  229. return false;
  230. mNumberOfBitmaps = mProfile->constructBitmapArray();
  231. return true;
  232. }
  233. //=============================================================================
  234. // Console Methods.
  235. //=============================================================================
  236. // MARK: ---- Console Methods ----
  237. //-----------------------------------------------------------------------------
  238. DefineEngineMethod( GuiProgressBitmapCtrl, setBitmap, void, ( const char* filename ),,
  239. "Set the bitmap to use for rendering the progress bar.\n\n"
  240. "@param filename ~Path to the bitmap file.\n\n"
  241. "@note Directly assign to #bitmap rather than using this method.\n\n"
  242. "@see GuiProgressBitmapCtrl::setBitmap" )
  243. {
  244. object->setBitmap( filename );
  245. }