GadgetVerticalSlider.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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: VerticalSlider.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: VerticalSlider.cpp
  36. //
  37. // Created: Colin Day, June 2001
  38. //
  39. // Desc: Vertical slider gui control
  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. // DEFINES ////////////////////////////////////////////////////////////////////
  50. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  51. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  52. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  53. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  54. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  55. ///////////////////////////////////////////////////////////////////////////////
  56. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  57. ///////////////////////////////////////////////////////////////////////////////
  58. #ifdef _INTERNAL
  59. // for occasional debugging...
  60. //#pragma optimize("", off)
  61. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  62. #endif
  63. // GadgetVerticlaSliderInput ==================================================
  64. /** Handle input for vertical slider */
  65. //=============================================================================
  66. WindowMsgHandledType GadgetVerticalSliderInput( GameWindow *window, UnsignedInt msg,
  67. WindowMsgData mData1, WindowMsgData mData2 )
  68. {
  69. SliderData *s = (SliderData *)window->winGetUserData();
  70. WinInstanceData *instData = window->winGetInstanceData();
  71. switch( msg )
  72. {
  73. // ------------------------------------------------------------------------
  74. case GWM_MOUSE_ENTERING:
  75. if( BitTest( instData->getStyle(), GWS_MOUSE_TRACK ) )
  76. {
  77. BitSet( instData->m_state, WIN_STATE_HILITED );
  78. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  79. GBM_MOUSE_ENTERING,
  80. (WindowMsgData)window,
  81. 0 );
  82. //TheWindowManager->winSetFocus( window );
  83. }
  84. break;
  85. // ------------------------------------------------------------------------
  86. case GWM_MOUSE_LEAVING:
  87. if( BitTest( instData->getStyle(), GWS_MOUSE_TRACK ) )
  88. {
  89. BitClear( instData->m_state, WIN_STATE_HILITED );
  90. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  91. GBM_MOUSE_LEAVING,
  92. (WindowMsgData)window,
  93. 0 );
  94. }
  95. break;
  96. // ------------------------------------------------------------------------
  97. case GWM_LEFT_DRAG:
  98. if( BitTest( instData->getStyle(), GWS_MOUSE_TRACK ) )
  99. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  100. GGM_LEFT_DRAG,
  101. (WindowMsgData)window,
  102. mData1 );
  103. break;
  104. // ------------------------------------------------------------------------
  105. case GWM_LEFT_DOWN:
  106. break;
  107. // ------------------------------------------------------------------------
  108. case GWM_LEFT_UP:
  109. {
  110. Int x, y;
  111. // Int mousex = mData1 & 0xFFFF;
  112. Int mousey = mData1 >> 16;
  113. ICoord2D size, childSize, childCenter;
  114. GameWindow *child = window->winGetChild();
  115. Int pageClickSize, clickPos;
  116. window->winGetScreenPosition( &x, &y );
  117. window->winGetSize( &size.x, &size.y );
  118. child->winGetSize( &childSize.x, &childSize.y );
  119. child->winGetPosition( &childCenter.x, &childCenter.y );
  120. childCenter.x += childSize.x / 2;
  121. childCenter.y += childSize.y / 2;
  122. //
  123. // when you click on the slider, but not the button, we will jump
  124. // the slider position up/down by this much
  125. //
  126. pageClickSize = size.y / 5;
  127. clickPos = mousey - y;
  128. if( clickPos >= childCenter.y )
  129. {
  130. clickPos = childCenter.y + pageClickSize;
  131. if( clickPos > mousey - y )
  132. clickPos = mousey - y;
  133. } // end if
  134. else
  135. {
  136. clickPos = childCenter.y - pageClickSize;
  137. if( clickPos < mousey - y )
  138. clickPos = mousey - y;
  139. } // end else
  140. // keep pos valid on window
  141. if( clickPos > y + size.y - childSize.y / 2 )
  142. clickPos = y + size.y - childSize.y / 2;
  143. if( clickPos < childSize.y / 2 )
  144. clickPos = childSize.y / 2;
  145. child->winSetPosition( 0, clickPos - childSize.y / 2 );
  146. TheWindowManager->winSendSystemMsg( window, GGM_LEFT_DRAG, 0, mData1 );
  147. break;
  148. }
  149. // ------------------------------------------------------------------------
  150. case GWM_CHAR:
  151. {
  152. switch (mData1)
  153. {
  154. // --------------------------------------------------------------------
  155. case KEY_UP:
  156. if( BitTest( mData2, KEY_STATE_DOWN ) )
  157. {
  158. if( s->position < s->maxVal - 1)
  159. {
  160. GameWindow *child = window->winGetChild();
  161. s->position += 2;
  162. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  163. GSM_SLIDER_TRACK,
  164. (WindowMsgData)window,
  165. s->position );
  166. // Translate to window coords
  167. child->winSetPosition( 0, (Int)((s->maxVal - s->position) * s->numTicks) );
  168. }
  169. }
  170. break;
  171. // --------------------------------------------------------------------
  172. case KEY_DOWN:
  173. if( BitTest( mData2, KEY_STATE_DOWN ) )
  174. {
  175. if( s->position > s->minVal + 1 )
  176. {
  177. GameWindow *child = window->winGetChild();
  178. s->position -= 2;
  179. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  180. GSM_SLIDER_TRACK,
  181. (WindowMsgData)window,
  182. s->position );
  183. // Translate to window coords
  184. child->winSetPosition( 0, (Int)((s->maxVal - s->position) * s->numTicks) );
  185. }
  186. }
  187. break;
  188. // --------------------------------------------------------------------
  189. case KEY_RIGHT:
  190. case KEY_TAB:
  191. if( BitTest( mData2, KEY_STATE_DOWN ) )
  192. window->winNextTab();
  193. break;
  194. // --------------------------------------------------------------------
  195. case KEY_LEFT:
  196. if( BitTest( mData2, KEY_STATE_DOWN ) )
  197. window->winPrevTab();
  198. break;
  199. default:
  200. return MSG_IGNORED;
  201. } // end switch( mData1 )
  202. break;
  203. } // end char
  204. default:
  205. return MSG_IGNORED;
  206. } // end switch( msg )
  207. return MSG_HANDLED;
  208. } // end GadgetVerticalSliderInput
  209. // GadgetVerticalSliderSystem =================================================
  210. /** Handle system messages for vertical slider */
  211. //=============================================================================
  212. WindowMsgHandledType GadgetVerticalSliderSystem( GameWindow *window, UnsignedInt msg,
  213. WindowMsgData mData1, WindowMsgData mData2 )
  214. {
  215. SliderData *s = (SliderData *)window->winGetUserData();
  216. WinInstanceData *instData = window->winGetInstanceData();
  217. switch( msg )
  218. {
  219. // ------------------------------------------------------------------------
  220. case GBM_SELECTED:
  221. {
  222. // tell owner I've finished moving
  223. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  224. GSM_SLIDER_DONE,
  225. (WindowMsgData)window,
  226. s->position );
  227. break;
  228. }
  229. // ------------------------------------------------------------------------
  230. case GGM_LEFT_DRAG:
  231. {
  232. // Int mousex = mData2 & 0xFFFF;
  233. Int mousey = mData2 >> 16;
  234. Int x, y, delta;
  235. ICoord2D size, childSize, childCenter;
  236. GameWindow *child = window->winGetChild();
  237. window->winGetScreenPosition( &x, &y );
  238. window->winGetSize( &size.x, &size.y );
  239. child->winGetSize( &childSize.x, &childSize.y );
  240. child->winGetScreenPosition( &childCenter.x, &childCenter.y );
  241. childCenter.x += childSize.x / 2;
  242. childCenter.y += childSize.y / 2;
  243. //
  244. // ignore drag attempts when the mouse is below or above the slider totally
  245. // and put the dragging thumb back at the slider pos
  246. //
  247. if( mousey > y + size.y )
  248. {
  249. //s->position = s->minVal;
  250. TheWindowManager->winSendSystemMsg( window, GSM_SET_SLIDER,
  251. s->minVal, 0 );
  252. // tell owner i moved
  253. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  254. GSM_SLIDER_TRACK,
  255. (WindowMsgData)window,
  256. s->position );
  257. break;
  258. } // end if
  259. else if( mousey < y )
  260. {
  261. //s->position = s->maxVal;
  262. TheWindowManager->winSendSystemMsg( window, GSM_SET_SLIDER,
  263. s->maxVal, 0 );
  264. // tell owner i moved
  265. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  266. GSM_SLIDER_TRACK,
  267. (WindowMsgData)window,
  268. s->position );
  269. break;
  270. } // end else if
  271. if( childCenter.y <= y + childSize.y / 2 )
  272. {
  273. child->winSetPosition( 0, 0 );
  274. s->position = s->maxVal;
  275. }
  276. else if( childCenter.y >= y + size.y - childSize.y / 2 )
  277. {
  278. child->winSetPosition( 0, size.y - childSize.y );
  279. s->position = s->minVal;
  280. }
  281. else
  282. {
  283. delta = childCenter.y - y - childSize.y/2;
  284. // Calc slider position
  285. s->position = (Int)(delta / s->numTicks) ;
  286. /*
  287. s->position += s->minVal;
  288. */
  289. if( s->position > s->maxVal )
  290. s->position = s->maxVal;
  291. // Invert slider position so that maxval is at the top
  292. s->position = s->maxVal - s->position;
  293. }
  294. // tell owner i moved
  295. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  296. GSM_SLIDER_TRACK,
  297. (WindowMsgData)window,
  298. s->position );
  299. break;
  300. }
  301. // ------------------------------------------------------------------------
  302. case GSM_SET_SLIDER:
  303. {
  304. Int newPos = (Int)mData1;
  305. GameWindow *child = window->winGetChild();
  306. if (newPos < s->minVal || newPos > s->maxVal)
  307. break;
  308. s->position = newPos;
  309. // Translate to window coords
  310. newPos = (Int)((s->maxVal - newPos) * s->numTicks);
  311. child->winSetPosition( 0, newPos );
  312. break;
  313. }
  314. // ------------------------------------------------------------------------
  315. case GSM_SET_MIN_MAX:
  316. {
  317. Int newPos;
  318. ICoord2D size;
  319. GameWindow *child = window->winGetChild();
  320. window->winGetSize( &size.x, &size.y );
  321. s->minVal = (Int)mData1;
  322. s->maxVal = (Int)mData2;
  323. s->numTicks = (Real)( size.y-GADGET_SIZE)/(Real)(s->maxVal - s->minVal);
  324. s->position = s->minVal;
  325. // Translate to window coords
  326. newPos = (Int)((s->maxVal - s->minVal) * s->numTicks);
  327. child->winSetPosition( 0, newPos );
  328. break;
  329. }
  330. // ------------------------------------------------------------------------
  331. case GWM_CREATE:
  332. break;
  333. // ------------------------------------------------------------------------
  334. case GWM_DESTROY:
  335. delete( (SliderData *)window->winGetUserData() );
  336. break;
  337. // ------------------------------------------------------------------------
  338. case GWM_INPUT_FOCUS:
  339. // If we're losing focus
  340. if( mData1 == FALSE )
  341. {
  342. BitClear( instData->m_state, WIN_STATE_HILITED );
  343. } else {
  344. BitSet( instData->m_state, WIN_STATE_HILITED );
  345. }
  346. TheWindowManager->winSendSystemMsg( window->winGetOwner(),
  347. GGM_FOCUS_CHANGE,
  348. mData1,
  349. window->winGetWindowId() );
  350. *(Bool*)mData2 = TRUE;
  351. break;
  352. // ------------------------------------------------------------------------
  353. case GGM_RESIZED:
  354. {
  355. Int width = (Int)mData1;
  356. // Int height = (Int)mData2;
  357. GameWindow *thumb = window->winGetChild();
  358. if( thumb )
  359. thumb->winSetSize( width, GADGET_SIZE );
  360. break;
  361. } // end resized
  362. default:
  363. return MSG_IGNORED;
  364. } // end switch( msg )
  365. return MSG_HANDLED;
  366. } // end GadgetVerticalSliderSystem