Team Fortress 2 Source Code as on 22/4/2020
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.

954 lines
24 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <stdio.h>
  8. #define PROTECTED_THINGS_DISABLE
  9. #include <vgui/MouseCode.h>
  10. #include <KeyValues.h>
  11. #include <vgui/IBorder.h>
  12. #include <vgui/IInput.h>
  13. #include <vgui/ISystem.h>
  14. #include <vgui/IScheme.h>
  15. #include <vgui/ISurface.h>
  16. #include <vgui/ILocalize.h>
  17. #include <vgui_controls/Slider.h>
  18. #include <vgui_controls/Controls.h>
  19. #include <vgui_controls/TextImage.h>
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include <tier0/memdbgon.h>
  22. using namespace vgui;
  23. DECLARE_BUILD_FACTORY( Slider );
  24. static const float NOB_SIZE = 8.0f;
  25. //-----------------------------------------------------------------------------
  26. // Purpose: Create a slider bar with ticks underneath it
  27. //-----------------------------------------------------------------------------
  28. Slider::Slider(Panel *parent, const char *panelName ) : BaseClass(parent, panelName)
  29. {
  30. m_bIsDragOnRepositionNob = false;
  31. _dragging = false;
  32. _value = 0;
  33. _range[0] = 0;
  34. _range[1] = 0;
  35. _buttonOffset = 0;
  36. _sliderBorder = NULL;
  37. _insetBorder = NULL;
  38. m_nNumTicks = 10;
  39. _leftCaption = NULL;
  40. _rightCaption = NULL;
  41. _subrange[ 0 ] = 0;
  42. _subrange[ 1 ] = 0;
  43. m_bUseSubRange = false;
  44. m_bInverted = false;
  45. SetThumbWidth( 8 );
  46. RecomputeNobPosFromValue();
  47. AddActionSignalTarget(this);
  48. SetBlockDragChaining( true );
  49. }
  50. // This allows the slider to behave like it's larger than what's actually being drawn
  51. //-----------------------------------------------------------------------------
  52. // Purpose:
  53. // Input : bEnable -
  54. // 0 -
  55. // 100 -
  56. //-----------------------------------------------------------------------------
  57. void Slider::SetSliderThumbSubRange( bool bEnable, int nMin /*= 0*/, int nMax /*= 100*/ )
  58. {
  59. m_bUseSubRange = bEnable;
  60. _subrange[ 0 ] = nMin;
  61. _subrange[ 1 ] = nMax;
  62. }
  63. //-----------------------------------------------------------------------------
  64. // Purpose: Set the size of the slider bar.
  65. // Warning less than 30 pixels tall and everything probably won't fit.
  66. //-----------------------------------------------------------------------------
  67. void Slider::OnSizeChanged(int wide,int tall)
  68. {
  69. BaseClass::OnSizeChanged(wide,tall);
  70. RecomputeNobPosFromValue();
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose: Set the value of the slider to one of the ticks.
  74. //-----------------------------------------------------------------------------
  75. void Slider::SetValue(int value, bool bTriggerChangeMessage)
  76. {
  77. int oldValue=_value;
  78. if ( _range[0] < _range[1] )
  79. {
  80. if(value<_range[0])
  81. {
  82. value=_range[0];
  83. }
  84. if(value>_range[1])
  85. {
  86. value=_range[1];
  87. }
  88. }
  89. else
  90. {
  91. if(value<_range[1])
  92. {
  93. value=_range[1];
  94. }
  95. if(value>_range[0])
  96. {
  97. value=_range[0];
  98. }
  99. }
  100. _value = value;
  101. RecomputeNobPosFromValue();
  102. if (_value != oldValue && bTriggerChangeMessage)
  103. {
  104. SendSliderMovedMessage();
  105. }
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Purpose: Return the value of the slider
  109. //-----------------------------------------------------------------------------
  110. int Slider::GetValue()
  111. {
  112. return _value;
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose: Layout the slider before drawing it on screen.
  116. //-----------------------------------------------------------------------------
  117. void Slider::PerformLayout()
  118. {
  119. BaseClass::PerformLayout();
  120. RecomputeNobPosFromValue();
  121. if (_leftCaption)
  122. {
  123. _leftCaption->ResizeImageToContent();
  124. }
  125. if (_rightCaption)
  126. {
  127. _rightCaption->ResizeImageToContent();
  128. }
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose: Move the nob on the slider in response to changing its value.
  132. //-----------------------------------------------------------------------------
  133. void Slider::RecomputeNobPosFromValue()
  134. {
  135. //int wide,tall;
  136. //GetPaintSize(wide,tall);
  137. int x, y, wide, tall;
  138. GetTrackRect( x, y, wide, tall );
  139. float usevalue = _value;
  140. int *userange = &_range[ 0 ];
  141. if ( m_bUseSubRange )
  142. {
  143. userange = &_subrange[ 0 ];
  144. usevalue = clamp( _value, _subrange[ 0 ], _subrange[ 1 ] );
  145. }
  146. float fwide=(float)wide;
  147. float frange=(float)(userange[1] -userange[0]);
  148. float fvalue=(float)(usevalue -userange[0]);
  149. float fper = (frange != 0.0f) ? fvalue / frange : 0.0f;
  150. if ( m_bInverted )
  151. fper = 1.0f - fper;
  152. float freepixels = fwide - _nobSize;
  153. float leftpixel = (float)x;
  154. float firstpixel = leftpixel + freepixels * fper + 0.5f;
  155. _nobPos[0]=(int)( firstpixel );
  156. _nobPos[1]=(int)( firstpixel + _nobSize );
  157. int rightEdge = x + wide;
  158. if(_nobPos[1]> rightEdge )
  159. {
  160. _nobPos[0]=rightEdge-((int)_nobSize);
  161. _nobPos[1]=rightEdge;
  162. }
  163. Repaint();
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Purpose: Sync the slider's value up with the nob's position.
  167. //-----------------------------------------------------------------------------
  168. void Slider::RecomputeValueFromNobPos()
  169. {
  170. int value = EstimateValueAtPos( _nobPos[ 0 ], 0 );
  171. SetValue( value );
  172. }
  173. int Slider::EstimateValueAtPos( int localMouseX, int /*localMouseY*/ )
  174. {
  175. int x, y, wide, tall;
  176. GetTrackRect( x, y, wide, tall );
  177. int *userange = &_range[ 0 ];
  178. if ( m_bUseSubRange )
  179. {
  180. userange = &_subrange[ 0 ];
  181. }
  182. float fwide = (float)wide;
  183. float fvalue = (float)( _value - userange[0] );
  184. float fnob = (float)( localMouseX - x );
  185. float freepixels = fwide - _nobSize;
  186. // Map into reduced range
  187. fvalue = freepixels != 0.0f ? fnob / freepixels : 0.0f;
  188. return (int) (RemapVal( fvalue, 0.0, 1.0, userange[0], userange[1] ));
  189. }
  190. void Slider::SetInverted( bool bInverted )
  191. {
  192. m_bInverted = bInverted;
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Purpose: Send a message to interested parties when the slider moves
  196. //-----------------------------------------------------------------------------
  197. void Slider::SendSliderMovedMessage()
  198. {
  199. // send a changed message
  200. KeyValues *pParams = new KeyValues("SliderMoved", "position", _value);
  201. pParams->SetPtr( "panel", this );
  202. PostActionSignal( pParams );
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose: Send a message to interested parties when the user begins dragging the slider
  206. //-----------------------------------------------------------------------------
  207. void Slider::SendSliderDragStartMessage()
  208. {
  209. // send a message
  210. KeyValues *pParams = new KeyValues("SliderDragStart", "position", _value);
  211. pParams->SetPtr( "panel", this );
  212. PostActionSignal( pParams );
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Purpose: Send a message to interested parties when the user ends dragging the slider
  216. //-----------------------------------------------------------------------------
  217. void Slider::SendSliderDragEndMessage()
  218. {
  219. // send a message
  220. KeyValues *pParams = new KeyValues("SliderDragEnd", "position", _value);
  221. pParams->SetPtr( "panel", this );
  222. PostActionSignal( pParams );
  223. }
  224. //-----------------------------------------------------------------------------
  225. // Purpose:
  226. //-----------------------------------------------------------------------------
  227. void Slider::ApplySchemeSettings(IScheme *pScheme)
  228. {
  229. BaseClass::ApplySchemeSettings(pScheme);
  230. SetFgColor(GetSchemeColor("Slider.NobColor", pScheme));
  231. // this line is useful for debugging
  232. //SetBgColor(GetSchemeColor("0 0 0 255"));
  233. m_TickColor = pScheme->GetColor( "Slider.TextColor", GetFgColor() );
  234. m_TrackColor = pScheme->GetColor( "Slider.TrackColor", GetFgColor() );
  235. #ifdef _X360
  236. m_DepressedBgColor = GetSchemeColor("Slider.NobFocusColor", pScheme);
  237. #endif
  238. m_DisabledTextColor1 = pScheme->GetColor( "Slider.DisabledTextColor1", GetFgColor() );
  239. m_DisabledTextColor2 = pScheme->GetColor( "Slider.DisabledTextColor2", GetFgColor() );
  240. _sliderBorder = pScheme->GetBorder("ButtonBorder");
  241. _insetBorder = pScheme->GetBorder("ButtonDepressedBorder");
  242. if ( _leftCaption )
  243. {
  244. _leftCaption->SetFont(pScheme->GetFont("DefaultVerySmall", IsProportional() ));
  245. }
  246. if ( _rightCaption )
  247. {
  248. _rightCaption->SetFont(pScheme->GetFont("DefaultVerySmall", IsProportional() ));
  249. }
  250. }
  251. //-----------------------------------------------------------------------------
  252. // Purpose:
  253. //-----------------------------------------------------------------------------
  254. void Slider::GetSettings(KeyValues *outResourceData)
  255. {
  256. BaseClass::GetSettings(outResourceData);
  257. char buf[256];
  258. if (_leftCaption)
  259. {
  260. _leftCaption->GetUnlocalizedText(buf, sizeof(buf));
  261. outResourceData->SetString("leftText", buf);
  262. }
  263. if (_rightCaption)
  264. {
  265. _rightCaption->GetUnlocalizedText(buf, sizeof(buf));
  266. outResourceData->SetString("rightText", buf);
  267. }
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Purpose:
  271. //-----------------------------------------------------------------------------
  272. void Slider::ApplySettings(KeyValues *inResourceData)
  273. {
  274. BaseClass::ApplySettings(inResourceData);
  275. const char *left = inResourceData->GetString("leftText", NULL);
  276. const char *right = inResourceData->GetString("rightText", NULL);
  277. int thumbWidth = inResourceData->GetInt("thumbwidth", 0);
  278. if (thumbWidth != 0)
  279. {
  280. SetThumbWidth(thumbWidth);
  281. }
  282. SetTickCaptions(left, right);
  283. int nNumTicks = inResourceData->GetInt( "numTicks", -1 );
  284. if ( nNumTicks >= 0 )
  285. {
  286. SetNumTicks( nNumTicks );
  287. }
  288. int nCurrentRange[2];
  289. GetRange( nCurrentRange[0], nCurrentRange[1] );
  290. KeyValues *pRangeMin = inResourceData->FindKey( "rangeMin", false );
  291. KeyValues *pRangeMax = inResourceData->FindKey( "rangeMax", false );
  292. bool bDoClamp = false;
  293. if ( pRangeMin )
  294. {
  295. _range[0] = inResourceData->GetInt( "rangeMin" );
  296. bDoClamp = true;
  297. }
  298. if ( pRangeMax )
  299. {
  300. _range[1] = inResourceData->GetInt( "rangeMax" );
  301. bDoClamp = true;
  302. }
  303. if ( bDoClamp )
  304. {
  305. ClampRange();
  306. }
  307. }
  308. //-----------------------------------------------------------------------------
  309. // Purpose:
  310. //-----------------------------------------------------------------------------
  311. const char *Slider::GetDescription()
  312. {
  313. static char buf[1024];
  314. Q_snprintf(buf, sizeof(buf), "%s, string leftText, string rightText", BaseClass::GetDescription());
  315. return buf;
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Purpose: Get the rectangle to draw the slider track in.
  319. //-----------------------------------------------------------------------------
  320. void Slider::GetTrackRect( int& x, int& y, int& w, int& h )
  321. {
  322. int wide, tall;
  323. GetPaintSize( wide, tall );
  324. x = 0;
  325. y = 8;
  326. w = wide - (int)_nobSize;
  327. h = 4;
  328. }
  329. //-----------------------------------------------------------------------------
  330. // Purpose: Draw everything on screen
  331. //-----------------------------------------------------------------------------
  332. void Slider::Paint()
  333. {
  334. DrawTicks();
  335. DrawTickLabels();
  336. // Draw nob last so it draws over ticks.
  337. DrawNob();
  338. }
  339. //-----------------------------------------------------------------------------
  340. // Purpose: Draw the ticks below the slider.
  341. //-----------------------------------------------------------------------------
  342. void Slider::DrawTicks()
  343. {
  344. int x, y;
  345. int wide,tall;
  346. GetTrackRect( x, y, wide, tall );
  347. // Figure out how to draw the ticks
  348. // GetPaintSize( wide, tall );
  349. float fwide = (float)wide;
  350. float freepixels = fwide - _nobSize;
  351. float leftpixel = _nobSize / 2.0f;
  352. float pixelspertick = freepixels / ( m_nNumTicks );
  353. y += (int)_nobSize;
  354. int tickHeight = 5;
  355. if (IsEnabled())
  356. {
  357. surface()->DrawSetColor( m_TickColor ); //vgui::Color( 127, 140, 127, 255 ) );
  358. for ( int i = 0; i <= m_nNumTicks; i++ )
  359. {
  360. int xpos = (int)( leftpixel + i * pixelspertick );
  361. surface()->DrawFilledRect( xpos, y, xpos + 1, y + tickHeight );
  362. }
  363. }
  364. else
  365. {
  366. surface()->DrawSetColor( m_DisabledTextColor1 ); //vgui::Color( 127, 140, 127, 255 ) );
  367. for ( int i = 0; i <= m_nNumTicks; i++ )
  368. {
  369. int xpos = (int)( leftpixel + i * pixelspertick );
  370. surface()->DrawFilledRect( xpos+1, y+1, xpos + 2, y + tickHeight + 1 );
  371. }
  372. surface()->DrawSetColor( m_DisabledTextColor2 ); //vgui::Color( 127, 140, 127, 255 ) );
  373. for ( int i = 0; i <= m_nNumTicks; i++ )
  374. {
  375. int xpos = (int)( leftpixel + i * pixelspertick );
  376. surface()->DrawFilledRect( xpos, y, xpos + 1, y + tickHeight );
  377. }
  378. }
  379. }
  380. //-----------------------------------------------------------------------------
  381. // Purpose: Draw Tick labels under the ticks.
  382. //-----------------------------------------------------------------------------
  383. void Slider::DrawTickLabels()
  384. {
  385. int x, y;
  386. int wide,tall;
  387. GetTrackRect( x, y, wide, tall );
  388. // Figure out how to draw the ticks
  389. // GetPaintSize( wide, tall );
  390. y += (int)NOB_SIZE + 4;
  391. // Draw Start and end range values
  392. if (IsEnabled())
  393. surface()->DrawSetTextColor( m_TickColor ); //vgui::Color( 127, 140, 127, 255 ) );
  394. else
  395. surface()->DrawSetTextColor( m_DisabledTextColor1 ); //vgui::Color( 127, 140, 127, 255 ) );
  396. if ( _leftCaption != NULL )
  397. {
  398. _leftCaption->SetPos(0, y);
  399. if (IsEnabled())
  400. {
  401. _leftCaption->SetColor( m_TickColor );
  402. }
  403. else
  404. {
  405. _leftCaption->SetColor( m_DisabledTextColor1 );
  406. }
  407. _leftCaption->Paint();
  408. }
  409. if ( _rightCaption != NULL)
  410. {
  411. int rwide, rtall;
  412. _rightCaption->GetSize(rwide, rtall);
  413. _rightCaption->SetPos((int)(wide - rwide) , y);
  414. if (IsEnabled())
  415. {
  416. _rightCaption->SetColor( m_TickColor );
  417. }
  418. else
  419. {
  420. _rightCaption->SetColor( m_DisabledTextColor1 );
  421. }
  422. _rightCaption->Paint();
  423. }
  424. }
  425. //-----------------------------------------------------------------------------
  426. // Purpose: Draw the nob part of the slider.
  427. //-----------------------------------------------------------------------------
  428. void Slider::DrawNob()
  429. {
  430. // horizontal nob
  431. int x, y;
  432. int wide,tall;
  433. GetTrackRect( x, y, wide, tall );
  434. Color col = GetFgColor();
  435. #ifdef _X360
  436. if(HasFocus())
  437. {
  438. col = m_DepressedBgColor;
  439. }
  440. #endif
  441. surface()->DrawSetColor(col);
  442. int nobheight = 16;
  443. surface()->DrawFilledRect(
  444. _nobPos[0],
  445. y + tall / 2 - nobheight / 2,
  446. _nobPos[1],
  447. y + tall / 2 + nobheight / 2);
  448. // border
  449. if (_sliderBorder)
  450. {
  451. _sliderBorder->Paint(
  452. _nobPos[0],
  453. y + tall / 2 - nobheight / 2,
  454. _nobPos[1],
  455. y + tall / 2 + nobheight / 2);
  456. }
  457. }
  458. //-----------------------------------------------------------------------------
  459. // Purpose: Set the text labels of the Start and end ticks.
  460. //-----------------------------------------------------------------------------
  461. void Slider::SetTickCaptions( const char *left, const char *right )
  462. {
  463. if (left)
  464. {
  465. if (_leftCaption)
  466. {
  467. _leftCaption->SetText(left);
  468. }
  469. else
  470. {
  471. _leftCaption = new TextImage(left);
  472. }
  473. }
  474. if (right)
  475. {
  476. if (_rightCaption)
  477. {
  478. _rightCaption->SetText(right);
  479. }
  480. else
  481. {
  482. _rightCaption = new TextImage(right);
  483. }
  484. }
  485. InvalidateLayout();
  486. }
  487. //-----------------------------------------------------------------------------
  488. // Purpose: Set the text labels of the Start and end ticks.
  489. //-----------------------------------------------------------------------------
  490. void Slider::SetTickCaptions( const wchar_t *left, const wchar_t *right )
  491. {
  492. if (left)
  493. {
  494. if (_leftCaption)
  495. {
  496. _leftCaption->SetText(left);
  497. }
  498. else
  499. {
  500. _leftCaption = new TextImage(left);
  501. }
  502. }
  503. if (right)
  504. {
  505. if (_rightCaption)
  506. {
  507. _rightCaption->SetText(right);
  508. }
  509. else
  510. {
  511. _rightCaption = new TextImage(right);
  512. }
  513. }
  514. InvalidateLayout();
  515. }
  516. //-----------------------------------------------------------------------------
  517. // Purpose: Draw the slider track
  518. //-----------------------------------------------------------------------------
  519. void Slider::PaintBackground()
  520. {
  521. BaseClass::PaintBackground();
  522. int x, y;
  523. int wide,tall;
  524. GetTrackRect( x, y, wide, tall );
  525. surface()->DrawSetColor( m_TrackColor );
  526. surface()->DrawFilledRect( x, y, x + wide, y + tall );
  527. if (_insetBorder)
  528. {
  529. _insetBorder->Paint( x, y, x + wide, y + tall );
  530. }
  531. }
  532. //-----------------------------------------------------------------------------
  533. // Purpose: Set the range of the slider.
  534. //-----------------------------------------------------------------------------
  535. void Slider::SetRange(int min,int max)
  536. {
  537. _range[0]=min;
  538. _range[1]=max;
  539. ClampRange();
  540. }
  541. //-----------------------------------------------------------------------------
  542. // Purpose: Sanity check and clamp the range if necessary.
  543. //-----------------------------------------------------------------------------
  544. void Slider::ClampRange()
  545. {
  546. if ( _range[0] < _range[1] )
  547. {
  548. if(_value<_range[0])
  549. {
  550. SetValue( _range[0], false );
  551. }
  552. else if( _value>_range[1])
  553. {
  554. SetValue( _range[1], false );
  555. }
  556. }
  557. else
  558. {
  559. if(_value<_range[1])
  560. {
  561. SetValue( _range[1], false );
  562. }
  563. else if( _value>_range[0])
  564. {
  565. SetValue( _range[0], false );
  566. }
  567. }
  568. }
  569. //-----------------------------------------------------------------------------
  570. // Purpose: Get the max and min values of the slider
  571. //-----------------------------------------------------------------------------
  572. void Slider::GetRange(int& min,int& max)
  573. {
  574. min=_range[0];
  575. max=_range[1];
  576. }
  577. //-----------------------------------------------------------------------------
  578. // Purpose: Respond when the cursor is moved in our window if we are clicking
  579. // and dragging.
  580. //-----------------------------------------------------------------------------
  581. void Slider::OnCursorMoved(int x,int y)
  582. {
  583. if(!_dragging)
  584. {
  585. return;
  586. }
  587. // input()->GetCursorPos(x,y);
  588. input()->GetCursorPosition( x, y );
  589. ScreenToLocal(x,y);
  590. // int wide,tall;
  591. // GetPaintSize(wide,tall);
  592. int _x, _y, wide, tall;
  593. GetTrackRect( _x, _y, wide, tall );
  594. _nobPos[0]=_nobDragStartPos[0]+(x-_dragStartPos[0]);
  595. _nobPos[1]=_nobDragStartPos[1]+(x-_dragStartPos[0]);
  596. int rightEdge = _x +wide;
  597. int unclamped = _nobPos[ 0 ];
  598. if(_nobPos[1]>rightEdge)
  599. {
  600. _nobPos[0]=rightEdge-(_nobPos[1]-_nobPos[0]);
  601. _nobPos[1]=rightEdge;
  602. }
  603. if(_nobPos[0]<_x)
  604. {
  605. int offset = _x - _nobPos[0];
  606. _nobPos[1]=_nobPos[1]-offset;
  607. _nobPos[0]=0;
  608. }
  609. int value = EstimateValueAtPos( unclamped, 0 );
  610. SetValue( value );
  611. // RecomputeValueFromNobPos();
  612. Repaint();
  613. SendSliderMovedMessage();
  614. }
  615. //-----------------------------------------------------------------------------
  616. // Purpose: If you click on the slider outside of the nob, the nob jumps
  617. // to the click position, and if this setting is enabled, the nob
  618. // is then draggable from the new position until the mouse is released
  619. // Input : state -
  620. //-----------------------------------------------------------------------------
  621. void Slider::SetDragOnRepositionNob( bool state )
  622. {
  623. m_bIsDragOnRepositionNob = state;
  624. }
  625. bool Slider::IsDragOnRepositionNob() const
  626. {
  627. return m_bIsDragOnRepositionNob;
  628. }
  629. bool Slider::IsDragged( void ) const
  630. {
  631. return _dragging;
  632. }
  633. //-----------------------------------------------------------------------------
  634. // Purpose: Respond to mouse presses. Trigger Record staring positon.
  635. //-----------------------------------------------------------------------------
  636. void Slider::OnMousePressed(MouseCode code)
  637. {
  638. int x,y;
  639. if (!IsEnabled())
  640. return;
  641. // input()->GetCursorPos(x,y);
  642. input()->GetCursorPosition( x, y );
  643. ScreenToLocal(x,y);
  644. RequestFocus();
  645. bool startdragging = false, bPostDragStartSignal = false;
  646. if ((x >= _nobPos[0]) && (x < _nobPos[1]))
  647. {
  648. startdragging = true;
  649. bPostDragStartSignal = true;
  650. }
  651. else
  652. {
  653. // we clicked elsewhere on the slider; move the nob to that position
  654. int min, max;
  655. GetRange(min, max);
  656. if ( m_bUseSubRange )
  657. {
  658. min = _subrange[ 0 ];
  659. max = _subrange[ 1 ];
  660. }
  661. // int wide = GetWide();
  662. int _x, _y, wide, tall;
  663. GetTrackRect( _x, _y, wide, tall );
  664. if ( wide > 0 )
  665. {
  666. float frange = ( float )( max - min );
  667. float clickFrac = clamp( ( float )( x - _x ) / (float)( wide - 1 ), 0.0f, 1.0f );
  668. float value = (float)min + clickFrac * frange;
  669. startdragging = IsDragOnRepositionNob();
  670. if ( startdragging )
  671. {
  672. _dragging = true; // Required when as
  673. SendSliderDragStartMessage();
  674. }
  675. SetValue( ( int )( value + 0.5f ) );
  676. }
  677. }
  678. if ( startdragging )
  679. {
  680. // drag the nob
  681. _dragging = true;
  682. input()->SetMouseCapture(GetVPanel());
  683. _nobDragStartPos[0] = _nobPos[0];
  684. _nobDragStartPos[1] = _nobPos[1];
  685. _dragStartPos[0] = x;
  686. _dragStartPos[1] = y;
  687. }
  688. if ( bPostDragStartSignal )
  689. SendSliderDragStartMessage();
  690. }
  691. //-----------------------------------------------------------------------------
  692. // Purpose: Just handle double presses like mouse presses
  693. //-----------------------------------------------------------------------------
  694. void Slider::OnMouseDoublePressed(MouseCode code)
  695. {
  696. OnMousePressed(code);
  697. }
  698. //-----------------------------------------------------------------------------
  699. // Purpose:
  700. //-----------------------------------------------------------------------------
  701. #ifdef _X360
  702. void Slider::OnKeyCodePressed(KeyCode code)
  703. {
  704. switch ( GetBaseButtonCode( code ) )
  705. {
  706. case KEY_XBUTTON_LEFT:
  707. case KEY_XSTICK1_LEFT:
  708. case KEY_XSTICK2_LEFT:
  709. SetValue(GetValue() - 1);
  710. break;
  711. case KEY_XBUTTON_RIGHT:
  712. case KEY_XSTICK1_RIGHT:
  713. case KEY_XSTICK2_RIGHT:
  714. SetValue(GetValue() + 1);
  715. break;
  716. default:
  717. BaseClass::OnKeyCodePressed(code);
  718. break;
  719. }
  720. }
  721. #endif
  722. //-----------------------------------------------------------------------------
  723. // Purpose: Handle key presses
  724. //-----------------------------------------------------------------------------
  725. void Slider::OnKeyCodeTyped(KeyCode code)
  726. {
  727. switch (code)
  728. {
  729. // for now left and right arrows just open or close submenus if they are there.
  730. case KEY_LEFT:
  731. case KEY_DOWN:
  732. {
  733. int val = GetValue();
  734. SetValue(val-1);
  735. break;
  736. }
  737. case KEY_RIGHT:
  738. case KEY_UP:
  739. {
  740. int val = GetValue();
  741. SetValue(val+1);
  742. break;
  743. }
  744. case KEY_PAGEDOWN:
  745. {
  746. int min, max;
  747. GetRange(min, max);
  748. float range = (float) max-min;
  749. float pertick = range/m_nNumTicks;
  750. int val = GetValue();
  751. SetValue(val - (int) pertick);
  752. break;
  753. }
  754. case KEY_PAGEUP:
  755. {
  756. int min, max;
  757. GetRange(min, max);
  758. float range = (float) max-min;
  759. float pertick = range/m_nNumTicks;
  760. int val = GetValue();
  761. SetValue(val + (int) pertick);
  762. break;
  763. }
  764. case KEY_HOME:
  765. {
  766. int min, max;
  767. GetRange(min, max);
  768. SetValue(min);
  769. break;
  770. }
  771. case KEY_END:
  772. {
  773. int min, max;
  774. GetRange(min, max);
  775. SetValue(max);
  776. break;
  777. }
  778. default:
  779. BaseClass::OnKeyCodeTyped(code);
  780. break;
  781. }
  782. }
  783. //-----------------------------------------------------------------------------
  784. // Purpose: Stop dragging when the mouse is released.
  785. //-----------------------------------------------------------------------------
  786. void Slider::OnMouseReleased(MouseCode code)
  787. {
  788. if ( _dragging )
  789. {
  790. _dragging=false;
  791. input()->SetMouseCapture(null);
  792. }
  793. if ( IsEnabled() )
  794. {
  795. SendSliderDragEndMessage();
  796. }
  797. }
  798. //-----------------------------------------------------------------------------
  799. // Purpose: Get the nob's position (the ends of each side of the nob)
  800. //-----------------------------------------------------------------------------
  801. void Slider::GetNobPos(int& min, int& max)
  802. {
  803. min=_nobPos[0];
  804. max=_nobPos[1];
  805. }
  806. //-----------------------------------------------------------------------------
  807. // Purpose:
  808. //-----------------------------------------------------------------------------
  809. void Slider::SetButtonOffset(int buttonOffset)
  810. {
  811. _buttonOffset=buttonOffset;
  812. }
  813. void Slider::SetThumbWidth( int width )
  814. {
  815. _nobSize = (float)width;
  816. }
  817. //-----------------------------------------------------------------------------
  818. // Purpose: Set the number of ticks that appear under the slider.
  819. //-----------------------------------------------------------------------------
  820. void Slider::SetNumTicks( int ticks )
  821. {
  822. m_nNumTicks = ticks;
  823. }