guiProgressBitmapCtrl.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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. mUseVariable( false ),
  110. mTile( false ),
  111. mNumberOfBitmaps(0),
  112. mDim(0)
  113. {
  114. INIT_ASSET(Bitmap);
  115. }
  116. //-----------------------------------------------------------------------------
  117. void GuiProgressBitmapCtrl::initPersistFields()
  118. {
  119. INITPERSISTFIELD_IMAGEASSET(Bitmap, GuiProgressBitmapCtrl, "Bitmap file to use for rendering the progress bar.\n\n"
  120. "If the profile assigned to the control already has a bitmap assigned, this property need not be "
  121. "set in which case the bitmap from the profile is used.");
  122. Parent::initPersistFields();
  123. }
  124. //-----------------------------------------------------------------------------
  125. void GuiProgressBitmapCtrl::setBitmap( const char* name )
  126. {
  127. bool awake = mAwake;
  128. if( awake )
  129. onSleep();
  130. _setBitmap(StringTable->insert(name));
  131. if( awake )
  132. onWake();
  133. setUpdate();
  134. }
  135. //-----------------------------------------------------------------------------
  136. const char* GuiProgressBitmapCtrl::getScriptValue()
  137. {
  138. static const U32 bufSize = 64;
  139. char * ret = Con::getReturnBuffer(bufSize);
  140. dSprintf(ret, bufSize, "%g", mProgress);
  141. return ret;
  142. }
  143. //-----------------------------------------------------------------------------
  144. void GuiProgressBitmapCtrl::setScriptValue(const char *value)
  145. {
  146. //set the value
  147. if (! value)
  148. mProgress = 0.0f;
  149. else
  150. mProgress = dAtof(value);
  151. //validate the value
  152. mProgress = mClampF(mProgress, 0.f, 1.f);
  153. setUpdate();
  154. }
  155. //-----------------------------------------------------------------------------
  156. void GuiProgressBitmapCtrl::onPreRender()
  157. {
  158. const char * var = getVariable();
  159. if(var)
  160. {
  161. F32 value = mClampF(dAtof(var), 0.f, 1.f);
  162. if(value != mProgress)
  163. {
  164. mProgress = value;
  165. setUpdate();
  166. }
  167. }
  168. }
  169. //-----------------------------------------------------------------------------
  170. void GuiProgressBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
  171. {
  172. RectI ctrlRect(offset, getExtent());
  173. //grab lowest dimension
  174. if(getHeight() <= getWidth())
  175. mDim = getHeight();
  176. else
  177. mDim = getWidth();
  178. GFXDrawUtil* drawUtil = GFX->getDrawUtil();
  179. drawUtil->clearBitmapModulation();
  180. if(mNumberOfBitmaps == 1)
  181. {
  182. //draw the progress with image
  183. S32 width = (S32)((F32)(getWidth()) * mProgress);
  184. if (width > 0)
  185. {
  186. //drawing stretch bitmap
  187. RectI progressRect = ctrlRect;
  188. progressRect.extent.x = width;
  189. drawUtil->drawBitmapStretchSR(mProfile->getBitmapResource(), progressRect, mProfile->mBitmapArrayRects[0]);
  190. }
  191. }
  192. else if(mNumberOfBitmaps >= 3)
  193. {
  194. //drawing left-end bitmap
  195. RectI progressRectLeft(ctrlRect.point.x, ctrlRect.point.y, mDim, mDim);
  196. drawUtil->drawBitmapStretchSR(mProfile->getBitmapResource(), progressRectLeft, mProfile->mBitmapArrayRects[0]);
  197. //draw the progress with image
  198. S32 width = (S32)((F32)(getWidth()) * mProgress);
  199. if (width > mDim)
  200. {
  201. //drawing stretch bitmap
  202. RectI progressRect = ctrlRect;
  203. progressRect.point.x += mDim;
  204. progressRect.extent.x = (width - mDim - mDim);
  205. if (progressRect.extent.x < 0)
  206. progressRect.extent.x = 0;
  207. drawUtil->drawBitmapStretchSR(mProfile->getBitmapResource(), progressRect, mProfile->mBitmapArrayRects[1]);
  208. //drawing right-end bitmap
  209. RectI progressRectRight(progressRect.point.x + progressRect.extent.x, ctrlRect.point.y, mDim, mDim );
  210. drawUtil->drawBitmapStretchSR(mProfile->getBitmapResource(), progressRectRight, mProfile->mBitmapArrayRects[2]);
  211. }
  212. }
  213. else
  214. Con::warnf("guiProgressBitmapCtrl only processes an array of bitmaps == 1 or >= 3");
  215. //if there's a border, draw it
  216. if (mProfile->mBorder)
  217. drawUtil->drawRect(ctrlRect, mProfile->mBorderColor);
  218. Parent::onRender( offset, updateRect );
  219. //render the children
  220. renderChildControls(offset, updateRect);
  221. }
  222. //-----------------------------------------------------------------------------
  223. bool GuiProgressBitmapCtrl::onWake()
  224. {
  225. if(!Parent::onWake())
  226. return false;
  227. mNumberOfBitmaps = mProfile->constructBitmapArray();
  228. return true;
  229. }
  230. //=============================================================================
  231. // Console Methods.
  232. //=============================================================================
  233. // MARK: ---- Console Methods ----
  234. //-----------------------------------------------------------------------------
  235. DefineEngineMethod( GuiProgressBitmapCtrl, setBitmap, void, ( const char* filename ),,
  236. "Set the bitmap to use for rendering the progress bar.\n\n"
  237. "@param filename ~Path to the bitmap file.\n\n"
  238. "@note Directly assign to #bitmap rather than using this method.\n\n"
  239. "@see GuiProgressBitmapCtrl::setBitmap" )
  240. {
  241. object->setBitmap( filename );
  242. }