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.

769 lines
24 KiB

  1. //======= Copyright � 1996-2008, Valve Corporation, All rights reserved. ======
  2. //
  3. // Purpose: A 2D Slider
  4. //
  5. //=============================================================================
  6. // Valve includes
  7. #include <KeyValues.h>
  8. #include <vgui/MouseCode.h>
  9. #include <vgui/IBorder.h>
  10. #include <vgui/IInput.h>
  11. #include <vgui/ISystem.h>
  12. #include <vgui/IScheme.h>
  13. #include <vgui/ISurface.h>
  14. #include <vgui/ILocalize.h>
  15. #include <vgui_controls/Controls.h>
  16. #include <vgui_controls/TextImage.h>
  17. #include <dme_controls/2DSlider.h>
  18. // memdbgon must be the last include file in a .cpp file!!!
  19. #include <tier0/memdbgon.h>
  20. using namespace vgui;
  21. //-----------------------------------------------------------------------------
  22. // Statics
  23. //-----------------------------------------------------------------------------
  24. Color C2DSlider::s_TextColor( 208, 143, 40, 192 );
  25. Color C2DSlider::s_NobColor( 0, 63, 98, 255 );
  26. Color C2DSlider::s_TickColor( 0, 79, 182, 255 );
  27. Color C2DSlider::s_TickFillXColor( 0, 63, 0, 255 );
  28. Color C2DSlider::s_TickFillYColor( 0, 0, 98, 255 );
  29. Color C2DSlider::s_TickFillColor( 0, 63, 98, 255 );
  30. Color C2DSlider::s_TrackColor( 31, 31, 31, 255 );
  31. //-----------------------------------------------------------------------------
  32. // Purpose: Create a slider bar with ticks underneath it
  33. //-----------------------------------------------------------------------------
  34. C2DSlider::C2DSlider( Panel *pParent, const char *pName )
  35. : BaseClass( pParent, pName )
  36. {
  37. m_bDrawLabel = true;
  38. m_bIsDragOnRepositionNob = true;
  39. m_bDragging = false;
  40. m_fValue[ kXAxis ] = 0.0f;
  41. m_fValue[ kYAxis ] = 0.0f;
  42. m_fRange[ kXAxis ][ 0 ] = 0.0f;
  43. m_fRange[ kXAxis ][ 1 ] = 1.0f;
  44. m_fRange[ kYAxis ][ 0 ] = 1.0f;
  45. m_fRange[ kYAxis ][ 1 ] = 0.0f;
  46. m_pNobBorder = NULL;
  47. m_pInsetBorder = NULL;
  48. SetNobSize( 7, 7 );
  49. RecomputeNobPosFromValue();
  50. AddActionSignalTarget( this );
  51. SetBlockDragChaining( true );
  52. m_pLabel = new TextImage( pName );
  53. }
  54. //-----------------------------------------------------------------------------
  55. //
  56. //-----------------------------------------------------------------------------
  57. C2DSlider::~C2DSlider()
  58. {
  59. delete m_pLabel;
  60. }
  61. //-----------------------------------------------------------------------------
  62. // Purpose: Set the value of the slider
  63. //-----------------------------------------------------------------------------
  64. void C2DSlider::SetValueX( float fValueX, bool bTriggerChangeMessage /* = true */ )
  65. {
  66. SetValue( fValueX, GetValueY(), bTriggerChangeMessage );
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose: Set the value of the slider
  70. //-----------------------------------------------------------------------------
  71. float C2DSlider::GetValueX() const
  72. {
  73. return m_fValue[ kXAxis ];
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Purpose: Set the value of the slider
  77. //-----------------------------------------------------------------------------
  78. void C2DSlider::SetValueY( float fValueY, bool bTriggerChangeMessage /* = true */ )
  79. {
  80. SetValue( GetValueX(), fValueY, bTriggerChangeMessage );
  81. }
  82. //-----------------------------------------------------------------------------
  83. // Purpose: Set the value of the slider to one of the ticks.
  84. //-----------------------------------------------------------------------------
  85. float C2DSlider::GetValueY() const
  86. {
  87. return m_fValue[ kYAxis ];
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose: Set the value of the slider to one of the ticks.
  91. //-----------------------------------------------------------------------------
  92. void C2DSlider::SetValue( float fValueX, float fValueY, bool bTriggerChangeMessage )
  93. {
  94. fValueX = RemapValClamped( fValueX, m_fRange[ kXAxis ][ 0 ], m_fRange[ kXAxis ][ 1 ], m_fRange[ kXAxis ][ 0 ], m_fRange[ kXAxis ][ 1 ] );
  95. fValueY = RemapValClamped( fValueY, m_fRange[ kYAxis ][ 0 ], m_fRange[ kYAxis ][ 1 ], m_fRange[ kYAxis ][ 0 ], m_fRange[ kYAxis ][ 1 ] );
  96. if ( fValueX != m_fValue[ kXAxis ] || fValueY != m_fValue[ kYAxis ] )
  97. {
  98. m_fValue[ kXAxis ] = fValueX;
  99. m_fValue[ kYAxis ] = fValueY;
  100. RecomputeNobPosFromValue();
  101. if ( bTriggerChangeMessage )
  102. {
  103. SendSliderMovedMessage();
  104. }
  105. }
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Purpose: Return the value of the slider
  109. //-----------------------------------------------------------------------------
  110. void C2DSlider::GetValue( float &fValueX, float &fValueY ) const
  111. {
  112. fValueX = GetValueX();
  113. fValueY = GetValueY();
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose: Set the range of the slider.
  117. //-----------------------------------------------------------------------------
  118. void C2DSlider::SetRange( float fMinX, float fMaxX, float fMinY, float fMaxY, bool bTriggerChangeMessage /* = true */ )
  119. {
  120. m_fRange[ kXAxis ][ 0 ] = fMinX;
  121. m_fRange[ kXAxis ][ 1 ] = fMaxX;
  122. m_fRange[ kYAxis ][ 0 ] = fMinY;
  123. m_fRange[ kYAxis ][ 1 ] = fMaxY;
  124. SetValue( m_fValue[ kXAxis ], m_fValue[ kYAxis ], bTriggerChangeMessage );
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Purpose: Get the max and min values of the slider
  128. //-----------------------------------------------------------------------------
  129. void C2DSlider::GetRange( float &fMinX, float &fMaxX, float &fMinY, float &fMaxY ) const
  130. {
  131. fMinX = m_fRange[ kXAxis ][ 0 ];
  132. fMaxX = m_fRange[ kXAxis ][ 1 ];
  133. fMinY = m_fRange[ kYAxis ][ 0 ];
  134. fMaxY = m_fRange[ kYAxis ][ 1 ];
  135. }
  136. //-----------------------------------------------------------------------------
  137. //
  138. //-----------------------------------------------------------------------------
  139. void C2DSlider::SetLabelText( const char *pText )
  140. {
  141. m_pLabel->SetText( pText );
  142. }
  143. //-----------------------------------------------------------------------------
  144. //
  145. //-----------------------------------------------------------------------------
  146. void C2DSlider::SetLabelText( const wchar_t *pText )
  147. {
  148. m_pLabel->SetText( pText );
  149. }
  150. //-----------------------------------------------------------------------------
  151. //
  152. //-----------------------------------------------------------------------------
  153. void C2DSlider::GetLabelText( wchar_t *pBuffer, int nBufferLen ) const
  154. {
  155. m_pLabel->GetText( pBuffer, nBufferLen );
  156. }
  157. //-----------------------------------------------------------------------------
  158. //
  159. //-----------------------------------------------------------------------------
  160. void C2DSlider::GetLabelUnlocalizedText( char *pBuffer, int nBufferLen ) const
  161. {
  162. m_pLabel->GetUnlocalizedText( pBuffer, nBufferLen );
  163. }
  164. //-----------------------------------------------------------------------------
  165. //
  166. //-----------------------------------------------------------------------------
  167. void C2DSlider::SetDrawLabel( bool bState )
  168. {
  169. m_bDrawLabel = bState;
  170. }
  171. //-----------------------------------------------------------------------------
  172. //
  173. //-----------------------------------------------------------------------------
  174. bool C2DSlider::IsDrawingLabel() const
  175. {
  176. return m_bDrawLabel;
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Purpose: Get the nob's position ( the ends of each side of the nob )
  180. //-----------------------------------------------------------------------------
  181. void C2DSlider::GetNobPos( int &nX, int &nY )
  182. {
  183. nX = m_nNobPos[ kXAxis ];
  184. nY = m_nNobPos[ kYAxis ];
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Purpose: Respond when the cursor is moved in our window if we are clicking
  188. // and dragging.
  189. //-----------------------------------------------------------------------------
  190. void C2DSlider::OnCursorMoved( int nMouseX, int nMouseY )
  191. {
  192. if ( !m_bDragging )
  193. return;
  194. input()->GetCursorPosition( nMouseX, nMouseY );
  195. ScreenToLocal( nMouseX, nMouseY );
  196. int nTrackX, nTrackY, nTrackWide, nTrackTall;
  197. GetTrackRect( nTrackX, nTrackY, nTrackWide, nTrackTall );
  198. m_nNobPos[ kXAxis ] = clamp( m_nNobDragStartPos[ kXAxis ] + nMouseX - m_nDragStartPos[ kXAxis ], nTrackX, nTrackX + nTrackWide - 1 );
  199. m_nNobPos[ kYAxis ] = clamp( m_nNobDragStartPos[ kYAxis ] + nMouseY - m_nDragStartPos[ kYAxis ], nTrackY, nTrackY + nTrackTall - 1 );
  200. RecomputeValueFromNobPos( false );
  201. Repaint();
  202. SendSliderMovedMessage();
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose: Respond to mouse presses. Trigger Record staring positon.
  206. //-----------------------------------------------------------------------------
  207. void C2DSlider::OnMousePressed( MouseCode /* mouseCode */ )
  208. {
  209. if ( !IsEnabled() )
  210. return;
  211. /*
  212. TODO: Do this in Maya
  213. if ( input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT ) )
  214. return;
  215. if ( input()->IsKeyDown( KEY_LCONTROL ) || input()->IsKeyDown( KEY_LCONTROL ) )
  216. return;
  217. */
  218. int nMouseX;
  219. int nMouseY;
  220. input()->GetCursorPosition( nMouseX, nMouseY );
  221. ScreenToLocal( nMouseX, nMouseY );
  222. RequestFocus();
  223. bool bStartDragging = false;
  224. bool bPostDragStartSignal = false;
  225. if (
  226. nMouseX >= ( m_nNobPos[ kXAxis ] - m_nNobHalfSize[ kXAxis ] ) &&
  227. nMouseX <= ( m_nNobPos[ kXAxis ] + m_nNobHalfSize[ kXAxis ] ) &&
  228. nMouseY >= ( m_nNobPos[ kYAxis ] - m_nNobHalfSize[ kYAxis ] ) &&
  229. nMouseY <= ( m_nNobPos[ kYAxis ] + m_nNobHalfSize[ kYAxis ] ) )
  230. {
  231. bStartDragging = true;
  232. bPostDragStartSignal = true;
  233. }
  234. else
  235. {
  236. // we clicked elsewhere on the slider; move the nob to that position
  237. int nTrackX, nTrackY, nTrackWide, nTrackTall;
  238. GetTrackRect( nTrackX, nTrackY, nTrackWide, nTrackTall );
  239. m_nNobPos[ kXAxis ] = clamp( nMouseX, nTrackX, nTrackX + nTrackWide - 1 );
  240. m_nNobPos[ kYAxis ] = clamp( nMouseY, nTrackY, nTrackY + nTrackTall - 1 );
  241. RecomputeValueFromNobPos( false );
  242. Repaint();
  243. SendSliderMovedMessage();
  244. m_nNobDragStartPos[ kXAxis ] = nMouseX;
  245. m_nNobDragStartPos[ kYAxis ] = nMouseY;
  246. m_nDragStartPos[ kXAxis ] = nMouseX;
  247. m_nDragStartPos[ kYAxis ] = nMouseY;
  248. OnCursorMoved( nMouseX, nMouseY );
  249. bStartDragging = IsDragOnRepositionNob();
  250. if ( bStartDragging )
  251. {
  252. SendSliderDragStartMessage();
  253. }
  254. }
  255. if ( bStartDragging )
  256. {
  257. // drag the nob
  258. m_bDragging = true;
  259. input()->SetMouseCapture( GetVPanel() );
  260. m_nNobDragStartPos[ kXAxis ] = m_nNobPos[ kXAxis ];
  261. m_nNobDragStartPos[ kYAxis ] = m_nNobPos[ kYAxis ];
  262. m_nDragStartPos[ kXAxis ] = nMouseX;
  263. m_nDragStartPos[ kYAxis ] = nMouseY;
  264. }
  265. if ( bPostDragStartSignal )
  266. {
  267. SendSliderDragStartMessage();
  268. }
  269. }
  270. //-----------------------------------------------------------------------------
  271. // Purpose: Just handle double presses like mouse presses
  272. //-----------------------------------------------------------------------------
  273. void C2DSlider::OnMouseDoublePressed( MouseCode mouseCode )
  274. {
  275. OnMousePressed( mouseCode );
  276. }
  277. //-----------------------------------------------------------------------------
  278. // Purpose: Stop dragging when the mouse is released.
  279. //-----------------------------------------------------------------------------
  280. void C2DSlider::OnMouseReleased( MouseCode /* mouseCode */ )
  281. {
  282. if ( m_bDragging )
  283. {
  284. m_bDragging = false;
  285. input()->SetMouseCapture( 0 );
  286. SendSliderDragEndMessage();
  287. }
  288. }
  289. //-----------------------------------------------------------------------------
  290. //
  291. //-----------------------------------------------------------------------------
  292. void C2DSlider::SetNobWidth( int nWidth )
  293. {
  294. m_nNobHalfSize[ kXAxis ] = ( ( nWidth | 1 ) - 1 ) / 2;
  295. }
  296. //-----------------------------------------------------------------------------
  297. //
  298. //-----------------------------------------------------------------------------
  299. int C2DSlider::GetNobWidth() const
  300. {
  301. return m_nNobHalfSize[ kXAxis ] * 2 + 1;
  302. }
  303. //-----------------------------------------------------------------------------
  304. //
  305. //-----------------------------------------------------------------------------
  306. void C2DSlider::SetNobTall( int nTall )
  307. {
  308. m_nNobHalfSize[ kYAxis ] = ( ( nTall | 1 ) - 1 ) / 2;
  309. }
  310. //-----------------------------------------------------------------------------
  311. //
  312. //-----------------------------------------------------------------------------
  313. int C2DSlider::GetNobTall() const
  314. {
  315. return m_nNobHalfSize[ kYAxis ] * 2 + 1;
  316. }
  317. //-----------------------------------------------------------------------------
  318. //
  319. //-----------------------------------------------------------------------------
  320. void C2DSlider::SetNobSize( int nWidth, int nTall )
  321. {
  322. SetNobWidth( nWidth );
  323. SetNobTall( nTall );
  324. }
  325. //-----------------------------------------------------------------------------
  326. //
  327. //-----------------------------------------------------------------------------
  328. void C2DSlider::GetNobSize( int &nHalfWidth, int &nHalfTall ) const
  329. {
  330. nHalfWidth = GetNobWidth();
  331. nHalfTall = GetNobTall();
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Purpose: If you click on the slider outside of the nob, the nob jumps
  335. // to the click position, and if this setting is enabled, the nob
  336. // is then draggable from the new position until the mouse is released
  337. // Input : state -
  338. //-----------------------------------------------------------------------------
  339. void C2DSlider::SetDragOnRepositionNob( bool bState )
  340. {
  341. m_bIsDragOnRepositionNob = bState;
  342. }
  343. //-----------------------------------------------------------------------------
  344. //
  345. //-----------------------------------------------------------------------------
  346. bool C2DSlider::IsDragOnRepositionNob() const
  347. {
  348. return m_bIsDragOnRepositionNob;
  349. }
  350. //-----------------------------------------------------------------------------
  351. //
  352. //-----------------------------------------------------------------------------
  353. bool C2DSlider::IsDragged() const
  354. {
  355. return m_bDragging;
  356. }
  357. //-----------------------------------------------------------------------------
  358. // Purpose: Set the size of the slider bar.
  359. // Warning less than 30 pixels tall and everything probably won't fit.
  360. //-----------------------------------------------------------------------------
  361. void C2DSlider::OnSizeChanged( int nWide, int nTall )
  362. {
  363. BaseClass::OnSizeChanged( nWide, nTall );
  364. RecomputeNobPosFromValue();
  365. }
  366. //-----------------------------------------------------------------------------
  367. // Purpose: Draw everything on screen
  368. //-----------------------------------------------------------------------------
  369. void C2DSlider::Paint()
  370. {
  371. DrawNob();
  372. }
  373. //-----------------------------------------------------------------------------
  374. // Purpose: Draw the slider track
  375. //-----------------------------------------------------------------------------
  376. void C2DSlider::PaintBackground()
  377. {
  378. BaseClass::PaintBackground();
  379. int x, y;
  380. int wide,tall;
  381. GetTrackRect( x, y, wide, tall );
  382. surface()->DrawSetColor( s_TrackColor );
  383. surface()->DrawFilledRect( x, y, x + wide + 1, y + tall + 1 );
  384. if ( m_pInsetBorder )
  385. {
  386. m_pInsetBorder->Paint( x, y, x + wide, y + tall );
  387. }
  388. }
  389. //-----------------------------------------------------------------------------
  390. // Purpose: Layout the slider before drawing it on screen.
  391. //-----------------------------------------------------------------------------
  392. void C2DSlider::PerformLayout()
  393. {
  394. BaseClass::PerformLayout();
  395. RecomputeNobPosFromValue();
  396. }
  397. //-----------------------------------------------------------------------------
  398. // Purpose:
  399. //-----------------------------------------------------------------------------
  400. void C2DSlider::ApplySchemeSettings( IScheme *pScheme )
  401. {
  402. BaseClass::ApplySchemeSettings( pScheme );
  403. s_TextColor = pScheme->GetColor( "2DSlider.TextColor", s_TextColor );
  404. s_NobColor = pScheme->GetColor( "2DSlider.NobColor", s_NobColor );
  405. s_TickColor = pScheme->GetColor( "2DSlider.TickColor", s_TickColor );
  406. s_TickFillXColor = pScheme->GetColor( "2DSlider.TickFillXColor", s_TickFillXColor );
  407. s_TickFillYColor = pScheme->GetColor( "2DSlider.TickFillYColor", s_TickFillYColor );
  408. s_TickFillColor = pScheme->GetColor( "2DSlider.TickFillColor", s_TickFillColor );
  409. s_TrackColor = pScheme->GetColor( "2DSlider.TrackColor", s_TrackColor );
  410. m_pLabel->SetColor( s_TextColor );
  411. m_pLabel->SetFont( pScheme->GetFont( "Default" ) );
  412. m_pLabel->ResizeImageToContent();
  413. SetFgColor( s_NobColor );
  414. m_pNobBorder = pScheme->GetBorder( "ButtonBorder" );
  415. m_pInsetBorder = pScheme->GetBorder( "ButtonDepressedBorder" );
  416. }
  417. //-----------------------------------------------------------------------------
  418. // Purpose:
  419. //-----------------------------------------------------------------------------
  420. void C2DSlider::ApplySettings( KeyValues *inResourceData )
  421. {
  422. BaseClass::ApplySettings( inResourceData );
  423. SetNobWidth( inResourceData->GetInt( "nobWidth", GetNobWidth() ) );
  424. SetNobTall( inResourceData->GetInt( "nobTall", GetNobTall() ) );
  425. SetDrawLabel( inResourceData->GetBool( "drawLabel", IsDrawingLabel() ) );
  426. wchar_t buf[ BUFSIZ ];
  427. m_pLabel->GetText( buf, ARRAYSIZE( buf ) );
  428. SetLabelText( inResourceData->GetWString( "labelText", buf ) );
  429. SetDragOnRepositionNob( inResourceData->GetBool( "dragOnRepositionNob", IsDragOnRepositionNob() ) );
  430. }
  431. //-----------------------------------------------------------------------------
  432. // Purpose:
  433. //-----------------------------------------------------------------------------
  434. void C2DSlider::GetSettings( KeyValues *outResourceData )
  435. {
  436. BaseClass::GetSettings( outResourceData );
  437. outResourceData->SetInt( "nobWidth", GetNobWidth() );
  438. outResourceData->SetInt( "nobTall", GetNobTall() );
  439. outResourceData->SetBool( "drawLabel", IsDrawingLabel() );
  440. wchar_t buf[ BUFSIZ ];
  441. m_pLabel->GetText( buf, ARRAYSIZE( buf ) );
  442. outResourceData->SetWString( "labelText", buf );
  443. outResourceData->SetBool( "dragOnRepositionNob", IsDragOnRepositionNob() );
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Purpose:
  447. //-----------------------------------------------------------------------------
  448. const char *C2DSlider::GetDescription()
  449. {
  450. static char buf[ 1024 ];
  451. Q_snprintf( buf, sizeof( buf ), "%s, int nobWidth, int nobTall, bool dragOnRepositionNob", BaseClass::GetDescription() );
  452. return buf;
  453. }
  454. //-----------------------------------------------------------------------------
  455. // Purpose: Handle key presses
  456. //-----------------------------------------------------------------------------
  457. void C2DSlider::OnKeyCodeTyped( KeyCode nKeyCode )
  458. {
  459. switch ( nKeyCode )
  460. {
  461. // for now left and right arrows just open or close submenus if they are there.
  462. case KEY_LEFT:
  463. MoveNobRelative( -1, 0 );
  464. break;
  465. case KEY_RIGHT:
  466. MoveNobRelative( 1, 0 );
  467. break;
  468. case KEY_DOWN:
  469. MoveNobRelative( 0, 1 );
  470. break;
  471. case KEY_UP:
  472. MoveNobRelative( 0, -1 );
  473. break;
  474. case KEY_HOME:
  475. SetValueX( m_fRange[ kXAxis ][ 0 ] );
  476. break;
  477. case KEY_END:
  478. SetValueX( m_fRange[ kXAxis ][ 1 ] );
  479. break;
  480. case KEY_PAGEUP:
  481. SetValueY( m_fRange[ kYAxis ][ 0 ] );
  482. break;
  483. case KEY_PAGEDOWN:
  484. SetValueY( m_fRange[ kYAxis ][ 1 ] );
  485. break;
  486. default:
  487. BaseClass::OnKeyCodeTyped( nKeyCode );
  488. break;
  489. }
  490. }
  491. //-----------------------------------------------------------------------------
  492. // Purpose: Draw the nob part of the slider.
  493. //-----------------------------------------------------------------------------
  494. void C2DSlider::DrawNob()
  495. {
  496. // horizontal nob
  497. int x, y;
  498. int wide,tall;
  499. GetTrackRect( x, y, wide, tall );
  500. surface()->DrawSetColor( s_TickFillXColor );
  501. surface()->DrawFilledRect( x, y, x + m_nNobPos[ kXAxis ], y + m_nNobPos[ kYAxis ] );
  502. surface()->DrawSetColor( s_TickFillYColor );
  503. surface()->DrawFilledRect( x + m_nNobPos[ kXAxis ] + 1, y + m_nNobPos[ kYAxis ] + 1, x + wide + 1, y + tall + 1 );
  504. surface()->DrawSetColor( s_TickFillColor );
  505. surface()->DrawFilledRect( x, y + m_nNobPos[ kYAxis ] + 1, x + m_nNobPos[ kXAxis ], y + tall + 1 );
  506. surface()->DrawSetColor( s_TickFillColor );
  507. surface()->DrawFilledRect( x, y + tall, m_nNobPos[ kXAxis ] + 1, m_nNobPos[ kYAxis ] );
  508. surface()->DrawSetColor( s_TickColor );
  509. surface()->DrawFilledRect( x, m_nNobPos[ kYAxis ], x + wide - 1, m_nNobPos[ kYAxis ] + 1 );
  510. surface()->DrawFilledRect( m_nNobPos[ kXAxis ], y, m_nNobPos[ kXAxis ] + 1, y + tall - 1 );
  511. // Redraw the inset border
  512. if ( m_pInsetBorder )
  513. {
  514. m_pInsetBorder->Paint( x, y, x + wide, y + tall );
  515. }
  516. surface()->DrawSetColor( s_NobColor );
  517. surface()->DrawFilledRect(
  518. m_nNobPos[ kXAxis ] - m_nNobHalfSize[ kXAxis ], m_nNobPos[ kYAxis ] - m_nNobHalfSize[ kYAxis ],
  519. m_nNobPos[ kXAxis ] + m_nNobHalfSize[ kXAxis ] + 1, m_nNobPos[ kYAxis ] + m_nNobHalfSize[ kYAxis ] + 1 );
  520. // border
  521. if ( m_pNobBorder )
  522. {
  523. m_pNobBorder->Paint(
  524. m_nNobPos[ kXAxis ] - m_nNobHalfSize[ kXAxis ], m_nNobPos[ kYAxis ] - m_nNobHalfSize[ kYAxis ],
  525. m_nNobPos[ kXAxis ] + m_nNobHalfSize[ kXAxis ] + 1, m_nNobPos[ kYAxis ] + m_nNobHalfSize[ kYAxis ] + 1 );
  526. }
  527. char buf[ BUFSIZ ];
  528. Q_snprintf( buf, ARRAYSIZE( buf ), "n %02d %02d v %3.1f %3.1f", m_nNobPos[ kXAxis ], m_nNobPos[ kYAxis ], m_fValue[ kXAxis ], m_fValue[ kYAxis ] );
  529. int nLabelWidth, nLabelTall;
  530. m_pLabel->GetContentSize( nLabelWidth, nLabelTall );
  531. // m_pLabel->SetPos( 10, y + MAX( tall, tall - ( tall - nLabelTall ) / 2 ) );
  532. m_pLabel->SetPos( 10, y + ( MAX( 0, tall - nLabelTall ) ) / 2 );
  533. m_pLabel->Paint();
  534. }
  535. //-----------------------------------------------------------------------------
  536. // Purpose: Get the rectangle to draw the slider track in.
  537. //-----------------------------------------------------------------------------
  538. void C2DSlider::GetTrackRect( int &x, int &y, int &w, int &t )
  539. {
  540. x = 0;
  541. y = 0;
  542. GetPaintSize( w, t );
  543. }
  544. //-----------------------------------------------------------------------------
  545. //
  546. //-----------------------------------------------------------------------------
  547. void C2DSlider::MoveNobRelative( int nX, int nY )
  548. {
  549. int x, y, wide, tall;
  550. GetTrackRect( x, y, wide, tall );
  551. m_nNobPos[ kXAxis ] = clamp( m_nNobPos[ kXAxis ] + nX, x, x + wide - 1 );
  552. m_nNobPos[ kYAxis ] = clamp( m_nNobPos[ kYAxis ] + nY, y, y + tall - 1 );
  553. RecomputeValueFromNobPos( true );
  554. }
  555. //-----------------------------------------------------------------------------
  556. // Purpose: Move the nob on the slider in response to changing its value.
  557. //-----------------------------------------------------------------------------
  558. void C2DSlider::RecomputeNobPosFromValue()
  559. {
  560. int x, y, wide, tall;
  561. GetTrackRect( x, y, wide, tall );
  562. m_nNobPos[ kXAxis ] = static_cast< int >( RemapValClamped( m_fValue[ kXAxis ], m_fRange[ kXAxis ][ 0 ], m_fRange[ kXAxis ][ 1 ], x, x + wide - 1 ) );
  563. m_nNobPos[ kYAxis ] = static_cast< int >( RemapValClamped( m_fValue[ kYAxis ], m_fRange[ kYAxis ][ 0 ], m_fRange[ kYAxis ][ 1 ], y, y + tall - 1 ) );
  564. Repaint();
  565. }
  566. //-----------------------------------------------------------------------------
  567. // Purpose: Sync the slider's value up with the nob's position.
  568. //-----------------------------------------------------------------------------
  569. void C2DSlider::RecomputeValueFromNobPos( bool bTriggerChangeMessage /* = true */ )
  570. {
  571. int x, y, wide, tall;
  572. GetTrackRect( x, y, wide, tall );
  573. const float fValueX = RemapValClamped( m_nNobPos[ kXAxis ], x, x + wide - 1, m_fRange[ kXAxis ][ 0 ], m_fRange[ kXAxis ][ 1 ] );
  574. const float fValueY = RemapValClamped( m_nNobPos[ kYAxis ], y, y + tall - 1, m_fRange[ kYAxis ][ 0 ], m_fRange[ kYAxis ][ 1 ] );
  575. SetValue( fValueX, fValueY, bTriggerChangeMessage );
  576. }
  577. //-----------------------------------------------------------------------------
  578. // Purpose: Send a message to interested parties when the slider moves
  579. //-----------------------------------------------------------------------------
  580. void C2DSlider::SendSliderMovedMessage()
  581. {
  582. KeyValues *p2DSliderMoved = new KeyValues( "2DSliderMoved" );
  583. p2DSliderMoved->SetFloat( "valueX", m_fValue[ kXAxis ] );
  584. p2DSliderMoved->SetFloat( "valueY", m_fValue[ kYAxis ] );
  585. PostActionSignal( p2DSliderMoved );
  586. }
  587. //-----------------------------------------------------------------------------
  588. // Purpose: Send a message to interested parties when the user begins dragging the slider
  589. //-----------------------------------------------------------------------------
  590. void C2DSlider::SendSliderDragStartMessage()
  591. {
  592. KeyValues *p2DSliderDragStart = new KeyValues( "2DSliderDragStart" );
  593. p2DSliderDragStart->SetFloat( "valueX", m_fValue[ kXAxis ] );
  594. p2DSliderDragStart->SetFloat( "valueY", m_fValue[ kYAxis ] );
  595. PostActionSignal( p2DSliderDragStart );
  596. }
  597. //-----------------------------------------------------------------------------
  598. // Purpose: Send a message to interested parties when the user ends dragging the slider
  599. //-----------------------------------------------------------------------------
  600. void C2DSlider::SendSliderDragEndMessage()
  601. {
  602. KeyValues *p2DSliderDragEnd = new KeyValues( "2DSliderDragEnd" );
  603. p2DSliderDragEnd->SetFloat( "valueX", m_fValue[ kXAxis ] );
  604. p2DSliderDragEnd->SetFloat( "valueY", m_fValue[ kYAxis ] );
  605. PostActionSignal( p2DSliderDragEnd );
  606. }