guiSceneScrollCtrl.cc 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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. #include "console/consoleTypes.h"
  23. #include "console/console.h"
  24. #include "graphics/gBitmap.h"
  25. #include "graphics/TextureManager.h"
  26. #include "io/resource/resourceManager.h"
  27. #include "platform/event.h"
  28. #include "graphics/dgl.h"
  29. #include "gui/guiArrayCtrl.h"
  30. #include "gui/containers/guiSceneScrollCtrl.h"
  31. #include "gui/guiDefaultControlRender.h"
  32. #include "gui/guiCanvas.h"
  33. // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
  34. GuiSceneScrollCtrl::GuiSceneScrollCtrl(SceneWindow* window) : GuiScrollCtrl()
  35. {
  36. mWindow = window;
  37. }
  38. void GuiSceneScrollCtrl::initPersistFields()
  39. {
  40. //Not a con object...
  41. }
  42. bool GuiSceneScrollCtrl::onWake()
  43. {
  44. if (mAwake)
  45. return false;
  46. if (mProfile != NULL)
  47. mProfile->incRefCount();
  48. if (mThumbProfile != NULL)
  49. mThumbProfile->incRefCount();
  50. if (mTrackProfile != NULL)
  51. mTrackProfile->incRefCount();
  52. if (mArrowProfile != NULL)
  53. mArrowProfile->incRefCount();
  54. mAwake = true;
  55. return true;
  56. }
  57. void GuiSceneScrollCtrl::onSleep()
  58. {
  59. if (!mAwake)
  60. return;
  61. if (mProfile != NULL)
  62. mProfile->decRefCount();
  63. if (mThumbProfile != NULL)
  64. mThumbProfile->decRefCount();
  65. if (mTrackProfile != NULL)
  66. mTrackProfile->decRefCount();
  67. if (mArrowProfile != NULL)
  68. mArrowProfile->decRefCount();
  69. mAwake = false;
  70. }
  71. #pragma region CalculationFunctions
  72. void GuiSceneScrollCtrl::calcContentExtents()
  73. {
  74. Vector2 v = mWindow->getCameraSize();
  75. mContentExt = Point2I(mCeil(v.x), mCeil(v.y));
  76. F32 zoom = getMax(mWindow->getCameraZoom(), 0.0000001f);
  77. mContentExt.x /= zoom;
  78. mContentExt.y /= zoom;
  79. //This will be removed later so we are countering it now.
  80. if (mHasVScrollBar)
  81. mContentExt.x += mScrollBarThickness;
  82. if (mHasHScrollBar)
  83. mContentExt.y += mScrollBarThickness;
  84. }
  85. bool GuiSceneScrollCtrl::calcChildExtents()
  86. {
  87. if (!mWindow->isViewLimitOn())
  88. return false;
  89. Vector2 v = mWindow->getViewLimitMax() - mWindow->getViewLimitMin();
  90. mChildExt = Point2I(mFloor(v.x), mFloor(v.y));
  91. return true;
  92. }
  93. void GuiSceneScrollCtrl::calcScrollOffset()
  94. {
  95. //Set the offset based on the position of the visible area of the window
  96. RectF cameraArea = mWindow->getCameraArea();
  97. F32 zoom = getMax(mWindow->getCameraZoom(), 0.0000001f);
  98. Point2F actualExtent = Point2F(cameraArea.extent);
  99. cameraArea.extent.x /= zoom;
  100. cameraArea.extent.y /= zoom;
  101. cameraArea.point.x += ((actualExtent.x - cameraArea.extent.x) / 2);
  102. cameraArea.point.y += ((actualExtent.y - cameraArea.extent.y) / 2);
  103. Vector2 min = mWindow->getViewLimitMin();
  104. Vector2 max = mWindow->getViewLimitMax();
  105. mScrollOffset.x = mRound(cameraArea.point.x - min.x);
  106. mScrollOffset.y = mRound(max.y - (cameraArea.point.y + cameraArea.extent.y));
  107. }
  108. void GuiSceneScrollCtrl::calcScrollRects(RectI &fillRect)
  109. {
  110. RectI rect = RectI(Point2I(0,0), mWindow->mBounds.extent);
  111. Parent::calcScrollRects(rect);
  112. }
  113. #pragma endregion
  114. #pragma region ScrollingFunctions
  115. void GuiSceneScrollCtrl::scrollDelta(S32 deltaX, S32 deltaY)
  116. {
  117. Vector2 pos = mWindow->getCameraPosition();
  118. Vector2 size = mWindow->getCameraSize() / mWindow->getCameraZoom();
  119. pos.x += deltaX;
  120. pos.y -= deltaY;
  121. Vector2 min = mWindow->getViewLimitMin();
  122. Vector2 max = mWindow->getViewLimitMax();
  123. pos.x = getMax(pos.x, min.x + (size.x / 2));
  124. pos.y = getMax(pos.y, min.y + (size.y / 2));
  125. pos.x = getMin(pos.x, max.x - (size.x / 2));
  126. pos.y = getMin(pos.y, max.y - (size.y / 2));
  127. mWindow->setTargetCameraPosition(pos);
  128. mWindow->startCameraMove(0.2);
  129. }
  130. void GuiSceneScrollCtrl::scrollTo(S32 x, S32 y)
  131. {
  132. Vector2 pos = mWindow->getCameraPosition();
  133. Vector2 size = mWindow->getCameraSize() / mWindow->getCameraZoom();
  134. Vector2 min = mWindow->getViewLimitMin();
  135. Vector2 max = mWindow->getViewLimitMax();
  136. if (x != mScrollOffset.x)
  137. {
  138. F32 halfW = size.x / 2;
  139. pos.x = getMin(getMax(x + halfW + min.x, min.x + halfW), max.x - halfW);
  140. }
  141. if (y != mScrollOffset.y)
  142. {
  143. F32 halfH = size.y / 2;
  144. pos.y = getMin(getMax(max.y - (y + halfH), min.y + halfH), max.y - halfH);
  145. }
  146. mWindow->setCameraPosition(pos);
  147. }
  148. void GuiSceneScrollCtrl::scrollByRegion(Region reg)
  149. {
  150. Vector2 v = mWindow->getCameraSize() / mWindow->getCameraZoom();
  151. U32 pageWidth = mCeil(v.x * 0.8);
  152. U32 pageHeight = mCeil(v.y * 0.8);
  153. U32 columnWidth = mCeil(v.x * 0.1);
  154. U32 rowHeight = mCeil(v.y * 0.1);
  155. if (mVBarEnabled)
  156. {
  157. switch (reg)
  158. {
  159. case UpPage:
  160. scrollDelta(0, -(S32)pageHeight);
  161. break;
  162. case DownPage:
  163. scrollDelta(0, pageHeight);
  164. break;
  165. case UpArrow:
  166. scrollDelta(0, -(S32)rowHeight);
  167. break;
  168. case DownArrow:
  169. scrollDelta(0, rowHeight);
  170. break;
  171. case LeftArrow:
  172. case RightArrow:
  173. case LeftPage:
  174. case RightPage:
  175. case VertThumb:
  176. case HorizThumb:
  177. case Content:
  178. //Con::errorf("Unhandled case in GuiSceneScrollCtrl::scrollByRegion");
  179. break;
  180. }
  181. }
  182. if (mHBarEnabled)
  183. {
  184. switch (reg)
  185. {
  186. case LeftPage:
  187. scrollDelta(-(S32)pageWidth, 0);
  188. break;
  189. case RightPage:
  190. scrollDelta(pageWidth, 0);
  191. break;
  192. case LeftArrow:
  193. scrollDelta(-(S32)columnWidth, 0);
  194. break;
  195. case RightArrow:
  196. scrollDelta(columnWidth, 0);
  197. break;
  198. case UpArrow:
  199. case DownArrow:
  200. case UpPage:
  201. case DownPage:
  202. case VertThumb:
  203. case HorizThumb:
  204. case Content:
  205. //Con::errorf("Unhandled case in GuiSceneScrollCtrl::scrollByRegion");
  206. break;
  207. }
  208. }
  209. }
  210. void GuiSceneScrollCtrl::scrollRectVisible(RectI rect)
  211. {
  212. //We don't do this...
  213. }
  214. #pragma endregion
  215. #pragma region Event_Processing
  216. Point2I GuiSceneScrollCtrl::localToGlobalCoord(const Point2I &src)
  217. {
  218. return mWindow->localToGlobalCoord(src);
  219. }
  220. Point2I GuiSceneScrollCtrl::globalToLocalCoord(const Point2I &src)
  221. {
  222. return mWindow->globalToLocalCoord(src);
  223. }
  224. void GuiSceneScrollCtrl::onTouchDown(const GuiEvent &event)
  225. {
  226. Point2I curMousePos = globalToLocalCoord(event.mousePoint);
  227. mDepressed = true;
  228. mouseLock();
  229. // Set a 0.5 second delay before we start scrolling
  230. mLastUpdated = Platform::getVirtualMilliseconds() + 500;
  231. scrollByRegion(curHitRegion);
  232. if (curHitRegion == VertThumb)
  233. {
  234. mScrollOffsetAnchor = mScrollOffset;
  235. mThumbMouseDelta = curMousePos.y - mVThumbPos;
  236. }
  237. else if (curHitRegion == HorizThumb)
  238. {
  239. mScrollOffsetAnchor = mScrollOffset;
  240. mThumbMouseDelta = curMousePos.x - mHThumbPos;
  241. }
  242. }
  243. void GuiSceneScrollCtrl::onTouchDragged(const GuiEvent &event)
  244. {
  245. Point2I curMousePos = globalToLocalCoord(event.mousePoint);
  246. mWindow->setUpdate();
  247. if ((curHitRegion != VertThumb) && (curHitRegion != HorizThumb))
  248. {
  249. Region hit = findHitRegion(curMousePos);
  250. if (hit != curHitRegion)
  251. mDepressed = false;
  252. else
  253. mDepressed = true;
  254. return;
  255. }
  256. // ok... if the mouse is 'near' the scroll bar, scroll with it
  257. // otherwise, snap back to the previous position.
  258. if (curHitRegion == VertThumb)
  259. {
  260. if (curMousePos.x >= mVTrackRect.point.x - mScrollBarDragTolerance &&
  261. curMousePos.x <= mVTrackRect.point.x + mVTrackRect.extent.x - 1 + mScrollBarDragTolerance &&
  262. curMousePos.y >= mVTrackRect.point.y - mScrollBarDragTolerance &&
  263. curMousePos.y <= mVTrackRect.point.y + mVTrackRect.extent.y - 1 + mScrollBarDragTolerance)
  264. {
  265. S32 newVThumbPos = curMousePos.y - mThumbMouseDelta;
  266. if (newVThumbPos != mVThumbPos)
  267. {
  268. S32 newVPos = (newVThumbPos) *
  269. (mChildExt.y - mContentExt.y) /
  270. (mVTrackRect.extent.y - mVThumbSize);
  271. scrollTo(mScrollOffset.x, newVPos);
  272. }
  273. }
  274. else
  275. scrollTo(mScrollOffset.x, mScrollOffsetAnchor.y);
  276. }
  277. else if (curHitRegion == HorizThumb)
  278. {
  279. if (curMousePos.x >= mHTrackRect.point.x - mScrollBarDragTolerance &&
  280. curMousePos.x <= mHTrackRect.point.x + mHTrackRect.extent.x - 1 + mScrollBarDragTolerance &&
  281. curMousePos.y >= mHTrackRect.point.y - mScrollBarDragTolerance &&
  282. curMousePos.y <= mHTrackRect.point.y + mHTrackRect.extent.y - 1 + mScrollBarDragTolerance)
  283. {
  284. S32 newHThumbPos = curMousePos.x - mThumbMouseDelta;
  285. if (newHThumbPos != mHThumbPos)
  286. {
  287. S32 newHPos = (newHThumbPos) *
  288. (mChildExt.x - mContentExt.x) /
  289. (mHTrackRect.extent.x - mHThumbSize);
  290. scrollTo(newHPos, mScrollOffset.y);
  291. }
  292. }
  293. else
  294. scrollTo(mScrollOffsetAnchor.x, mScrollOffset.y);
  295. }
  296. }
  297. bool GuiSceneScrollCtrl::isMouseLocked()
  298. {
  299. GuiCanvas *root = mWindow->getRoot();
  300. return root ? root->getMouseLockedControl() == this : false;
  301. }
  302. void GuiSceneScrollCtrl::mouseLock(GuiControl *lockingControl)
  303. {
  304. GuiCanvas *root = mWindow->getRoot();
  305. if (root)
  306. root->mouseLock(lockingControl);
  307. }
  308. void GuiSceneScrollCtrl::mouseLock()
  309. {
  310. GuiCanvas *root = mWindow->getRoot();
  311. if (root)
  312. root->mouseLock(this);
  313. }
  314. void GuiSceneScrollCtrl::mouseUnlock()
  315. {
  316. GuiCanvas *root = mWindow->getRoot();
  317. if (root)
  318. root->mouseUnlock(this);
  319. }
  320. #pragma endregion
  321. #pragma region rendering
  322. void GuiSceneScrollCtrl::onRender(Point2I offset, const RectI &updateRect)
  323. {
  324. RectI contentRect = applyScrollBarSpacing(offset, mBounds.extent);
  325. mChildArea.set(contentRect.point, contentRect.extent);
  326. renderVScrollBar(offset);
  327. renderHScrollBar(offset);
  328. }
  329. #pragma endregion