GadgetTabControl.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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: RadioButton.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: \projects\RTS\code\gameengine\Source\GameClient\GUI\Gadget\GadgetTabControl.cpp
  36. //
  37. // Created: Graham Smallwood, November 2001
  38. //
  39. // Desc: Tab Set 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. #include "GameClient/GadgetTabControl.h"
  50. // DEFINES ////////////////////////////////////////////////////////////////////
  51. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  52. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  53. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  54. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  55. ///////////////////////////////////////////////////////////////////////////////
  56. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  57. ///////////////////////////////////////////////////////////////////////////////
  58. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  59. // GadgetTabControlInput =====================================================
  60. /** Handle input for TabControl */
  61. //=============================================================================
  62. WindowMsgHandledType GadgetTabControlInput( GameWindow *tabControl, UnsignedInt msg,
  63. WindowMsgData mData1, WindowMsgData mData2 )
  64. {
  65. // WinInstanceData *instData = tabControl->winGetInstanceData();
  66. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  67. Int tabX, tabY;
  68. tabControl->winGetScreenPosition( &tabX, &tabY );
  69. Int mouseX = LOLONGTOSHORT(mData1) - tabX;//mData1 is packedMouseCoords in screen space
  70. Int mouseY = HILONGTOSHORT(mData1) - tabY;
  71. Int tabsLeft = tabData->tabsLeftLimit;
  72. Int tabsRight = tabData->tabsRightLimit;
  73. Int tabsBottom = tabData->tabsBottomLimit;
  74. Int tabsTop = tabData->tabsTopLimit;
  75. switch( msg )
  76. {
  77. case GWM_LEFT_DOWN:
  78. {
  79. if( (mouseX < tabsLeft)
  80. || (mouseX > tabsRight)
  81. || (mouseY < tabsTop)
  82. || (mouseY > tabsBottom)
  83. )
  84. {//I eat input on myself that isn't a tab (a button click would mean I don't see the input ever.)
  85. return MSG_HANDLED;
  86. }
  87. Int distanceIn;
  88. Int tabSize;
  89. if( (tabData->tabEdge == TP_RIGHT_SIDE) || (tabData->tabEdge == TP_LEFT_SIDE) )
  90. {//scan down to find which button
  91. distanceIn = mouseY - tabsTop;
  92. tabSize = tabData->tabHeight;
  93. }
  94. else
  95. {//scan right to find which button
  96. distanceIn = mouseX - tabsLeft;
  97. tabSize = tabData->tabWidth;
  98. }
  99. Int tabPressed = distanceIn / tabSize;
  100. if( ! tabData->subPaneDisabled[tabPressed] && (tabPressed != tabData->activeTab) )
  101. GadgetTabControlShowSubPane( tabControl, tabPressed );
  102. }
  103. default:
  104. {
  105. return MSG_IGNORED;
  106. }
  107. }
  108. return MSG_HANDLED;
  109. } // end GadgetTabControlInput
  110. // GadgetTabControlSystem ====================================================
  111. /** Handle system messages for TabControl */
  112. //=============================================================================
  113. WindowMsgHandledType GadgetTabControlSystem( GameWindow *tabControl, UnsignedInt msg,
  114. WindowMsgData mData1, WindowMsgData mData2 )
  115. {
  116. switch( msg )
  117. {
  118. // ------------------------------------------------------------------------
  119. case GWM_CREATE:
  120. break;
  121. // ------------------------------------------------------------------------
  122. case GWM_DESTROY:
  123. {
  124. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  125. // free tab control user data
  126. delete tabData;
  127. break;
  128. } // end destroy
  129. case GGM_RESIZED:
  130. {//On resize, we need to upkeep the pane sizes and tabs since they are bound to us
  131. GadgetTabControlResizeSubPanes( tabControl );
  132. GadgetTabControlComputeTabRegion( tabControl );
  133. break;
  134. }
  135. case GBM_SELECTED:
  136. {//Pass buttons messages up
  137. GameWindow *parent = tabControl->winGetParent();
  138. if( parent )
  139. return TheWindowManager->winSendSystemMsg( parent, msg, mData1, mData2 );
  140. }
  141. default:
  142. return MSG_IGNORED;
  143. } // end switch( msg )
  144. return MSG_HANDLED;
  145. } // end GadgetTabControlSystem
  146. void GadgetTabControlComputeTabRegion( GameWindow *tabControl )///< Recalc the tab positions based on userData
  147. {
  148. Int winWidth, winHeight;
  149. tabControl->winGetSize( &winWidth, &winHeight );
  150. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  151. Int horzOffset = 0, vertOffset = 0;
  152. if( (tabData->tabEdge == TP_TOP_SIDE) || (tabData->tabEdge == TP_BOTTOM_SIDE) )
  153. {
  154. if( tabData->tabOrientation == TP_CENTER )
  155. {
  156. horzOffset = winWidth - ( 2 * tabData->paneBorder ) - ( tabData->tabCount * tabData->tabWidth );
  157. horzOffset /= 2;
  158. }
  159. else if( tabData->tabOrientation == TP_BOTTOMRIGHT )
  160. {
  161. horzOffset = winWidth - ( 2 * tabData->paneBorder ) - ( tabData->tabCount * tabData->tabWidth );
  162. }
  163. else if( tabData->tabOrientation == TP_TOPLEFT )
  164. {
  165. horzOffset = 0;
  166. }
  167. }
  168. else
  169. {
  170. if( tabData->tabOrientation == TP_CENTER )
  171. {
  172. vertOffset = winHeight - ( 2 * tabData->paneBorder ) - ( tabData->tabCount * tabData->tabHeight );
  173. vertOffset /= 2;
  174. }
  175. else if( tabData->tabOrientation == TP_BOTTOMRIGHT )
  176. {
  177. vertOffset = winHeight - ( 2 * tabData->paneBorder ) - ( tabData->tabCount * tabData->tabHeight );
  178. }
  179. else if( tabData->tabOrientation == TP_TOPLEFT )
  180. {
  181. vertOffset = 0;
  182. }
  183. }
  184. if( tabData->tabEdge == TP_TOP_SIDE )
  185. {
  186. tabData->tabsTopLimit = tabData->paneBorder;
  187. tabData->tabsBottomLimit = tabData->paneBorder + tabData->tabHeight;
  188. tabData->tabsLeftLimit = tabData->paneBorder + horzOffset;
  189. tabData->tabsRightLimit = tabData->paneBorder + horzOffset + ( tabData->tabWidth * tabData->tabCount );
  190. }
  191. else if( tabData->tabEdge == TP_BOTTOM_SIDE )
  192. {
  193. tabData->tabsTopLimit = winHeight - tabData->paneBorder - tabData->tabHeight;
  194. tabData->tabsBottomLimit = winHeight - tabData->paneBorder;
  195. tabData->tabsLeftLimit = tabData->paneBorder + horzOffset;
  196. tabData->tabsRightLimit = tabData->paneBorder + horzOffset + ( tabData->tabWidth * tabData->tabCount );
  197. }
  198. else if( tabData->tabEdge == TP_RIGHT_SIDE )
  199. {
  200. tabData->tabsLeftLimit = winWidth - tabData->paneBorder - tabData->tabWidth;
  201. tabData->tabsRightLimit = winWidth - tabData->paneBorder;
  202. tabData->tabsTopLimit = tabData->paneBorder + vertOffset;
  203. tabData->tabsBottomLimit = tabData->paneBorder + vertOffset + ( tabData->tabHeight * tabData->tabCount );
  204. }
  205. else if( tabData->tabEdge == TP_LEFT_SIDE )
  206. {
  207. tabData->tabsLeftLimit = tabData->paneBorder;
  208. tabData->tabsRightLimit = tabData->paneBorder + tabData->tabWidth;
  209. tabData->tabsTopLimit = tabData->paneBorder + vertOffset;
  210. tabData->tabsBottomLimit = tabData->paneBorder + vertOffset + ( tabData->tabHeight * tabData->tabCount );
  211. }
  212. }
  213. void GadgetTabControlComputeSubPaneSize( GameWindow *tabControl, Int *width, Int *height, Int *x, Int *y )
  214. {
  215. Int winWidth, winHeight;
  216. tabControl->winGetSize( &winWidth, &winHeight );
  217. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  218. if( (tabData->tabEdge == TP_TOP_SIDE) || (tabData->tabEdge == TP_BOTTOM_SIDE) )
  219. *height = winHeight - (2 * tabData->paneBorder) - tabData->tabHeight;
  220. else
  221. *height = winHeight - (2 * tabData->paneBorder);
  222. if( (tabData->tabEdge == TP_LEFT_SIDE) || (tabData->tabEdge == TP_RIGHT_SIDE) )
  223. *width = winWidth - (2 * tabData->paneBorder) - tabData->tabWidth;
  224. else
  225. *width = winWidth - (2 * tabData->paneBorder);
  226. if( tabData->tabEdge == TP_LEFT_SIDE )
  227. *x = tabData->paneBorder + tabData->tabWidth;
  228. else
  229. *x = tabData->paneBorder;
  230. if( tabData->tabEdge == TP_TOP_SIDE )
  231. *y = tabData->paneBorder + tabData->tabHeight;
  232. else
  233. *y = tabData->paneBorder;
  234. }
  235. void GadgetTabControlShowSubPane( GameWindow *tabControl, Int whichPane)
  236. {
  237. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  238. for( Int paneIndex = 0; paneIndex < NUM_TAB_PANES; paneIndex++ )
  239. {
  240. if( tabData->subPanes[paneIndex] != NULL )
  241. tabData->subPanes[paneIndex]->winHide( true );
  242. }
  243. if( tabData->subPanes[whichPane] )
  244. tabData->activeTab = whichPane;
  245. else
  246. tabData->activeTab = 0;
  247. tabData->activeTab = min( tabData->activeTab, tabData->tabCount - 1 );
  248. tabData->subPanes[tabData->activeTab]->winHide( false );
  249. }
  250. void GadgetTabControlCreateSubPanes( GameWindow *tabControl )///< Create User Windows attached to userData as Panes
  251. {//These two funcs are called after all the Editor set data is updated
  252. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  253. Int width, height, x, y;
  254. GadgetTabControlComputeSubPaneSize(tabControl, &width, &height, &x, &y);
  255. for( Int paneIndex = 0; paneIndex < NUM_TAB_PANES; paneIndex++ )
  256. {
  257. if( (tabData->subPanes[paneIndex] == NULL) )//This one is blank
  258. {
  259. tabData->subPanes[paneIndex] = TheWindowManager->winCreate( tabControl,
  260. WIN_STATUS_NONE, x, y,
  261. width, height,
  262. PassSelectedButtonsToParentSystem,
  263. NULL);
  264. WinInstanceData *instData = tabData->subPanes[paneIndex]->winGetInstanceData();
  265. BitSet( instData->m_style, GWS_TAB_PANE );
  266. char buffer[20];
  267. sprintf( buffer, "Pane %d", paneIndex );
  268. instData->m_decoratedNameString = buffer;
  269. //set enabled status to that of Parent
  270. tabData->subPanes[paneIndex]->winEnable( BitTest(tabControl->winGetStatus(), WIN_STATUS_ENABLED) );
  271. }
  272. else//this one exists, tabCount will control keeping extra panes perma-hidden
  273. {
  274. tabData->subPanes[paneIndex]->winSetSize( width, height );
  275. tabData->subPanes[paneIndex]->winSetPosition( x, y );
  276. }
  277. }
  278. GadgetTabControlShowSubPane( tabControl, tabData->activeTab );
  279. }
  280. void GadgetTabControlResizeSubPanes( GameWindow *tabControl )
  281. {
  282. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  283. Int width, height, x, y;
  284. GadgetTabControlComputeSubPaneSize(tabControl, &width, &height, &x, &y);
  285. for( Int paneIndex = 0; paneIndex < NUM_TAB_PANES; paneIndex++ )
  286. {
  287. if( tabData->subPanes[paneIndex] )
  288. {
  289. tabData->subPanes[paneIndex]->winSetSize( width, height );
  290. tabData->subPanes[paneIndex]->winSetPosition( x, y );
  291. }
  292. }
  293. }
  294. ///<In game creation finished, hook up Children to SubPane array
  295. void GadgetTabControlFixupSubPaneList( GameWindow *tabControl )
  296. {
  297. Int childIndex =0;
  298. TabControlData *tabData = (TabControlData *)tabControl->winGetUserData();
  299. GameWindow *child = tabControl->winGetChild();
  300. if( child )
  301. {//need to write down children, and they are reversed from our array
  302. while( child->winGetNext() != NULL )
  303. {
  304. child = child->winGetNext();
  305. }
  306. while( child )
  307. {
  308. tabData->subPanes[childIndex] = child;
  309. childIndex++;
  310. child = child->winGetPrev();
  311. }
  312. }
  313. }