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.

1357 lines
40 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "dme_controls/attributeslider.h"
  7. #include "dme_controls/dmecontrols_utils.h"
  8. #include "materialsystem/imesh.h"
  9. #include "movieobjects/dmeanimationset.h"
  10. #include "movieobjects/dmeexpressionoperator.h"
  11. #include "vgui/IInput.h"
  12. #include "vgui/ISurface.h"
  13. #include "vgui_controls/TextImage.h"
  14. #include "vgui_controls/subrectimage.h"
  15. #include "vgui_controls/CheckButton.h"
  16. #include "vgui_controls/Menu.h"
  17. #include "dme_controls/BaseAnimSetAttributeSliderPanel.h"
  18. #include "dme_controls/BaseAnimSetPresetFaderPanel.h"
  19. #include "dme_controls/BaseAnimationSetEditor.h"
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include "tier0/memdbgon.h"
  22. using namespace vgui;
  23. //-----------------------------------------------------------------------------
  24. // Enums
  25. //-----------------------------------------------------------------------------
  26. #define SLIDER_PIXEL_SPACING 3
  27. #define UNDO_CHAIN_MOUSEWHEEL_ATTRIBUTE_SLIDER 9876
  28. #define FRAC_PER_PIXEL 0.0025f
  29. static ConVar ifm_attributeslider_sensitivity( "ifm_attributeslider_sensitivity", "3.0", 0 );
  30. static ConVar ifm_attributeslider_legacy( "ifm_attributeslider_legacy", "0", 0, "Uses old style slider dragging." );
  31. //-----------------------------------------------------------------------------
  32. // Globals
  33. //-----------------------------------------------------------------------------
  34. static Color s_TextColor( 200, 200, 200, 192 );
  35. static Color s_TextColorFocus( 208, 143, 40, 192 );
  36. static Color s_TextColorDependent( 240, 50, 50, 192 );
  37. static Color s_BarColor[2] =
  38. {
  39. Color( 45, 45, 45, 255 ), Color( 30, 255, 255, 80 )
  40. };
  41. static Color s_ZeroColor[2] =
  42. {
  43. Color( 33, 33, 33, 255 ), Color( 100, 80, 0, 255 )
  44. };
  45. static Color s_DraggingBarColor( 142, 142, 142, 255 );
  46. static Color s_PreviewTickColor( 255, 164, 8, 255 );
  47. static Color s_OldValueTickColor( 100, 100, 100, 63 );
  48. static Color s_MidpointColor( 115, 115, 115, 255 );
  49. //-----------------------------------------------------------------------------
  50. // Blends flex values in left-right space instead of balance/value space
  51. //-----------------------------------------------------------------------------
  52. static void BlendFlexValues( AttributeValue_t *pResult, const AttributeValue_t &src, const AttributeValue_t &dest, float flBlend, float flBalanceFilter = 0.5f )
  53. {
  54. float flLeftFilter, flRightFilter;
  55. ValueBalanceToLeftRight( &flLeftFilter, &flRightFilter, flBlend, flBalanceFilter, 0.0f );
  56. pResult->m_pValue[ANIM_CONTROL_VALUE ] = src.m_pValue[ANIM_CONTROL_VALUE ] + ( dest.m_pValue[ANIM_CONTROL_VALUE ] - src.m_pValue[ANIM_CONTROL_VALUE ] ) * flBlend;
  57. pResult->m_pValue[ANIM_CONTROL_VALUE_LEFT ] = src.m_pValue[ANIM_CONTROL_VALUE_LEFT ] + ( dest.m_pValue[ANIM_CONTROL_VALUE_LEFT ] - src.m_pValue[ANIM_CONTROL_VALUE_LEFT ] ) * flLeftFilter;
  58. pResult->m_pValue[ANIM_CONTROL_VALUE_RIGHT] = src.m_pValue[ANIM_CONTROL_VALUE_RIGHT] + ( dest.m_pValue[ANIM_CONTROL_VALUE_RIGHT] - src.m_pValue[ANIM_CONTROL_VALUE_RIGHT] ) * flRightFilter;
  59. }
  60. static void BlendTransformValues( AttributeValue_t *pResult, const AttributeValue_t &src, const AttributeValue_t &dest, float flBlend )
  61. {
  62. pResult->m_Vector = Lerp( flBlend, src.m_Vector, dest.m_Vector );
  63. // TODO: SHould this be a Slerp or a simple blend or some other op?
  64. QuaternionSlerp( src.m_Quaternion, dest.m_Quaternion, flBlend, pResult->m_Quaternion );
  65. }
  66. void BlendValues( bool bTransform, AttributeValue_t *pResult, const AttributeValue_t &src, const AttributeValue_t &dest, float flBlend, float flBalanceFilter = 0.5f )
  67. {
  68. if ( bTransform )
  69. {
  70. BlendTransformValues( pResult, src, dest, flBlend );
  71. }
  72. else
  73. {
  74. BlendFlexValues( pResult, src, dest, flBlend, flBalanceFilter );
  75. }
  76. }
  77. //-----------------------------------------------------------------------------
  78. // The panel used to do text entry when double-clicking in the slider
  79. //-----------------------------------------------------------------------------
  80. class CAttributeSliderTextEntry : public TextEntry
  81. {
  82. DECLARE_CLASS_SIMPLE( CAttributeSliderTextEntry, TextEntry );
  83. public:
  84. CAttributeSliderTextEntry( CAttributeSlider *slider, const char *panelName ) :
  85. BaseClass( (Panel *)slider, panelName ), m_pSlider( slider )
  86. {
  87. Assert( m_pSlider );
  88. }
  89. MESSAGE_FUNC_PARAMS( OnKillFocus, "KillFocus", kv );
  90. virtual void OnMouseWheeled( int delta );
  91. private:
  92. CAttributeSlider *m_pSlider;
  93. };
  94. //-----------------------------------------------------------------------------
  95. //
  96. // CAttributeSlider begins here
  97. //
  98. //-----------------------------------------------------------------------------
  99. //-----------------------------------------------------------------------------
  100. // Constructor, destructor
  101. //-----------------------------------------------------------------------------
  102. CAttributeSlider::CAttributeSlider( CBaseAnimSetAttributeSliderPanel *parent ) :
  103. BaseClass( (Panel *)parent, "" ),
  104. m_pParent( parent ),
  105. m_flFaderAmount( 1.0f ),
  106. m_bDependent( false ),
  107. m_pTextField( 0 ),
  108. m_pRightTextField( 0 ),
  109. m_nVisibleComponents( LOG_COMPONENTS_ALL )
  110. {
  111. SetPaintBackgroundEnabled( true );
  112. SetPaintBorderEnabled( false );
  113. SetBgColor( Color( 42, 42, 42, 255 ) );
  114. m_pName = new TextImage( "" );
  115. m_pValues[ 0 ] = new TextImage( "" );
  116. m_pValues[ 1 ] = new TextImage( "" );
  117. m_pValues[ 2 ] = new TextImage( "" );
  118. m_pValues[ 3 ] = new TextImage( "" );
  119. SetSize( 100, 20 );
  120. }
  121. void CAttributeSlider::Init( CDmElement *control, bool bOrientation )
  122. {
  123. SetName( control->GetName() );
  124. m_SliderMode = SLIDER_MODE_NONE;
  125. m_hControl = control;
  126. m_bTransform = false;
  127. m_bOrientation = false;
  128. // Cache off control information since this state should never change
  129. // NOTE: If it ever does, just change the implementations of
  130. // IsTransform + GetMidpoint to always read these values from the attributes
  131. CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( control );
  132. if ( pTransformControl )
  133. {
  134. m_bTransform = true;
  135. m_bOrientation = bOrientation;
  136. }
  137. m_bStereo = IsStereoControl( control );
  138. m_nDragStartPosition[ 0 ] = m_nDragStartPosition[ 1 ] = 0;
  139. m_nAccum[ 0 ] = m_nAccum[ 1 ] = 0;
  140. m_dragStartValues = GetValue();
  141. SetPaintBackgroundEnabled( true );
  142. if ( m_bTransform )
  143. {
  144. m_pName->SetText( CFmtStr( m_bOrientation ? "%s - rot" : "%s - pos", control->GetName() ) );
  145. }
  146. else
  147. {
  148. m_pName->SetText( control->GetName() );
  149. }
  150. m_pName->ResizeImageToContent();
  151. InitControls();
  152. }
  153. CAttributeSlider::~CAttributeSlider()
  154. {
  155. delete m_pName;
  156. delete m_pValues[ 0 ];
  157. delete m_pValues[ 1 ];
  158. delete m_pValues[ 2 ];
  159. delete m_pValues[ 3 ];
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Scheme
  163. //-----------------------------------------------------------------------------
  164. void CAttributeSlider::ApplySchemeSettings( IScheme *scheme )
  165. {
  166. BaseClass::ApplySchemeSettings( scheme );
  167. m_pName->SetFont( scheme->GetFont( "Default" ) );
  168. m_pName->SetColor( s_TextColor );
  169. m_pName->ResizeImageToContent();
  170. m_pValues[ 0 ]->SetColor( s_TextColor );
  171. m_pValues[ 0 ]->SetFont( scheme->GetFont( "Default" ) );
  172. m_pValues[ 1 ]->SetColor( s_TextColorFocus );
  173. m_pValues[ 1 ]->SetFont( scheme->GetFont( "Default" ) );
  174. m_pValues[ 2 ]->SetColor( s_TextColor );
  175. m_pValues[ 2 ]->SetFont( scheme->GetFont( "Default" ) );
  176. m_pValues[ 3 ]->SetColor( s_TextColor );
  177. m_pValues[ 3 ]->SetFont( scheme->GetFont( "Default" ) );
  178. SetBgColor( Color( 42, 42, 42, 255 ) );
  179. SetFgColor( Color( 194, 120, 0, 255 ) );
  180. }
  181. void CAttributeSlider::InitControls()
  182. {
  183. if ( m_bTransform )
  184. {
  185. CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( m_hControl );
  186. if ( pTransformControl )
  187. {
  188. if ( m_bOrientation )
  189. {
  190. SetValue( ANIM_CONTROL_TXFORM_ORIENTATION, pTransformControl->GetOrientation() );
  191. }
  192. else
  193. {
  194. SetValue( ANIM_CONTROL_TXFORM_POSITION, pTransformControl->GetPosition() );
  195. }
  196. }
  197. }
  198. else
  199. {
  200. if ( m_bStereo )
  201. {
  202. SetValue( ANIM_CONTROL_VALUE_LEFT, m_hControl->GetValue< float >( "leftValue" ) );
  203. SetValue( ANIM_CONTROL_VALUE_RIGHT, m_hControl->GetValue< float >( "rightValue" ) );
  204. }
  205. else
  206. {
  207. SetValue( ANIM_CONTROL_VALUE, m_hControl->GetValue< float >( "value" ) );
  208. }
  209. }
  210. }
  211. void CAttributeSlider::SetValue( AnimationControlType_t type, float flValue )
  212. {
  213. Assert( type < ANIM_CONTROL_COUNT );
  214. if ( m_Control.m_pValue[type] != flValue )
  215. {
  216. m_Control.m_pValue[type] = flValue;
  217. }
  218. }
  219. void CAttributeSlider::SetValue( const AttributeValue_t& value )
  220. {
  221. for ( int i = 0; i < ANIM_CONTROL_COUNT; ++i )
  222. {
  223. SetValue( (AnimationControlType_t)i, value.m_pValue[i] );
  224. }
  225. SetValue( ANIM_CONTROL_TXFORM_POSITION, value.m_Vector );
  226. SetValue( ANIM_CONTROL_TXFORM_ORIENTATION, value.m_Quaternion );
  227. }
  228. void CAttributeSlider::SetValue( AnimationControlType_t type, const Vector &vec )
  229. {
  230. Assert( type == ANIM_CONTROL_TXFORM_POSITION );
  231. if ( m_Control.m_Vector != vec )
  232. {
  233. m_Control.m_Vector = vec;
  234. }
  235. }
  236. void CAttributeSlider::SetValue( AnimationControlType_t type, const Quaternion &quat )
  237. {
  238. Assert( type == ANIM_CONTROL_TXFORM_ORIENTATION );
  239. if ( m_Control.m_Quaternion != quat )
  240. {
  241. m_Control.m_Quaternion = quat;
  242. }
  243. }
  244. const AttributeValue_t& CAttributeSlider::GetValue() const
  245. {
  246. return m_Control;
  247. }
  248. float CAttributeSlider::GetValue( AnimationControlType_t type ) const
  249. {
  250. Assert( type < ANIM_CONTROL_COUNT );
  251. return m_Control.m_pValue[type];
  252. }
  253. void CAttributeSlider::GetValue( AnimationControlType_t type, Vector &out ) const
  254. {
  255. Assert( type == ANIM_CONTROL_TXFORM_POSITION );
  256. out = m_Control.m_Vector;
  257. }
  258. void CAttributeSlider::GetValue( AnimationControlType_t type, Quaternion &out ) const
  259. {
  260. Assert( type == ANIM_CONTROL_TXFORM_ORIENTATION );
  261. out = m_Control.m_Quaternion;
  262. }
  263. float CAttributeSlider::GetPreview( AnimationControlType_t type ) const
  264. {
  265. Assert( type < ANIM_CONTROL_COUNT );
  266. return m_PreviewCurrent.m_pValue[type];
  267. }
  268. void CAttributeSlider::GetPreview( AnimationControlType_t type, Vector &out ) const
  269. {
  270. Assert( type == ANIM_CONTROL_TXFORM_POSITION );
  271. out = m_PreviewCurrent.m_Vector;
  272. }
  273. void CAttributeSlider::GetPreview( AnimationControlType_t type, Quaternion &out ) const
  274. {
  275. Assert( type == ANIM_CONTROL_TXFORM_ORIENTATION );
  276. out = m_PreviewCurrent.m_Quaternion;
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Purpose: Set the flags controlling which specific components of the slider
  280. // are visible.
  281. //-----------------------------------------------------------------------------
  282. void CAttributeSlider::SetVisibleComponents( LogComponents_t componentFlags )
  283. {
  284. m_nVisibleComponents = componentFlags;
  285. }
  286. //-----------------------------------------------------------------------------
  287. // Purpose: Get the set of flags specifying which components of the slider are
  288. // visible.
  289. //-----------------------------------------------------------------------------
  290. LogComponents_t CAttributeSlider::VisibleComponents() const
  291. {
  292. return m_nVisibleComponents;
  293. }
  294. void CAttributeSlider::OnCursorEntered()
  295. {
  296. if ( IsDragging() )
  297. return;
  298. BaseClass::OnCursorEntered();
  299. m_pParent->GetController()->SetActiveAttributeSlider( this );
  300. }
  301. void CAttributeSlider::OnCursorExited()
  302. {
  303. if ( IsDragging() )
  304. return;
  305. BaseClass::OnCursorExited();
  306. m_pParent->GetController()->SetActiveAttributeSlider( NULL );
  307. }
  308. void CAttributeSlider::SetToDefault()
  309. {
  310. if ( m_bTransform )
  311. {
  312. if ( m_bOrientation )
  313. {
  314. const Quaternion &quat = m_hControl->GetValue< Quaternion >( DEFAULT_ORIENTATION_ATTR );
  315. SetValue( ANIM_CONTROL_TXFORM_ORIENTATION, quat );
  316. CUndoScopeGuard guard( "Set Slider Value To Default" );
  317. StampValueIntoLogs( ANIM_CONTROL_TXFORM_ORIENTATION, quat );
  318. }
  319. else
  320. {
  321. const Vector &vec = m_hControl->GetValue< Vector >( DEFAULT_POSITION_ATTR );
  322. SetValue( ANIM_CONTROL_TXFORM_POSITION, vec );
  323. CUndoScopeGuard guard( "Set Slider Value To Default" );
  324. StampValueIntoLogs( ANIM_CONTROL_TXFORM_POSITION, vec );
  325. }
  326. }
  327. else
  328. {
  329. float flDefaultValue = m_hControl->GetValue< float >( DEFAULT_FLOAT_ATTR );
  330. if ( m_bStereo )
  331. {
  332. SetValue( ANIM_CONTROL_VALUE_LEFT, flDefaultValue );
  333. SetValue( ANIM_CONTROL_VALUE_RIGHT, flDefaultValue );
  334. CUndoScopeGuard guard( "Set Slider Value To Default" );
  335. StampValueIntoLogs( ANIM_CONTROL_VALUE_LEFT, flDefaultValue );
  336. StampValueIntoLogs( ANIM_CONTROL_VALUE_RIGHT, flDefaultValue );
  337. }
  338. else
  339. {
  340. SetValue( ANIM_CONTROL_VALUE, flDefaultValue );
  341. CUndoScopeGuard guard( "Set Slider Value To Default" );
  342. StampValueIntoLogs( ANIM_CONTROL_VALUE, flDefaultValue );
  343. }
  344. }
  345. }
  346. void CAttributeSlider::OnSetToDefault()
  347. {
  348. SetToDefault();
  349. }
  350. void CAttributeSlider::OnEditMinMaxDefault()
  351. {
  352. CDmeChannel *pChannel = m_hControl->GetValueElement< CDmeChannel >( "channel" );
  353. if ( !pChannel )
  354. return;
  355. CDmeExpressionOperator *pExpr = CastElement< CDmeExpressionOperator >( pChannel->GetToElement() );
  356. if ( !pExpr )
  357. return;
  358. if ( m_bStereo )
  359. return;
  360. float flMin = pExpr->GetValue< float >( "lo" );
  361. float flMax = pExpr->GetValue< float >( "hi" );
  362. float flDefault = m_hControl->GetValue< float >( "defaultValue" );
  363. flDefault = flMin + flDefault * ( flMax - flMin );
  364. MultiInputDialog *pDialog = new MultiInputDialog( this, "Edit Min/Max/Default" );
  365. pDialog->AddEntry( "min", "Min:", flMin );
  366. pDialog->AddEntry( "max", "Max:", flMax );
  367. pDialog->AddEntry( "default", "Default:", flDefault );
  368. pDialog->DoModal();
  369. }
  370. void CAttributeSlider::OnInputCompleted( KeyValues *params )
  371. {
  372. CDmeChannel *pChannel = m_hControl->GetValueElement< CDmeChannel >( "channel" );
  373. if ( !pChannel )
  374. return;
  375. CDmeExpressionOperator *pExpr = CastElement< CDmeExpressionOperator >( pChannel->GetToElement() );
  376. if ( !pExpr )
  377. return;
  378. m_pParent->GetController()->OnSliderRangeRemapped();
  379. float flOldMin = pExpr->GetValue< float >( "lo" );
  380. float flOldMax = pExpr->GetValue< float >( "hi" );
  381. float flOldValue = m_hControl->GetValue< float >( "value" );
  382. flOldValue = flOldMin + flOldValue * ( flOldMax - flOldMin );
  383. float flMin = params->GetFloat( "min" );
  384. float flMax = params->GetFloat( "max" );
  385. float flDefault = params->GetFloat( "default" );
  386. flDefault = ( flDefault - flMin ) / ( flMax - flMin );
  387. flOldValue = ( flOldValue - flMin ) / ( flMax - flMin );
  388. CUndoScopeGuard sg( "Set Control Min/Max/Default" );
  389. pExpr->SetValue( "lo", flMin );
  390. pExpr->SetValue( "hi", flMax );
  391. m_hControl->SetValue( "defaultValue", clamp( flDefault, 0.0f, 1.0f ) );
  392. m_hControl->SetValue( "value", clamp( flOldValue, 0.0f, 1.0f ) );
  393. float flBias = ( flOldMin - flMin ) / ( flMax - flMin );
  394. float flScale = ( flOldMax - flOldMin ) / ( flMax - flMin );
  395. RemapFloatLogValues( pChannel, flBias, flScale );
  396. }
  397. //-----------------------------------------------------------------------------
  398. // Mouse event handlers
  399. //-----------------------------------------------------------------------------
  400. void CAttributeSlider::OnMousePressed( MouseCode code )
  401. {
  402. if ( !IsEnabled() || IsInTextEntry() || IsDragging() )
  403. return;
  404. if ( code != MOUSE_LEFT )
  405. return;
  406. // Cache off the value at the click point
  407. // in case we end up receiving a double-click
  408. m_pParent->GetTypeInValueForControl( m_hControl, m_bOrientation, m_InitialTextEntryValue, m_Control );
  409. if ( m_bTransform )
  410. return;
  411. // Determine which control we clicked on
  412. int x,y;
  413. input()->GetCursorPosition( x, y );
  414. ScreenToLocal( x, y );
  415. // Enter drag mode
  416. m_SliderMode = SLIDER_MODE_DRAG_VALUE;
  417. m_nDragStartPosition[ 0 ] = x;
  418. m_nDragStartPosition[ 1 ] = y;
  419. m_nAccum[ 0 ] = m_nAccum[ 1 ] = 0;
  420. m_dragStartValues = GetValue();
  421. input()->SetMouseCapture( GetVPanel() );
  422. SetCursor( dc_blank );
  423. }
  424. void CAttributeSlider::OnCursorMoved( int x, int y )
  425. {
  426. if ( !IsEnabled() || !IsDragging() || m_bTransform )
  427. return;
  428. // NOTE: This works because we always slam the mouse to be back at the start position
  429. // at the end of this function
  430. // Accumulate the total mouse movement
  431. int dx = x - m_nDragStartPosition[ 0 ];
  432. m_nAccum[ 0 ] += dx;
  433. float flFactor = 1.0f;
  434. if ( ifm_attributeslider_legacy.GetBool() )
  435. {
  436. flFactor = FRAC_PER_PIXEL * ifm_attributeslider_sensitivity.GetFloat();
  437. }
  438. else
  439. {
  440. Rect_t rect;
  441. GetControlRect( &rect ); // assumes controls are same width
  442. if ( rect.width > 0 )
  443. {
  444. flFactor = 1.0f / (float)rect.width;
  445. }
  446. }
  447. bool bInRecordMode = m_pParent->GetEditor()->GetController()->GetRecordingState() == AS_RECORD;
  448. float flMinVal = bInRecordMode ? -1.0f : 0.0f;
  449. float flMaxVal = bInRecordMode ? 2.0f : 1.0f;
  450. if ( m_bStereo )
  451. {
  452. float flBalance = m_pParent->GetBalanceSliderValue();
  453. float flLeftValue = m_dragStartValues.m_pValue[ ANIM_CONTROL_VALUE_LEFT ];
  454. float flRightValue = m_dragStartValues.m_pValue[ ANIM_CONTROL_VALUE_RIGHT ];
  455. int nMinVal = floor( ( flMinVal - MAX( flLeftValue, flRightValue ) ) / flFactor );
  456. int nMaxVal = ceil ( ( flMaxVal - MIN( flLeftValue, flRightValue ) ) / flFactor );
  457. m_nAccum[ 0 ] = clamp( m_nAccum[ 0 ], nMinVal, nMaxVal );
  458. float flDelta = flFactor * m_nAccum[ 0 ];
  459. float flLeftDelta, flRightDelta;
  460. ValueBalanceToLeftRight( &flLeftDelta, &flRightDelta, flDelta, flBalance, 0.0f );
  461. flLeftValue = clamp( flLeftValue + flLeftDelta, flMinVal, flMaxVal );
  462. flRightValue = clamp( flRightValue + flRightDelta, flMinVal, flMaxVal );
  463. SetValue( ANIM_CONTROL_VALUE_LEFT, flLeftValue );
  464. SetValue( ANIM_CONTROL_VALUE_RIGHT, flRightValue );
  465. }
  466. else
  467. {
  468. AnimationControlType_t type = ANIM_CONTROL_VALUE;
  469. float flValue = m_dragStartValues.m_pValue[ type ];
  470. int nMinVal = floor( ( flMinVal - flValue ) / flFactor );
  471. int nMaxVal = ceil ( ( flMaxVal - flValue ) / flFactor );
  472. m_nAccum[ 0 ] = clamp( m_nAccum[ 0 ], nMinVal, nMaxVal );
  473. float flDelta = flFactor * m_nAccum[ 0 ];
  474. flValue = clamp( flValue + flDelta, flMinVal, flMaxVal );
  475. SetValue( type, flValue );
  476. }
  477. // Slam the cursor back to the drag start point
  478. if ( x != m_nDragStartPosition[ 0 ] || y != m_nDragStartPosition[ 1 ] )
  479. {
  480. x = m_nDragStartPosition[ 0 ];
  481. y = m_nDragStartPosition[ 1 ];
  482. LocalToScreen( x, y );
  483. input()->SetCursorPos( x, y );
  484. }
  485. }
  486. void CAttributeSlider::OnMouseReleased( MouseCode code )
  487. {
  488. if ( !IsEnabled() || m_bTransform )
  489. return;
  490. if ( code == MOUSE_RIGHT )
  491. {
  492. if ( m_hContextMenu.Get() )
  493. {
  494. delete m_hContextMenu.Get();
  495. m_hContextMenu = NULL;
  496. }
  497. m_hContextMenu = new Menu( this, "ActionMenu" );
  498. int x,y;
  499. input()->GetCursorPosition( x, y );
  500. ScreenToLocal( x, y );
  501. m_hContextMenu->AddMenuItem( "Set To Default", new KeyValues( "SetToDefault" ), this );
  502. if ( CDmeChannel *pChannel = m_hControl->GetValueElement< CDmeChannel >( "channel" ) )
  503. {
  504. CDmElement *pToElement = pChannel->GetToElement();
  505. if ( pToElement && pToElement->IsA< CDmeExpressionOperator >() )
  506. {
  507. m_hContextMenu->AddMenuItem( "Edit Min/Max/Default...", new KeyValues( "EditMinMaxDefault" ), this );
  508. }
  509. }
  510. Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
  511. return;
  512. }
  513. if ( !IsDragging() )
  514. return;
  515. m_SliderMode = SLIDER_MODE_NONE;
  516. input()->SetMouseCapture( NULL );
  517. SetCursor( dc_arrow );
  518. m_pParent->UpdatePreview( "Attribute Slider Released" );
  519. }
  520. //-----------------------------------------------------------------------------
  521. //
  522. // Methods related to text entry mode
  523. //
  524. //-----------------------------------------------------------------------------
  525. //-----------------------------------------------------------------------------
  526. // Called by the text entry code to enter the value into the logs
  527. //-----------------------------------------------------------------------------
  528. void CAttributeSlider::StampValueIntoLogs( AnimationControlType_t type, float flValue )
  529. {
  530. Assert( !m_bTransform );
  531. Assert( type < ANIM_CONTROL_COUNT );
  532. m_pParent->StampValueIntoLogs( m_hControl, type, flValue );
  533. }
  534. void CAttributeSlider::StampValueIntoLogs( AnimationControlType_t type, const Vector &vecValue )
  535. {
  536. Assert( m_bTransform );
  537. Assert( type == ANIM_CONTROL_TXFORM_POSITION || type == ANIM_CONTROL_TXFORM_ORIENTATION );
  538. m_pParent->StampValueIntoLogs( m_hControl, type, vecValue );
  539. }
  540. void CAttributeSlider::StampValueIntoLogs( AnimationControlType_t type, const Quaternion &qValue )
  541. {
  542. Assert( m_bTransform );
  543. Assert( type == ANIM_CONTROL_TXFORM_ORIENTATION );
  544. m_pParent->StampValueIntoLogs( m_hControl, type, qValue );
  545. }
  546. //-----------------------------------------------------------------------------
  547. // Key typed key handler
  548. //-----------------------------------------------------------------------------
  549. void CAttributeSlider::OnKeyCodeTyped( KeyCode code )
  550. {
  551. if ( !IsInTextEntry() )
  552. {
  553. BaseClass::OnKeyCodeTyped( code );
  554. return;
  555. }
  556. switch ( code )
  557. {
  558. default:
  559. BaseClass::OnKeyCodeTyped( code );
  560. break;
  561. case KEY_ESCAPE:
  562. DiscardTextEntryValue();
  563. break;
  564. case KEY_ENTER:
  565. AcceptTextEntryValue();
  566. break;
  567. }
  568. }
  569. void CAttributeSlider::SetupTextFieldForTextEntryMode( CAttributeSliderTextEntry *&pTextField, const char *pText, bool bRequestFocus )
  570. {
  571. if ( !pTextField )
  572. {
  573. pTextField = new CAttributeSliderTextEntry( this, GetName() );
  574. pTextField->SetVisible( false );
  575. pTextField->SetEnabled( false );
  576. pTextField->SelectAllOnFocusAlways( true );
  577. InvalidateLayout();
  578. }
  579. pTextField->SetVisible( true );
  580. pTextField->SetEnabled( true );
  581. pTextField->SetText( pText );
  582. pTextField->GotoTextEnd();
  583. if ( bRequestFocus )
  584. {
  585. pTextField->RequestFocus();
  586. }
  587. }
  588. //-----------------------------------------------------------------------------
  589. // Methods to entry text entry mode
  590. //-----------------------------------------------------------------------------
  591. void CAttributeSlider::EnterTextEntryMode( bool bRelatchValues )
  592. {
  593. m_SliderMode = SLIDER_MODE_TEXT;
  594. // For double-clicking, ignore the value set by the first single mouse click
  595. if ( !bRelatchValues )
  596. {
  597. SetValue( m_InitialTextEntryValue );
  598. }
  599. if ( !IsTransform() )
  600. {
  601. if ( m_bStereo )
  602. {
  603. char val[ 64 ];
  604. V_snprintf( val, sizeof( val ), "%f", m_InitialTextEntryValue.m_pValue[ ANIM_CONTROL_VALUE_LEFT ] );
  605. SetupTextFieldForTextEntryMode( m_pTextField, val, true );
  606. V_snprintf( val, sizeof( val ), "%f", m_InitialTextEntryValue.m_pValue[ ANIM_CONTROL_VALUE_RIGHT ] );
  607. SetupTextFieldForTextEntryMode( m_pRightTextField, val, false );
  608. }
  609. else
  610. {
  611. char val[ 64 ];
  612. Q_snprintf( val, sizeof( val ), "%f", m_InitialTextEntryValue.m_pValue[ ANIM_CONTROL_VALUE ] );
  613. SetupTextFieldForTextEntryMode( m_pTextField, val, true );
  614. }
  615. }
  616. else
  617. {
  618. char val[ 128 ];
  619. Q_snprintf( val, sizeof( val ), "%f %f %f", VectorExpand( m_InitialTextEntryValue.m_Vector ) );
  620. SetupTextFieldForTextEntryMode( m_pTextField, val, true );
  621. }
  622. }
  623. //-----------------------------------------------------------------------------
  624. // Methods to accept or discard the value in the text entry field
  625. //-----------------------------------------------------------------------------
  626. void CAttributeSlider::AcceptTextEntryValue()
  627. {
  628. if ( !IsInTextEntry() )
  629. return;
  630. // Get the value in the text entry field
  631. char buf[ 64 ];
  632. m_pTextField->GetText( buf, sizeof( buf ) );
  633. // Hide the text entry
  634. m_pTextField->SetVisible( false );
  635. m_pTextField->SetEnabled( false );
  636. CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( m_hControl );
  637. if ( !IsTransform() )
  638. {
  639. float flValue = Q_atof( buf );
  640. if ( m_bStereo )
  641. {
  642. float flLeftValue = flValue;
  643. SetValue( ANIM_CONTROL_VALUE_LEFT, flLeftValue );
  644. StampValueIntoLogs( ANIM_CONTROL_VALUE_LEFT, flLeftValue );
  645. // Get the value in the text entry field
  646. char buf[ 64 ];
  647. m_pRightTextField->GetText( buf, sizeof( buf ) );
  648. float flRightValue = Q_atof( buf );
  649. // Hide the text entry
  650. m_pRightTextField->SetVisible( false );
  651. m_pRightTextField->SetEnabled( false );
  652. SetValue( ANIM_CONTROL_VALUE_RIGHT, flRightValue );
  653. StampValueIntoLogs( ANIM_CONTROL_VALUE_RIGHT, flRightValue );
  654. }
  655. else
  656. {
  657. SetValue( ANIM_CONTROL_VALUE, flValue );
  658. StampValueIntoLogs( ANIM_CONTROL_VALUE, flValue );
  659. }
  660. }
  661. else if ( pTransformControl )
  662. {
  663. Vector vecValue;
  664. if ( 3 == sscanf( buf, "%f %f %f", &vecValue.x, &vecValue.y, &vecValue.z ) )
  665. {
  666. if ( !m_bOrientation )
  667. {
  668. SetValue( ANIM_CONTROL_TXFORM_POSITION, vecValue );
  669. StampValueIntoLogs( ANIM_CONTROL_TXFORM_POSITION, vecValue );
  670. }
  671. else
  672. {
  673. StampValueIntoLogs( ANIM_CONTROL_TXFORM_ORIENTATION, vecValue );
  674. SetValue( ANIM_CONTROL_TXFORM_ORIENTATION, pTransformControl->GetOrientation() );
  675. /*
  676. QAngle angValue;
  677. if ( 3 == sscanf( buf, "%f %f %f", &angValue.x, &angValue.y, &angValue.z ) )
  678. {
  679. // Convert back to a quat
  680. Quaternion qValue;
  681. AngleQuaternion( angValue, qValue );
  682. SetValue( ANIM_CONTROL_TXFORM_ORIENTATION, qValue );
  683. StampValueIntoLogs( ANIM_CONTROL_TXFORM_ORIENTATION, qValue );
  684. }
  685. */
  686. }
  687. }
  688. m_pParent->UpdatePreview( "AcceptTextEntryValue\n" );
  689. }
  690. m_SliderMode = SLIDER_MODE_NONE;
  691. RequestFocus();
  692. }
  693. void CAttributeSlider::DiscardTextEntryValue()
  694. {
  695. if ( !IsInTextEntry() )
  696. return;
  697. // Hide the text entry
  698. m_pTextField->SetVisible( false );
  699. m_pTextField->SetEnabled( false );
  700. if ( m_bStereo )
  701. {
  702. m_pRightTextField->SetVisible( false );
  703. m_pRightTextField->SetEnabled( false );
  704. }
  705. m_SliderMode = SLIDER_MODE_NONE;
  706. RequestFocus();
  707. }
  708. //-----------------------------------------------------------------------------
  709. // Methods of the text entry widget
  710. //-----------------------------------------------------------------------------
  711. void CAttributeSliderTextEntry::OnKillFocus( KeyValues *pParams )
  712. {
  713. Assert( m_pSlider );
  714. SelectNone();
  715. VPANEL hPanel = (VPANEL)pParams->GetPtr( "newPanel" );
  716. if ( hPanel != INVALID_PANEL && vgui::ipanel()->GetParent( hPanel ) == m_pSlider->GetVPanel() )
  717. return;
  718. m_pSlider->AcceptTextEntryValue();
  719. }
  720. void CAttributeSliderTextEntry::OnMouseWheeled( int delta )
  721. {
  722. if ( m_pSlider->IsTransform() )
  723. return;
  724. if ( m_pSlider->IsStereo() )
  725. return;
  726. float deltaFactor;
  727. if ( input()->IsKeyDown(KEY_LSHIFT) )
  728. {
  729. deltaFactor = ((float)delta) * 10.0f;
  730. }
  731. else if ( input()->IsKeyDown(KEY_LCONTROL) )
  732. {
  733. deltaFactor = ((float)delta) / 100.0;
  734. }
  735. else
  736. {
  737. deltaFactor = ((float)delta) / 10.0;
  738. }
  739. char sz[ 64 ];
  740. GetText( sz, sizeof( sz ) );
  741. float val = Q_atof( sz ) + deltaFactor;
  742. if ( input()->IsKeyDown(KEY_LALT) )
  743. {
  744. val = clamp( val, 0.0f, 1.0f );
  745. }
  746. Q_snprintf( sz, sizeof( sz ), "%f", val );
  747. SetText( sz );
  748. m_pSlider->SetValue( ANIM_CONTROL_VALUE, val );
  749. CUndoScopeGuard guard( UNDO_CHAIN_MOUSEWHEEL_ATTRIBUTE_SLIDER, "Set Slider Value" );
  750. m_pSlider->StampValueIntoLogs( ANIM_CONTROL_VALUE, val );
  751. }
  752. void CAttributeSlider::OnMouseDoublePressed( MouseCode code )
  753. {
  754. if ( !IsEnabled() || IsDragging() )
  755. return;
  756. if ( code != MOUSE_LEFT )
  757. return;
  758. int x,y;
  759. input()->GetCursorPosition( x, y );
  760. ScreenToLocal( x, y );
  761. EnterTextEntryMode( false );
  762. }
  763. //-----------------------------------------------------------------------------
  764. //
  765. // Methods related to preview
  766. //
  767. //-----------------------------------------------------------------------------
  768. void CAttributeSlider::UpdateFaderAmount( float flAmount )
  769. {
  770. m_flFaderAmount = flAmount;
  771. BlendValues( m_bTransform, &m_PreviewCurrent, GetValue(), m_PreviewFull, flAmount );
  772. }
  773. void CAttributeSlider::SetPreview( const AttributeValue_t &value, const AttributeValue_t &full )
  774. {
  775. m_PreviewCurrent = value;
  776. m_PreviewFull = full;
  777. }
  778. const AttributeValue_t &CAttributeSlider::GetPreview() const
  779. {
  780. return m_PreviewCurrent;
  781. }
  782. const AttributeValue_t &CAttributeSlider::GetPreviewFull() const
  783. {
  784. return m_PreviewFull;
  785. }
  786. // Estimates the value of the control given a local coordinate
  787. float CAttributeSlider::EstimateValueAtPos( int nLocalX, int nLocalY ) const
  788. {
  789. Rect_t rect;
  790. GetControlRect( &rect ); // assumes controls are same width
  791. float flFactor = rect.width > 1 ? (float)( nLocalX - rect.x ) / (float)( rect.width - 1 ) : 0.5f;
  792. flFactor = clamp( flFactor, 0.0f, 1.0f );
  793. return flFactor;
  794. }
  795. //-----------------------------------------------------------------------------
  796. // Layout
  797. //-----------------------------------------------------------------------------
  798. void CAttributeSlider::PerformLayout()
  799. {
  800. BaseClass::PerformLayout();
  801. if ( !m_pTextField )
  802. return;
  803. Rect_t rect;
  804. GetControlRect( &rect );
  805. // Place the text entry along the main attribute track rectangle
  806. if ( m_bStereo )
  807. {
  808. m_pTextField ->SetBounds( rect.x, rect.y, rect.width / 2, rect.height );
  809. m_pRightTextField->SetBounds( rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height );
  810. }
  811. else
  812. {
  813. m_pTextField->SetBounds( rect.x, rect.y, rect.width, rect.height );
  814. }
  815. }
  816. void CAttributeSlider::GetControlRect( Rect_t *pRect ) const
  817. {
  818. int sw, sh;
  819. const_cast<CAttributeSlider*>( this )->GetSize( sw, sh );
  820. pRect->x = 2 * SLIDER_PIXEL_SPACING;
  821. pRect->y = SLIDER_PIXEL_SPACING;
  822. pRect->width = sw - pRect->x * 2;
  823. pRect->height = MAX( 0, sh - SLIDER_PIXEL_SPACING * 2 );
  824. }
  825. //-----------------------------------------------------------------------------
  826. //
  827. // Methods related to painting start here
  828. //
  829. //-----------------------------------------------------------------------------
  830. //-----------------------------------------------------------------------------
  831. // Used to control how fader-driven ticks look
  832. //-----------------------------------------------------------------------------
  833. float CAttributeSlider::GetPreviewAlphaScale() const
  834. {
  835. return MAX( m_flFaderAmount, 0.1f );
  836. }
  837. //-----------------------------------------------------------------------------
  838. // Draws a tick on the main control
  839. //-----------------------------------------------------------------------------
  840. void DrawTick( float flValue, int xbase, int nTotalWidth, int nTickWidth, int y, int nHeight )
  841. {
  842. int x = xbase + (int)( flValue * (float)nTotalWidth + 0.5f ) - nTickWidth / 2;
  843. x = clamp( x, xbase, xbase + nTotalWidth - nTickWidth );
  844. surface()->DrawFilledRect( x, y, x + nTickWidth, y + nHeight );
  845. }
  846. void CAttributeSlider::DrawTick( const Color& clr, const AttributeValue_t &value, int width, int inset )
  847. {
  848. surface()->DrawSetColor( clr );
  849. // Get the control position
  850. Rect_t rect;
  851. GetControlRect( &rect );
  852. // Inset by 1 pixel
  853. rect.x++; rect.y++; rect.width -= 2; rect.height -= 2;
  854. int previewtall = rect.height - 2 * inset;
  855. int ypos = rect.y + ( rect.height - previewtall ) / 2;
  856. if ( m_bStereo )
  857. {
  858. previewtall /= 2;
  859. ::DrawTick( value.m_pValue[ ANIM_CONTROL_VALUE_LEFT ], rect.x, rect.width, width, ypos, previewtall );
  860. ::DrawTick( value.m_pValue[ ANIM_CONTROL_VALUE_RIGHT ], rect.x, rect.width, width, ypos + previewtall, previewtall );
  861. }
  862. else
  863. {
  864. ::DrawTick( value.m_pValue[ ANIM_CONTROL_VALUE ], rect.x, rect.width, width, ypos + previewtall, previewtall );
  865. }
  866. }
  867. //-----------------------------------------------------------------------------
  868. // Paints ticks
  869. //-----------------------------------------------------------------------------
  870. void CAttributeSlider::Paint()
  871. {
  872. if ( IsTransform() )
  873. return;
  874. DrawTick( s_OldValueTickColor, GetValue(), 1, 0 );
  875. bool shiftDown = input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT );
  876. bool bPreviewingAttributeSlider = m_pParent->GetController()->GetActiveAttributeSlider() == this && !IsDragging() && shiftDown;
  877. bool bMouseOverPreviewSlider = m_pParent->GetEditor()->GetPresetFader()->GetActivePresetSlider() ? true : false;
  878. if ( bPreviewingAttributeSlider || bMouseOverPreviewSlider )
  879. {
  880. Color col = s_PreviewTickColor;
  881. col[ 3 ] *= GetPreviewAlphaScale();
  882. DrawTick( col, m_PreviewFull, 2, 2 );
  883. }
  884. }
  885. //-----------------------------------------------------------------------------
  886. // Draws the min, current, and max values for the slider
  887. //-----------------------------------------------------------------------------
  888. void CAttributeSlider::DrawValueLabel()
  889. {
  890. if ( IsTransform() )
  891. return;
  892. float flMinVal = 0.0f;
  893. float flMaxVal = 1.0f;
  894. Rect_t rect;
  895. GetControlRect( &rect );
  896. int cw, ch;
  897. char sz[ 32 ];
  898. Q_snprintf( sz, sizeof( sz ), "%.1f", flMinVal );
  899. m_pValues[ 0 ]->SetText( sz );
  900. m_pValues[ 0 ]->ResizeImageToContent();
  901. m_pValues[ 0 ]->GetContentSize( cw, ch );
  902. m_pValues[ 0 ]->SetPos( rect.x + 5, rect.y + ( rect.height - ch ) * 0.5f );
  903. m_pValues[ 0 ]->Paint();
  904. Q_snprintf( sz, sizeof( sz ), "%.1f", flMaxVal );
  905. m_pValues[ 1 ]->SetText( sz );
  906. m_pValues[ 1 ]->ResizeImageToContent();
  907. m_pValues[ 1 ]->GetContentSize( cw, ch );
  908. m_pValues[ 1 ]->SetPos( rect.x + rect.width - cw - 5, rect.y + ( rect.height - ch ) * 0.5f );
  909. m_pValues[ 1 ]->Paint();
  910. if ( m_bStereo )
  911. {
  912. float flLeftValue = clamp( GetValue().m_pValue[ ANIM_CONTROL_VALUE_LEFT ], flMinVal, flMaxVal );
  913. Q_snprintf( sz, sizeof( sz ), "%.3f", flLeftValue );
  914. m_pValues[ 2 ]->SetText( sz );
  915. m_pValues[ 2 ]->ResizeImageToContent();
  916. m_pValues[ 2 ]->GetContentSize( cw, ch );
  917. m_pValues[ 2 ]->SetPos( rect.x + ( rect.width - cw ) * 0.4f, rect.y + ( rect.height - ch ) * 0.5f );
  918. m_pValues[ 2 ]->Paint();
  919. float flRightValue = clamp( GetValue().m_pValue[ ANIM_CONTROL_VALUE_RIGHT ], flMinVal, flMaxVal );
  920. Q_snprintf( sz, sizeof( sz ), "%.3f", flRightValue );
  921. m_pValues[ 3 ]->SetText( sz );
  922. m_pValues[ 3 ]->ResizeImageToContent();
  923. m_pValues[ 3 ]->GetContentSize( cw, ch );
  924. m_pValues[ 3 ]->SetPos( rect.x + ( rect.width - cw ) * 0.6f, rect.y + ( rect.height - ch ) * 0.5f );
  925. m_pValues[ 3 ]->Paint();
  926. }
  927. else
  928. {
  929. float flValue = clamp( GetValue().m_pValue[ ANIM_CONTROL_VALUE ], flMinVal, flMaxVal );
  930. Q_snprintf( sz, sizeof( sz ), "%.3f", flValue );
  931. m_pValues[ 2 ]->SetText( sz );
  932. m_pValues[ 2 ]->ResizeImageToContent();
  933. m_pValues[ 2 ]->GetContentSize( cw, ch );
  934. m_pValues[ 2 ]->SetPos( rect.x + ( rect.width - cw ) * 0.5f, rect.y + ( rect.height - ch ) * 0.5f );
  935. m_pValues[ 2 ]->Paint();
  936. }
  937. }
  938. //-----------------------------------------------------------------------------
  939. // Draws the text for the slider. It's either the slider name, or its value if dragging is happening
  940. //-----------------------------------------------------------------------------
  941. void CAttributeSlider::DrawNameLabel()
  942. {
  943. if ( IsDragging() )
  944. {
  945. DrawValueLabel();
  946. return;
  947. }
  948. if ( IsInTextEntry() )
  949. return;
  950. if ( !m_pName )
  951. return;
  952. int cw, ch;
  953. Color clr = s_TextColor;
  954. if ( m_pParent->GetController()->GetActiveAttributeSlider() == this )
  955. {
  956. clr = s_TextColorFocus;
  957. }
  958. else if ( m_bDependent )
  959. {
  960. clr = s_TextColorDependent;
  961. }
  962. m_pName->SetColor( clr );
  963. m_pName->GetContentSize( cw, ch );
  964. Rect_t rect;
  965. GetControlRect( &rect );
  966. m_pName->SetPos( rect.x + ( rect.width - cw ) * 0.5f, rect.y + ( rect.height - ch ) * 0.5f );
  967. m_pName->Paint();
  968. }
  969. //-----------------------------------------------------------------------------
  970. // Draws the midpoint value for the slider
  971. //-----------------------------------------------------------------------------
  972. void CAttributeSlider::DrawMidpoint( int x, int ty, int ttall )
  973. {
  974. if ( IsTransform() )
  975. return;
  976. surface()->DrawSetColor( s_MidpointColor );
  977. surface()->DrawFilledRect( x, ty, x + 1, ty + ttall );
  978. }
  979. //-----------------------------------------------------------------------------
  980. // Paints the slider
  981. //-----------------------------------------------------------------------------
  982. void CAttributeSlider::PaintBackground()
  983. {
  984. Rect_t rect;
  985. GetControlRect( &rect );
  986. // Paint the border
  987. surface()->DrawSetColor( Color( 24, 24, 24, 255 ) );
  988. // top and left
  989. surface()->DrawOutlinedRect( rect.x, rect.y, rect.x + rect.width, rect.y + 1 );
  990. surface()->DrawOutlinedRect( rect.x, rect.y, rect.x + 1, rect.y + rect.height );
  991. // right
  992. surface()->DrawSetColor( Color( 33, 33, 33, 255 ) );
  993. surface()->DrawOutlinedRect( rect.x + rect.width - 1, rect.y, rect.x + rect.width, rect.y + rect.height );
  994. // bottom
  995. surface()->DrawSetColor( Color( 56, 56, 56, 255 ) );
  996. surface()->DrawOutlinedRect( rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height );
  997. // Inset the rect by 1 pixel
  998. ++rect.x; ++rect.y; rect.width -= 2; rect.height -= 2;
  999. int y0 = rect.y;
  1000. int y1 = rect.y + rect.height / 2;
  1001. int y2 = rect.y + rect.height;
  1002. bool bIsLogPreviewControl = ( m_pParent->GetController()->GetActiveAttributeSlider() == this );
  1003. // Draw the main bar background
  1004. surface()->DrawSetColor( s_ZeroColor[ bIsLogPreviewControl ] );
  1005. surface()->DrawFilledRect( rect.x, y0, rect.x + rect.width, y2 );
  1006. if ( IsInTextEntry() )
  1007. return;
  1008. if ( !IsTransform() )
  1009. {
  1010. CBaseAnimationSetControl *pController = m_pParent->GetController();
  1011. bool shiftDown = input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT );
  1012. bool bPreviewingAttributeSlider = pController->GetActiveAttributeSlider() == this && !IsDragging() && shiftDown;
  1013. bool bDraggingPreviewSlider = pController->IsPresetFaderBeingDragged();
  1014. bool bPreviewingPreset = pController->WasPreviouslyHoldingPresetPreviewKey();
  1015. bool bUsePreview = bPreviewingAttributeSlider || bDraggingPreviewSlider || bPreviewingPreset;
  1016. float flDefaultValue = m_hControl->GetValue< float >( DEFAULT_FLOAT_ATTR );
  1017. int nMidPoint = (int)( (float)rect.width * clamp( flDefaultValue, 0.0f, 1.0f ) + 0.5f );
  1018. if ( m_bStereo )
  1019. {
  1020. const AttributeValue_t &value = bUsePreview ? m_PreviewCurrent : GetValue();
  1021. float flLeftValue = value.m_pValue[ ANIM_CONTROL_VALUE_LEFT ];
  1022. float flRightValue = value.m_pValue[ ANIM_CONTROL_VALUE_RIGHT ];
  1023. int nLeftValue = (int)( (float)rect.width * clamp( flLeftValue, 0.0f, 1.0f ) + 0.5f );
  1024. int nRightValue = (int)( (float)rect.width * clamp( flRightValue, 0.0f, 1.0f ) + 0.5f );
  1025. // Draw the current value as a bar from the midpoint
  1026. surface()->DrawSetColor( IsDragging() ? s_DraggingBarColor : s_BarColor[ bIsLogPreviewControl ] );
  1027. surface()->DrawFilledRect( rect.x + MIN( nLeftValue, nMidPoint ), y0, rect.x + MAX( nLeftValue, nMidPoint ), y1 );
  1028. surface()->DrawFilledRect( rect.x + MIN( nRightValue, nMidPoint ), y1, rect.x + MAX( nRightValue, nMidPoint ), y2 );
  1029. }
  1030. else
  1031. {
  1032. const AttributeValue_t &value = bUsePreview ? m_PreviewCurrent : GetValue();
  1033. float flValue = value.m_pValue[ ANIM_CONTROL_VALUE ];
  1034. int nValue = (int)( (float)rect.width * clamp( flValue, 0.0f, 1.0f ) + 0.5f );
  1035. // Draw the current value as a bar from the midpoint
  1036. surface()->DrawSetColor( IsDragging() ? s_DraggingBarColor : s_BarColor[ bIsLogPreviewControl ] );
  1037. surface()->DrawFilledRect( rect.x + MIN( nValue, nMidPoint ), y0, rect.x + MAX( nValue, nMidPoint ), y2 );
  1038. }
  1039. // Draw the midpoint over the top of the current value
  1040. DrawMidpoint( rect.x + nMidPoint, rect.y, rect.height );
  1041. }
  1042. // Draw the name or value over the top of that
  1043. DrawNameLabel();
  1044. }
  1045. //-----------------------------------------------------------------------------
  1046. // Manipulate in/out curve types
  1047. //-----------------------------------------------------------------------------
  1048. void CAttributeSlider::OnCurve1()
  1049. {
  1050. m_pParent->DispatchCurve( 1 );
  1051. }
  1052. void CAttributeSlider::OnCurve2()
  1053. {
  1054. m_pParent->DispatchCurve( 2 );
  1055. }
  1056. void CAttributeSlider::OnCurve3()
  1057. {
  1058. m_pParent->DispatchCurve( 3 );
  1059. }
  1060. void CAttributeSlider::OnCurve4()
  1061. {
  1062. m_pParent->DispatchCurve( 4 );
  1063. }
  1064. //-----------------------------------------------------------------------------
  1065. //
  1066. // Slider dependency functions, provide management and information about the
  1067. // other sliders on which the function of this slider depends.
  1068. //
  1069. //-----------------------------------------------------------------------------
  1070. //-----------------------------------------------------------------------------
  1071. // Purpose: Clear the list of sliders that this slider is dependent on
  1072. //-----------------------------------------------------------------------------
  1073. void CAttributeSlider::ClearDependencies()
  1074. {
  1075. m_Dependenices.RemoveAll();
  1076. }
  1077. //-----------------------------------------------------------------------------
  1078. // Purpose: Add a slider to the list of sliders this slider is dependent on
  1079. //-----------------------------------------------------------------------------
  1080. bool CAttributeSlider::AddDependency( const CAttributeSlider* pSlider )
  1081. {
  1082. if ( pSlider == NULL )
  1083. return false;
  1084. // Make sure the slider is not already in the dependency list
  1085. if ( m_Dependenices.Find( pSlider ) != m_Dependenices.InvalidIndex() )
  1086. return false;
  1087. m_Dependenices.AddToTail( pSlider );
  1088. return true;
  1089. }
  1090. //-----------------------------------------------------------------------------
  1091. // Purpose: Check the dependency list to see the operation of this slider is
  1092. // dependent of the specified slider.
  1093. //-----------------------------------------------------------------------------
  1094. bool CAttributeSlider::IsDependent( const CAttributeSlider* pSlider ) const
  1095. {
  1096. return ( m_Dependenices.Find( pSlider) != m_Dependenices.InvalidIndex() );
  1097. }
  1098. //-----------------------------------------------------------------------------
  1099. // Purpose: Set the flag indicating that the operation of the slider is
  1100. // dependent on the currently selected slider.
  1101. //-----------------------------------------------------------------------------
  1102. void CAttributeSlider::SetDependent( bool dependent )
  1103. {
  1104. m_bDependent = dependent;
  1105. }