Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

478 lines
11 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "tabwindow.h"
  8. #include "ChoreoWidgetDrawHelper.h"
  9. #include "hlfaceposer.h"
  10. //-----------------------------------------------------------------------------
  11. // Purpose: Constructor
  12. // Input : *parent -
  13. // x -
  14. // y -
  15. // w -
  16. // h -
  17. // id -
  18. // style -
  19. //-----------------------------------------------------------------------------
  20. CTabWindow::CTabWindow( mxWindow *parent, int x, int y, int w, int h, int id /*= 0*/, int style /*=0*/ )
  21. : mxWindow( parent, x, y, w, h, "", style )
  22. {
  23. setId( id );
  24. m_nSelected = -1;
  25. m_nRowHeight = 20;
  26. m_nRowsRequired = 1;
  27. m_nTabWidth = 80;
  28. m_nPixelDelta = 3;
  29. m_bInverted = false;
  30. m_bRightJustify = false;
  31. SetColor( COLOR_BG, RGBToColor( GetSysColor( COLOR_BTNFACE ) ) );
  32. SetColor( COLOR_FG, RGBToColor( GetSysColor( COLOR_INACTIVECAPTION ) ) );
  33. SetColor( COLOR_FG_SELECTED, RGBToColor( GetSysColor( COLOR_ACTIVECAPTION ) ) );
  34. SetColor( COLOR_HILITE, RGBToColor( GetSysColor( COLOR_3DSHADOW ) ) );
  35. SetColor( COLOR_HILITE_SELECTED, RGBToColor( GetSysColor( COLOR_3DHILIGHT ) ) );
  36. SetColor( COLOR_TEXT, RGBToColor( GetSysColor( COLOR_CAPTIONTEXT ) ) );
  37. SetColor( COLOR_TEXT_SELECTED, RGBToColor( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) );
  38. FacePoser_AddWindowStyle( this, WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
  39. }
  40. //-----------------------------------------------------------------------------
  41. // Purpose:
  42. // Output : CTabWindow::~CTabWindow
  43. //-----------------------------------------------------------------------------
  44. CTabWindow::~CTabWindow ( void )
  45. {
  46. removeAll();
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose:
  50. // Input : index -
  51. // clr -
  52. //-----------------------------------------------------------------------------
  53. void CTabWindow::SetColor( int index, const Color& clr )
  54. {
  55. if ( index < 0 || index >= NUM_COLORS )
  56. return;
  57. m_Colors[ index ] = clr;
  58. }
  59. void CTabWindow::SetInverted( bool invert )
  60. {
  61. m_bInverted = invert;
  62. RecomputeLayout( w2() );
  63. }
  64. void CTabWindow::SetRightJustify( bool rightjustify )
  65. {
  66. m_bRightJustify = true;
  67. RecomputeLayout( w2() );
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose: Tabs are sized to string content
  71. // Input : rcClient -
  72. // tabRect -
  73. // tabNum -
  74. //-----------------------------------------------------------------------------
  75. void CTabWindow::GetTabRect( const RECT& rcClient, RECT& tabRect, int tabNum )
  76. {
  77. tabRect = m_Items[ tabNum ].rect;
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Purpose:
  81. // Input : drawHelper -
  82. // rcClient -
  83. // tabnum -
  84. // selected -
  85. //-----------------------------------------------------------------------------
  86. void CTabWindow::DrawTab( CChoreoWidgetDrawHelper& drawHelper, RECT& rcClient, int tabnum, bool selected )
  87. {
  88. RECT rcTab;
  89. if ( tabnum < 0 || tabnum >= m_Items.Count() )
  90. return;
  91. GetTabRect( rcClient, rcTab, tabnum );
  92. Color fgcolor = m_Colors[ selected ? COLOR_FG_SELECTED : COLOR_FG ];
  93. Color hilightcolor = m_Colors[ selected ? COLOR_HILITE_SELECTED : COLOR_HILITE ];
  94. Color text = m_Colors[ selected ? COLOR_TEXT_SELECTED : COLOR_TEXT ];
  95. // Create a trapezoid/paralleogram
  96. POINT region[4];
  97. int cPoints = 4;
  98. OffsetRect( &rcTab, 0, m_bInverted ? 1 : -1 );
  99. if ( m_bInverted )
  100. {
  101. region[ 0 ].x = rcTab.left - m_nPixelDelta;
  102. region[ 0 ].y = rcTab.top;
  103. region[ 1 ].x = rcTab.right + m_nPixelDelta;
  104. region[ 1 ].y = rcTab.top;
  105. region[ 2 ].x = rcTab.right - m_nPixelDelta;
  106. region[ 2 ].y = rcTab.bottom;
  107. region[ 3 ].x = rcTab.left + m_nPixelDelta;
  108. region[ 3 ].y = rcTab.bottom;
  109. }
  110. else
  111. {
  112. region[ 0 ].x = rcTab.left + m_nPixelDelta;
  113. region[ 0 ].y = rcTab.top;
  114. region[ 1 ].x = rcTab.right - m_nPixelDelta;
  115. region[ 1 ].y = rcTab.top;
  116. region[ 2 ].x = rcTab.right + m_nPixelDelta;
  117. region[ 2 ].y = rcTab.bottom;
  118. region[ 3 ].x = rcTab.left - m_nPixelDelta;
  119. region[ 3 ].y = rcTab.bottom;
  120. }
  121. HDC dc = drawHelper.GrabDC();
  122. HRGN rgn = CreatePolygonRgn( region, cPoints, ALTERNATE );
  123. int oldPF = SetPolyFillMode( dc, ALTERNATE );
  124. HBRUSH brBg = CreateSolidBrush( ColorToRGB( fgcolor ) );
  125. HBRUSH brBorder = CreateSolidBrush( ColorToRGB( hilightcolor ) );
  126. FillRgn( dc, rgn, brBg );
  127. FrameRgn( dc, rgn, brBorder, 1, 1 );
  128. SetPolyFillMode( dc, oldPF );
  129. DeleteObject( rgn );
  130. DeleteObject( brBg );
  131. DeleteObject( brBorder );
  132. //DeleteObject( brInset );
  133. // Position label
  134. InflateRect( &rcTab, -5, 0 );
  135. OffsetRect( &rcTab, 2, 0 );
  136. // Draw label
  137. drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, text, rcTab, "%s%s", getPrefix( tabnum ), getLabel( tabnum ) );
  138. }
  139. //-----------------------------------------------------------------------------
  140. // Purpose:
  141. //-----------------------------------------------------------------------------
  142. void CTabWindow::redraw( void )
  143. {
  144. CChoreoWidgetDrawHelper drawHelper( this, m_Colors[ COLOR_BG ] );
  145. int liney = m_bInverted ? 1 : h2() - 2;
  146. drawHelper.DrawColoredLine( m_Colors[ COLOR_HILITE ], PS_SOLID, 1, 0, liney, w(), liney );
  147. RECT rc;
  148. drawHelper.GetClientRect( rc );
  149. // Draw non-selected first
  150. for ( int i = 0 ; i < m_Items.Count(); i++ )
  151. {
  152. if ( i == m_nSelected )
  153. continue;
  154. DrawTab( drawHelper, rc, i );
  155. }
  156. // Draw selected last, so that it appears to pop to top of z order
  157. if ( m_nSelected >= 0 && m_nSelected < m_Items.Count() )
  158. {
  159. DrawTab( drawHelper, rc, m_nSelected, true );
  160. }
  161. }
  162. //-----------------------------------------------------------------------------
  163. // Purpose:
  164. // Input : mx -
  165. // my -
  166. // Output : int
  167. //-----------------------------------------------------------------------------
  168. int CTabWindow::GetItemUnderMouse( int mx, int my )
  169. {
  170. RECT rcClient;
  171. GetClientRect( (HWND)getHandle(), &rcClient );
  172. for ( int i = 0; i < m_Items.Count() ; i++ )
  173. {
  174. RECT rcTab;
  175. GetTabRect( rcClient, rcTab, i );
  176. if ( mx < rcTab.left ||
  177. mx > rcTab.right ||
  178. my < rcTab.top ||
  179. my > rcTab.bottom )
  180. {
  181. continue;
  182. }
  183. return i;
  184. }
  185. return -1;
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Purpose:
  189. // Input : *event -
  190. // Output : int CTabWindow::handleEvent
  191. //-----------------------------------------------------------------------------
  192. int CTabWindow::handleEvent (mxEvent *event)
  193. {
  194. int iret = 0;
  195. switch ( event->event )
  196. {
  197. case mxEvent::MouseDown:
  198. {
  199. int item = GetItemUnderMouse( (short)event->x, (short)event->y );
  200. if ( item != -1 )
  201. {
  202. m_nSelected = item;
  203. redraw();
  204. // Send CBN_SELCHANGE WM_COMMAND message to parent
  205. HWND parent = (HWND)( getParent() ? getParent()->getHandle() : NULL );
  206. if ( parent )
  207. {
  208. LPARAM lp;
  209. WPARAM wp;
  210. wp = MAKEWPARAM( getId(), CBN_SELCHANGE );
  211. lp = (long)getHandle();
  212. PostMessage( parent, WM_COMMAND, wp, lp );
  213. }
  214. iret = 1;
  215. }
  216. if ( event->buttons & mxEvent::MouseRightButton )
  217. {
  218. ShowRightClickMenu( (short)event->x, (short)event->y );
  219. iret = 1;
  220. }
  221. }
  222. break;
  223. case mxEvent::Size:
  224. {
  225. RecomputeLayout( w2() );
  226. }
  227. break;
  228. }
  229. return iret;
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose: Add string to table
  233. // Input : *item -
  234. //-----------------------------------------------------------------------------
  235. void CTabWindow::add( const char *item )
  236. {
  237. m_Items.AddToTail();
  238. CETItem *p = &m_Items[ m_Items.Count() - 1 ];
  239. Assert( p );
  240. Q_memset( &p->rect, 0, sizeof( p->rect) );
  241. strcpy( p->m_szString, item );
  242. p->m_szPrefix[ 0 ] = 0;
  243. m_nSelected = min( m_nSelected, m_Items.Count() - 1 );
  244. m_nSelected = max( m_nSelected, 0 );
  245. RecomputeLayout( w2() );
  246. redraw();
  247. }
  248. void CTabWindow::setPrefix( int item, char const *prefix )
  249. {
  250. if ( item < 0 || item >= m_Items.Count() )
  251. return;
  252. Q_strncpy( m_Items[ item ].m_szPrefix, prefix, sizeof( m_Items[ item ].m_szPrefix ) );
  253. // RecomputeLayout( w2() );
  254. }
  255. //-----------------------------------------------------------------------------
  256. // Purpose: Change selected item
  257. // Input : index -
  258. //-----------------------------------------------------------------------------
  259. void CTabWindow::select( int index )
  260. {
  261. if ( index < 0 || index >= m_Items.Count() )
  262. return;
  263. m_nSelected = index;
  264. redraw();
  265. }
  266. //-----------------------------------------------------------------------------
  267. // Purpose: Remove a string
  268. // Input : index -
  269. //-----------------------------------------------------------------------------
  270. void CTabWindow::remove( int index )
  271. {
  272. if ( index < 0 || index >= m_Items.Count() )
  273. return;
  274. m_Items.Remove( index );
  275. m_nSelected = min( m_nSelected, m_Items.Count() - 1 );
  276. m_nSelected = max( m_nSelected, 0 );
  277. RecomputeLayout( w2() );
  278. redraw();
  279. }
  280. //-----------------------------------------------------------------------------
  281. // Purpose: Clear out everything
  282. //-----------------------------------------------------------------------------
  283. void CTabWindow::removeAll()
  284. {
  285. m_nSelected = -1;
  286. m_Items.RemoveAll();
  287. RecomputeLayout( w2() );
  288. redraw();
  289. }
  290. //-----------------------------------------------------------------------------
  291. // Purpose:
  292. // Output : int
  293. //-----------------------------------------------------------------------------
  294. int CTabWindow::getItemCount () const
  295. {
  296. return m_Items.Count();
  297. }
  298. //-----------------------------------------------------------------------------
  299. // Purpose:
  300. // Output : int
  301. //-----------------------------------------------------------------------------
  302. int CTabWindow::getSelectedIndex () const
  303. {
  304. // Convert based on override index
  305. return m_nSelected;
  306. }
  307. char const *CTabWindow::getLabel( int item )
  308. {
  309. if ( item < 0 || item >= m_Items.Count() )
  310. return "";
  311. return m_Items[ item ].m_szString;
  312. }
  313. char const *CTabWindow::getPrefix( int item )
  314. {
  315. if ( item < 0 || item >= m_Items.Count() )
  316. return "";
  317. return m_Items[ item ].m_szPrefix;
  318. }
  319. void CTabWindow::SetRowHeight( int rowheight )
  320. {
  321. m_nRowHeight = rowheight;
  322. RecomputeLayout( w2() );
  323. redraw();
  324. }
  325. int CTabWindow::GetBestHeight( int width )
  326. {
  327. return RecomputeLayout( width, false ) * m_nRowHeight;
  328. }
  329. int CTabWindow::RecomputeLayout( int windowWidth, bool dolayout /*=true*/ )
  330. {
  331. // Draw non-selected first
  332. int curedge = m_nPixelDelta + 1;
  333. int curtop = 0;
  334. if ( m_bRightJustify )
  335. {
  336. curedge = windowWidth - ( m_nPixelDelta + 1 ) - 5;
  337. }
  338. int startedge = curedge;
  339. int currentrow = 0;
  340. for ( int i = 0 ; i < m_Items.Count(); i++ )
  341. {
  342. CETItem *p = &m_Items[ i ];
  343. RECT rc;
  344. int textwidth = CChoreoWidgetDrawHelper::CalcTextWidth( "Arial", 9, FW_NORMAL, "%s%s", p->m_szPrefix, p->m_szString ) + 15;
  345. if ( !m_bRightJustify )
  346. {
  347. // Starting column
  348. if ( curedge + textwidth > windowWidth )
  349. {
  350. curedge = startedge;
  351. curtop += m_nRowHeight;
  352. currentrow++;
  353. }
  354. rc.left = curedge;
  355. rc.right = curedge + textwidth;
  356. rc.top = curtop + 2;
  357. rc.bottom = curtop + m_nRowHeight;
  358. curedge += textwidth;
  359. p->rect = rc;
  360. }
  361. else
  362. {
  363. // Starting column
  364. if ( curedge - textwidth < 0 )
  365. {
  366. curedge = startedge;
  367. curtop += m_nRowHeight;
  368. currentrow++;
  369. }
  370. rc.left = curedge - textwidth;
  371. rc.right = curedge;
  372. rc.top = curtop;
  373. rc.bottom = curtop + m_nRowHeight - 2;
  374. curedge -= textwidth;
  375. }
  376. if ( dolayout )
  377. {
  378. p->rect = rc;
  379. }
  380. }
  381. if ( dolayout )
  382. {
  383. m_nRowsRequired = currentrow + 1;
  384. }
  385. return currentrow + 1;
  386. }