GadgetHorizontalSlider.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: HorizontalSlider.cpp /////////////////////////////////////////////////
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Westwood Studios Pacific.
  27. //
  28. // Confidential Information
  29. // Copyright (C) 2001 - All Rights Reserved
  30. //
  31. //-----------------------------------------------------------------------------
  32. //
  33. // Project: RTS3
  34. //
  35. // File name: HorizontalSlider.cpp
  36. //
  37. // Created: Colin Day, June 2001
  38. //
  39. // Desc: Horizontal GUI slider
  40. //
  41. //-----------------------------------------------------------------------------
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
  44. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  45. // USER INCLUDES //////////////////////////////////////////////////////////////
  46. #include "Common/Language.h"
  47. #include "Gameclient/GameWindowManager.h"
  48. #include "GameClient/Gadget.h"
  49. #include "GameClient/GadgetSlider.h"
  50. // DEFINES ////////////////////////////////////////////////////////////////////
  51. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  52. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  53. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  54. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  55. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  56. ///////////////////////////////////////////////////////////////////////////////
  57. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  58. ///////////////////////////////////////////////////////////////////////////////
  59. #ifdef _INTERNAL
  60. // for occasional debugging...
  61. //#pragma optimize("", off)
  62. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  63. #endif
  64. // GadgetHorizontalSliderInput ================================================
  65. /** Handle input for horizontal slider */
  66. //=============================================================================
  67. WindowMsgHandledType GadgetHorizontalSliderInput( GameWindow *window, UnsignedInt msg,
  68. WindowMsgData mData1, WindowMsgData mData2 )
  69. {
  70. SliderData *s = (SliderData *)window->winGetUserData();
  71. WinInstanceData *instData = window->winGetInstanceData();
  72. ICoord2D size, childSize, childCenter;
  73. window->winGetSize( &size.x, &size.y );
  74. switch( msg )
  75. {
  76. // ------------------------------------------------------------------------
  77. case GWM_MOUSE_ENTERING:
  78. {
  79. if( BitTest( instData->getStyle(), GWS_MOUSE_TRACK ) )
  80. {
  81. BitSet( instData->m_state, WIN_STATE_HILITED );
  82. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  83. GBM_MOUSE_ENTERING,
  84. (WindowMsgData)window,
  85. 0 );
  86. //TheWindowManager->winSetFocus( window );
  87. } // end if
  88. if(window->winGetChild() && BitTest(window->winGetChild()->winGetStyle(),GWS_PUSH_BUTTON) )
  89. {
  90. WinInstanceData *instDataChild = window->winGetChild()->winGetInstanceData();
  91. BitSet(instDataChild->m_state, WIN_STATE_HILITED);
  92. }
  93. break;
  94. } // end mouse entering
  95. // ------------------------------------------------------------------------
  96. case GWM_MOUSE_LEAVING:
  97. {
  98. if( BitTest( instData->getStyle(), GWS_MOUSE_TRACK ))
  99. {
  100. BitClear( instData->m_state, WIN_STATE_HILITED );
  101. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  102. GBM_MOUSE_LEAVING,
  103. (WindowMsgData)window,
  104. 0 );
  105. } // end if
  106. if(window->winGetChild() && BitTest(window->winGetChild()->winGetStyle(),GWS_PUSH_BUTTON) )
  107. {
  108. WinInstanceData *instDataChild = window->winGetChild()->winGetInstanceData();
  109. BitClear(instDataChild->m_state, WIN_STATE_HILITED);
  110. }
  111. break;
  112. } // end mouse leaving
  113. // ------------------------------------------------------------------------
  114. case GWM_LEFT_DRAG:
  115. if( BitTest( instData->getStyle(), GWS_MOUSE_TRACK ) )
  116. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  117. GGM_LEFT_DRAG,
  118. (WindowMsgData)window,
  119. mData1 );
  120. break;
  121. // ------------------------------------------------------------------------
  122. case GWM_LEFT_DOWN:
  123. break;
  124. // ------------------------------------------------------------------------
  125. case GWM_LEFT_UP:
  126. {
  127. Int x, y;
  128. Int mousex = mData1 & 0xFFFF;
  129. // Int mousey = mData1 >> 16;
  130. GameWindow *child = window->winGetChild();
  131. Int pageClickSize, clickPos;
  132. window->winGetScreenPosition( &x, &y );
  133. child->winGetSize( &childSize.x, &childSize.y );
  134. child->winGetPosition( &childCenter.x, &childCenter.y );
  135. childCenter.x += childSize.x / 2;
  136. childCenter.y += childSize.y / 2;
  137. //
  138. // when you click on the slider, but not the button, we will jump
  139. // the slider position up/down by this much
  140. //
  141. pageClickSize = size.x / 5;
  142. clickPos = mousex - x;
  143. if( clickPos >= childCenter.x )
  144. {
  145. clickPos = childCenter.x + pageClickSize;
  146. if( clickPos > mousex - x )
  147. clickPos = mousex - x;
  148. } // end if
  149. else
  150. {
  151. clickPos = childCenter.x - pageClickSize;
  152. if( clickPos < mousex - x )
  153. clickPos = mousex - x;
  154. } // end else
  155. // keep it all valid to the window
  156. if( clickPos > x + size.x - childSize.x / 2 )
  157. clickPos = x + size.y - childSize.x / 2;
  158. if( clickPos < childSize.x / 2 )
  159. clickPos = childSize.x / 2;
  160. child->winSetPosition( clickPos - childSize.x / 2, HORIZONTAL_SLIDER_THUMB_POSITION);
  161. TheWindowManager->winSendSystemMsg( window, GGM_LEFT_DRAG, 0, mData1 );
  162. break;
  163. } // end left up, left click
  164. // ------------------------------------------------------------------------
  165. case GWM_CHAR:
  166. {
  167. switch( mData1 )
  168. {
  169. // --------------------------------------------------------------------
  170. case KEY_RIGHT:
  171. if( BitTest( mData2, KEY_STATE_DOWN ) )
  172. {
  173. if( s->position > s->minVal + 1 )
  174. {
  175. GameWindow *child = window->winGetChild();
  176. s->position -= 2;
  177. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  178. GSM_SLIDER_TRACK,
  179. (WindowMsgData)window,
  180. s->position );
  181. // Translate to window coords
  182. child->winSetPosition( (Int)((s->position - s->minVal) * s->numTicks), HORIZONTAL_SLIDER_THUMB_POSITION );
  183. } // end if
  184. } // if key down
  185. break;
  186. // --------------------------------------------------------------------
  187. case KEY_LEFT:
  188. if( BitTest( mData2, KEY_STATE_DOWN ) )
  189. {
  190. if( s->position < s->maxVal - 1 )
  191. {
  192. GameWindow *child = window->winGetChild();
  193. s->position += 2;
  194. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  195. GSM_SLIDER_TRACK,
  196. (WindowMsgData)window,
  197. s->position );
  198. // Translate to window coords
  199. child->winSetPosition( (Int)((s->position - s->minVal) * s->numTicks),HORIZONTAL_SLIDER_THUMB_POSITION );
  200. }
  201. } // end if key down
  202. break;
  203. // --------------------------------------------------------------------
  204. case KEY_DOWN:
  205. case KEY_TAB:
  206. if( BitTest( mData2, KEY_STATE_DOWN ) )
  207. window->winNextTab();
  208. break;
  209. // --------------------------------------------------------------------
  210. case KEY_UP:
  211. if( BitTest( mData2, KEY_STATE_DOWN ) )
  212. window->winPrevTab();
  213. break;
  214. // --------------------------------------------------------------------
  215. default:
  216. return MSG_IGNORED;
  217. } // end switch( mData1 )
  218. break;
  219. } // end char
  220. // ------------------------------------------------------------------------
  221. default:
  222. return MSG_IGNORED;
  223. }
  224. return MSG_HANDLED;
  225. } // end GadgetHorizontalSliderInput
  226. // GadgetHorizontalSliderSystem ===============================================
  227. /** Handle system messages for horizontal slider */
  228. //=============================================================================
  229. WindowMsgHandledType GadgetHorizontalSliderSystem( GameWindow *window, UnsignedInt msg,
  230. WindowMsgData mData1, WindowMsgData mData2 )
  231. {
  232. SliderData *s = (SliderData *)window->winGetUserData();
  233. WinInstanceData *instData = window->winGetInstanceData();
  234. ICoord2D size, childSize, childCenter,childRelativePos;
  235. window->winGetSize( &size.x, &size.y );
  236. switch( msg )
  237. {
  238. // ------------------------------------------------------------------------
  239. case GGM_LEFT_DRAG:
  240. {
  241. Int mousex = mData2 & 0xFFFF;
  242. // Int mousey = mData2 >> 16;
  243. Int x, y, delta;
  244. GameWindow *child = window->winGetChild();
  245. window->winGetScreenPosition( &x, &y );
  246. child->winGetSize( &childSize.x, &childSize.y );
  247. child->winGetScreenPosition( &childCenter.x, &childCenter.y );
  248. child->winGetPosition(&childRelativePos.x, &childRelativePos.y);
  249. childCenter.x += childSize.x / 2;
  250. childCenter.y += childSize.y / 2;
  251. //
  252. // ignore drag attempts when the mouse is right or left of slider totally
  253. // and put the dragging thumb back at the slider pos
  254. //
  255. if( mousex > x + size.x -HORIZONTAL_SLIDER_THUMB_WIDTH/2 )
  256. {
  257. TheWindowManager->winSendSystemMsg( window, GSM_SET_SLIDER,
  258. s->maxVal, 0 );
  259. // tell owner i moved
  260. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  261. GSM_SLIDER_TRACK,
  262. (WindowMsgData)window,
  263. s->position );
  264. break;
  265. } // end if
  266. else if( mousex < x + HORIZONTAL_SLIDER_THUMB_WIDTH/2)
  267. {
  268. TheWindowManager->winSendSystemMsg( window, GSM_SET_SLIDER,
  269. s->minVal, 0 );
  270. // tell owner i moved
  271. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  272. GSM_SLIDER_TRACK,
  273. (WindowMsgData)window,
  274. s->position );
  275. break;
  276. } // end else if
  277. if( childCenter.x < x + childSize.x / 2 )
  278. {
  279. child->winSetPosition( 0,HORIZONTAL_SLIDER_THUMB_POSITION );
  280. s->position = s->minVal;
  281. }
  282. else if( childCenter.x >= x + size.x - childSize.x / 2 )
  283. {
  284. child->winSetPosition( (Int)((s->maxVal - s->minVal) * s->numTicks) -HORIZONTAL_SLIDER_THUMB_WIDTH/2 , HORIZONTAL_SLIDER_THUMB_POSITION );
  285. s->position = s->maxVal;
  286. }
  287. else
  288. {
  289. delta = childCenter.x - x -HORIZONTAL_SLIDER_THUMB_WIDTH/2;
  290. // Calc slider position
  291. s->position = (Int)((delta) / s->numTicks)+ s->minVal ;
  292. /*
  293. s->position += s->minVal;
  294. */
  295. if( s->position > s->maxVal )
  296. s->position = s->maxVal;
  297. if( s->position < s->minVal)
  298. s->position = s->minVal;
  299. child->winSetPosition( childRelativePos.x, HORIZONTAL_SLIDER_THUMB_POSITION );
  300. }
  301. // tell owner i moved
  302. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  303. GSM_SLIDER_TRACK,
  304. (WindowMsgData)window,
  305. s->position );
  306. break;
  307. } // end left drag
  308. // ------------------------------------------------------------------------
  309. case GSM_SET_SLIDER:
  310. {
  311. Int newPos = (Int)mData1;
  312. GameWindow *child = window->winGetChild();
  313. if( newPos < s->minVal || newPos > s->maxVal )
  314. break;
  315. s->position = newPos;
  316. // Translate to window coords
  317. newPos = (Int)((newPos - s->minVal) * s->numTicks);
  318. child->winSetPosition( newPos , HORIZONTAL_SLIDER_THUMB_POSITION );
  319. break;
  320. } // end set slider
  321. // ------------------------------------------------------------------------
  322. case GSM_SET_MIN_MAX:
  323. {
  324. ICoord2D size;
  325. GameWindow *child = window->winGetChild();
  326. window->winGetSize( &size.x, &size.y );
  327. s->minVal = (Int)mData1;
  328. s->maxVal = (Int)mData2;
  329. s->numTicks = (Real)(size.x - HORIZONTAL_SLIDER_THUMB_WIDTH)/(Real)(s->maxVal - s->minVal);
  330. s->position = s->minVal;
  331. child->winSetPosition( 0, HORIZONTAL_SLIDER_THUMB_POSITION );
  332. break;
  333. } // end set min max
  334. // ------------------------------------------------------------------------
  335. case GWM_CREATE:
  336. break;
  337. // ------------------------------------------------------------------------
  338. case GWM_DESTROY:
  339. delete ( (SliderData *)window->winGetUserData() );
  340. break;
  341. // ------------------------------------------------------------------------
  342. case GWM_INPUT_FOCUS:
  343. {
  344. // If we're losing focus
  345. if( mData1 == FALSE )
  346. BitClear( instData->m_state, WIN_STATE_HILITED );
  347. else
  348. BitSet( instData->m_state, WIN_STATE_HILITED );
  349. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  350. GGM_FOCUS_CHANGE,
  351. mData1,
  352. window->winGetWindowId() );
  353. *(Bool*)mData2 = TRUE;
  354. break;
  355. } // end focus msg
  356. // ------------------------------------------------------------------------
  357. case GGM_RESIZED:
  358. {
  359. // Int width = (Int)mData1;
  360. Int height = (Int)mData2;
  361. GameWindow *thumb = window->winGetChild();
  362. if( thumb )
  363. thumb->winSetSize( GADGET_SIZE, height );
  364. break;
  365. } // end resized
  366. default:
  367. return MSG_IGNORED;
  368. } // end switch( msg )
  369. return MSG_HANDLED;
  370. } // end GadgetHorizontalSliderSystem