summaryrefslogtreecommitdiff
path: root/vgui2/dme_controls/BaseAnimSetAttributeSliderPanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vgui2/dme_controls/BaseAnimSetAttributeSliderPanel.cpp')
-rw-r--r--vgui2/dme_controls/BaseAnimSetAttributeSliderPanel.cpp1534
1 files changed, 1534 insertions, 0 deletions
diff --git a/vgui2/dme_controls/BaseAnimSetAttributeSliderPanel.cpp b/vgui2/dme_controls/BaseAnimSetAttributeSliderPanel.cpp
new file mode 100644
index 0000000..cc57436
--- /dev/null
+++ b/vgui2/dme_controls/BaseAnimSetAttributeSliderPanel.cpp
@@ -0,0 +1,1534 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "dme_controls/BaseAnimSetAttributeSliderPanel.h"
+#include "movieobjects/dmechannel.h"
+#include "movieobjects/dmeanimationset.h"
+#include "vgui_controls/TextImage.h"
+#include "vgui_controls/Button.h"
+#include "vgui_controls/Slider.h"
+#include "vgui_controls/PanelListPanel.h"
+#include "dme_controls/BaseAnimSetPresetFaderPanel.h"
+#include "dme_controls/BaseAnimationSetEditor.h"
+#include "dme_controls/attributeslider.h"
+#include "vgui/ISurface.h"
+#include "vgui/ISystem.h"
+#include "vgui/IInput.h"
+
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+#define ANIMATION_SET_EDITOR_ATTRIBUTESLIDERS_BUTTONTRAY_HEIGHT 32
+#define ANIMATION_SET_EDITOR_ATTRIBUTESLIDERS_BUTTONTRAY_YPOS 0
+
+//-----------------------------------------------------------------------------
+// Enums
+//-----------------------------------------------------------------------------
+#define SLIDER_PIXEL_SPACING 3
+#define RECOMPUTE_PREVIEW_INTERVAL ( 0.5f )
+#define CIRCULAR_CONTROL_RADIUS 6.0f
+#define FRAC_PER_PIXEL 0.0025f
+
+static ConVar ifm_attributesliderbalance_sensitivity( "ifm_attributesliderbalance_sensitivity", "1.0", 0 );
+
+extern float ifm_fader_timescale;
+
+enum
+{
+ // Just some arbitrary number that we're not likely to see in another .lib or the main app's code
+ UNDO_CHAIN_MOUSEWHEEL_ATTRIBUTE_SLIDER = 9876,
+};
+
+
+bool CBaseAnimSetAttributeSliderPanel::ChannelToSliderLookup_t::Less( const ChannelToSliderLookup_t& lhs, const ChannelToSliderLookup_t& rhs )
+{
+ return lhs.ch.Get() < rhs.ch.Get();
+}
+
+
+//-----------------------------------------------------------------------------
+// Blends flex values in left-right space instead of balance/value space
+//-----------------------------------------------------------------------------
+static void BlendFlexValues( AttributeValue_t *pResult, const AttributeValue_t &src, const AttributeValue_t &dest, float flBlend, float flBalanceFilter = 0.5f )
+{
+ // Apply the left-right balance to the target
+ float flLeftFilter, flRightFilter;
+ ValueBalanceToLeftRight( &flLeftFilter, &flRightFilter, flBlend, flBalanceFilter );
+
+ // Do the math in 'left-right' space because we filter in that space
+ float flSrcLeft, flSrcRight;
+ ValueBalanceToLeftRight( &flSrcLeft, &flSrcRight, src.m_pValue[ANIM_CONTROL_VALUE], src.m_pValue[ANIM_CONTROL_BALANCE] );
+
+ float flDestLeft, flDestRight;
+ ValueBalanceToLeftRight( &flDestLeft, &flDestRight, dest.m_pValue[ANIM_CONTROL_VALUE], dest.m_pValue[ANIM_CONTROL_BALANCE] );
+
+ float flTargetLeft = flSrcLeft + flLeftFilter * ( flDestLeft - flSrcLeft );
+ float flTargetRight = flSrcRight + flRightFilter * ( flDestRight - flSrcRight );
+
+ LeftRightToValueBalance( &pResult->m_pValue[ANIM_CONTROL_VALUE], &pResult->m_pValue[ANIM_CONTROL_BALANCE], flTargetLeft, flTargetRight,
+ ( flBlend <= 0.5f ) ? src.m_pValue[ANIM_CONTROL_BALANCE] : dest.m_pValue[ANIM_CONTROL_BALANCE] );
+
+ pResult->m_pValue[ANIM_CONTROL_MULTILEVEL] = src.m_pValue[ANIM_CONTROL_MULTILEVEL] + ( dest.m_pValue[ANIM_CONTROL_MULTILEVEL] - src.m_pValue[ANIM_CONTROL_MULTILEVEL] ) * flBlend;
+}
+
+
+//-----------------------------------------------------------------------------
+//
+// CPresetSideFilterSlider class begins
+//
+//-----------------------------------------------------------------------------
+class CPresetSideFilterSlider : public Slider
+{
+ DECLARE_CLASS_SIMPLE( CPresetSideFilterSlider, Slider );
+
+public:
+ CPresetSideFilterSlider( CBaseAnimSetAttributeSliderPanel *pParent, const char *panelName );
+ virtual ~CPresetSideFilterSlider();
+
+ float GetPos();
+ void SetPos( float frac );
+
+protected:
+ virtual void Paint();
+ virtual void PaintBackground();
+ virtual void ApplySchemeSettings( IScheme *scheme );
+ virtual void GetTrackRect( int &x, int &y, int &w, int &h );
+ virtual void OnMousePressed(MouseCode code);
+ virtual void OnMouseDoublePressed(MouseCode code);
+
+private:
+ CBaseAnimSetAttributeSliderPanel *m_pParent;
+
+ Color m_ZeroColor;
+ Color m_TextColor;
+ Color m_TextColorFocus;
+ TextImage *m_pName;
+ float m_flCurrent;
+};
+
+
+//-----------------------------------------------------------------------------
+// Constructor, destructor
+//-----------------------------------------------------------------------------
+CPresetSideFilterSlider::CPresetSideFilterSlider( CBaseAnimSetAttributeSliderPanel *parent, const char *panelName ) :
+ BaseClass( (Panel *)parent, panelName ), m_pParent( parent )
+{
+ SetRange( 0, 1000 );
+ SetDragOnRepositionNob( true );
+ SetPos( 0.5f );
+ SetPaintBackgroundEnabled( true );
+
+ m_pName = new TextImage( "Preset Side Filter" );
+
+ SetBgColor( Color( 128, 128, 128, 128 ) );
+
+ m_ZeroColor = Color( 33, 33, 33, 255 );
+ m_TextColor = Color( 200, 200, 200, 255 );
+ m_TextColorFocus = Color( 208, 143, 40, 255 );
+}
+
+CPresetSideFilterSlider::~CPresetSideFilterSlider()
+{
+ delete m_pName;
+}
+
+void CPresetSideFilterSlider::OnMousePressed(MouseCode code)
+{
+ if ( code == MOUSE_RIGHT )
+ {
+ SetPos( 0.5f );
+ return;
+ }
+
+ BaseClass::OnMousePressed( code );
+}
+
+void CPresetSideFilterSlider::OnMouseDoublePressed(MouseCode code)
+{
+ if ( code == MOUSE_LEFT )
+ {
+ SetPos( 0.5f );
+ return;
+ }
+
+ BaseClass::OnMouseDoublePressed( code );
+}
+
+float CPresetSideFilterSlider::GetPos()
+{
+ return GetValue() * 0.001f;
+}
+
+void CPresetSideFilterSlider::SetPos( float frac )
+{
+ SetValue( (int)( frac * 1000.0f + 0.5f ), false );
+}
+
+void CPresetSideFilterSlider::ApplySchemeSettings( IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ m_pName->SetFont( scheme->GetFont( "DefaultBold" ) );
+ m_pName->SetColor( m_TextColor );
+ m_pName->ResizeImageToContent();
+
+ SetFgColor( Color( 194, 120, 0, 255 ) );
+ SetThumbWidth( 3 );
+}
+
+void CPresetSideFilterSlider::GetTrackRect( int &x, int &y, int &w, int &h )
+{
+ GetSize( w, h );
+ x = 0;
+ y = 2;
+ h -= 4;
+}
+
+void CPresetSideFilterSlider::Paint()
+{
+ // horizontal nob
+ int x, y;
+ int wide,tall;
+ GetTrackRect( x, y, wide, tall );
+
+ Color col = GetFgColor();
+ surface()->DrawSetColor( col );
+ surface()->DrawFilledRect( _nobPos[0], 1, _nobPos[1], GetTall() - 1 );
+ surface()->DrawSetColor( m_ZeroColor );
+ surface()->DrawFilledRect( _nobPos[0] - 1, y + 1, _nobPos[0], y + tall - 1 );
+}
+
+void CPresetSideFilterSlider::PaintBackground()
+{
+ int w, h;
+ GetSize( w, h );
+
+ int tx, ty, tw, th;
+ GetTrackRect( tx, ty, tw, th );
+ surface()->DrawSetColor( m_ZeroColor );
+ surface()->DrawFilledRect( tx, ty, tx + tw, ty + th );
+
+ int cw, ch;
+ m_pName->SetColor( _dragging ? m_TextColorFocus : m_TextColor );
+ m_pName->GetContentSize( cw, ch );
+ m_pName->SetPos( ( w - cw ) * 0.5f, ( h - ch ) * 0.5f );
+ m_pName->Paint();
+}
+
+
+//-----------------------------------------------------------------------------
+//
+// CBaseAnimSetAttributeSliderPanel begins
+//
+//-----------------------------------------------------------------------------
+CBaseAnimSetAttributeSliderPanel::CBaseAnimSetAttributeSliderPanel( vgui::Panel *parent, const char *className, CBaseAnimationSetEditor *editor ) :
+ BaseClass( parent, className ),
+ m_flEstimatedValue( 0.0f ),
+ m_ChannelToSliderLookup( 0, 0, ChannelToSliderLookup_t::Less ),
+ m_flRecomputePreviewTime( -1.0f ),
+ m_bRequestedNewPreview( false ),
+ m_flPrevTime( 0.0f ),
+ m_nFaderChangeFlags( 0 )
+{
+ m_hEditor = editor;
+
+ m_pLeftRightBoth[ 0 ] = new Button( this, "AttributeSliderLeftOnly", "", this, "OnLeftOnly" );
+ m_pLeftRightBoth[ 1 ] = new Button( this, "AttributeSliderRightOnly", "", this, "OnRightOnly" );
+ m_pPresetSideFilter = new CPresetSideFilterSlider( this, "PresetSideFilter" );
+ m_Sliders = new PanelListPanel( this, "AttributeSliders" );
+ m_Sliders->SetFirstColumnWidth( 0 );
+ m_Sliders->SetAutoResize
+ (
+ Panel::PIN_TOPLEFT,
+ Panel::AUTORESIZE_DOWNANDRIGHT,
+ 0, ANIMATION_SET_EDITOR_ATTRIBUTESLIDERS_BUTTONTRAY_HEIGHT,
+ 0, 0
+ );
+ m_Sliders->SetVerticalBufferPixels( 0 );
+
+ m_PreviousPreviewFader = "";
+ m_Previous.isbeingdragged = false;
+ m_Previous.holdingctrl = false;
+ m_Previous.amount = 0.0f;
+}
+
+void CBaseAnimSetAttributeSliderPanel::OnCommand( const char *pCommand )
+{
+ if ( !Q_stricmp( pCommand, "OnLeftOnly" ) )
+ {
+ m_pPresetSideFilter->SetPos( 0.0f );
+ return;
+ }
+
+ if ( !Q_stricmp( pCommand, "OnRightOnly" ) )
+ {
+ m_pPresetSideFilter->SetPos( 1.0f );
+ return;
+ }
+
+ BaseClass::OnCommand( pCommand );
+}
+
+void CBaseAnimSetAttributeSliderPanel::StampValueIntoLogs( CDmElement *control, AnimationControlType_t type, float flValue )
+{
+}
+
+void CBaseAnimSetAttributeSliderPanel::ApplySchemeSettings( IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+ m_Sliders->SetBgColor( Color( 42, 42, 42, 255 ) );
+}
+
+void CBaseAnimSetAttributeSliderPanel::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ int w, h;
+ GetSize( w, h );
+
+ int availH = ANIMATION_SET_EDITOR_ATTRIBUTESLIDERS_BUTTONTRAY_HEIGHT;
+
+ int btnSize = 9;
+ m_pLeftRightBoth[ 0 ]->SetBounds( 15, ( availH - btnSize ) / 2, btnSize, btnSize );
+ m_pLeftRightBoth[ 1 ]->SetBounds( w - 15, ( availH - btnSize ) / 2, btnSize, btnSize );
+ m_pPresetSideFilter->SetBounds( 23 + btnSize, 4, w - 38 - 2 * btnSize, availH - 8 );
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Determines:
+// a) are we holding the ctrl key still, if so
+// figures out the crossfade amount of each preset slider with non-zero influence
+// b) not holding control, then just see if we are previewing whichever preset the mouse is over
+// Input : -
+//-----------------------------------------------------------------------------
+void CBaseAnimSetAttributeSliderPanel::OnThink()
+{
+ BaseClass::OnThink();
+
+ CBaseAnimSetPresetFaderPanel *presets = m_hEditor->GetPresetFader();
+ if ( !presets )
+ return;
+
+ FaderPreview_t fader;
+ presets->GetPreviewFader( fader );
+
+ bool nameChanged = ( fader.name && ( m_PreviousPreviewFader.IsEmpty() || Q_stricmp( m_PreviousPreviewFader.Get(), fader.name ) ) ) ? true : false;
+ bool beingDraggedChanged = fader.isbeingdragged != m_Previous.isbeingdragged ? true : false;
+ bool ctrlKeyChanged = fader.holdingctrl != m_Previous.holdingctrl ? true : false;
+ bool bFaderChanged = ( nameChanged || beingDraggedChanged || ctrlKeyChanged );
+ bool bPresetChanged = fader.preset != m_Previous.preset;
+ bool faderAmountChanged = fader.amount != m_Previous.amount ? true : false;
+
+ m_nFaderChangeFlags = 0;
+ if ( nameChanged )
+ {
+ m_nFaderChangeFlags |= FADER_NAME_CHANGED;
+ }
+ if ( beingDraggedChanged )
+ {
+ m_nFaderChangeFlags |= FADER_DRAG_CHANGED;
+ }
+ if ( ctrlKeyChanged )
+ {
+ m_nFaderChangeFlags |= FADER_CTRLKEY_CHANGED;
+ }
+ if ( faderAmountChanged )
+ {
+ m_nFaderChangeFlags |= FADER_AMOUNT_CHANGED;
+ }
+ if ( bPresetChanged )
+ {
+ m_nFaderChangeFlags |= FADER_PRESET_CHANGED;
+ }
+
+ m_PreviousPreviewFader = fader.name;
+ m_Previous = fader;
+
+ int c = m_SliderList.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ slider->EnablePreview( false, false, false );
+ if ( !slider->IsVisible() )
+ continue;
+
+ if ( !slider->GetControl() )
+ continue;
+
+ const char *name = slider->GetName();
+ Assert( name );
+
+ if ( m_CtrlKeyPreviewSlider.Get() == slider )
+ {
+ // The preset stuff shouldn't be active when we're holding ctrl over the raw attribute sliders!!!
+ Assert( !fader.isbeingdragged );
+ m_CtrlKeyPreviewSliderElement = NULL;
+ m_CtrlKeyPreviewSlider = NULL;
+
+ AttributeValue_t dest;
+ if ( !slider->IsTransform() )
+ {
+ dest.m_pValue[ ANIM_CONTROL_VALUE ] = m_flEstimatedValue;
+ dest.m_pValue[ ANIM_CONTROL_BALANCE ] = slider->GetValue( ANIM_CONTROL_BALANCE );
+ dest.m_pValue[ ANIM_CONTROL_MULTILEVEL ] = slider->GetValue( ANIM_CONTROL_MULTILEVEL );
+ }
+ else
+ {
+ dest.m_pValue[ ANIM_CONTROL_VALUE ] = 0.0f;
+ dest.m_pValue[ ANIM_CONTROL_BALANCE ] = 0.5f;
+ dest.m_pValue[ ANIM_CONTROL_MULTILEVEL ] = 0.5f;
+ }
+
+ // If we aren't over any of the preset sliders, then we need to be able to ramp down to the current value, too
+ slider->EnablePreview( true, false, false );
+ slider->SetPreview( dest, dest, true, true );
+ continue;
+ }
+
+ if ( !fader.values )
+ continue;
+
+ AttributeValue_t preview;
+ preview.m_pValue[ ANIM_CONTROL_VALUE ] = slider->IsTransform() ? 0.0f : slider->GetControlDefaultValue( ANIM_CONTROL_VALUE );
+ preview.m_pValue[ ANIM_CONTROL_BALANCE ] = 0.5f;
+ preview.m_pValue[ ANIM_CONTROL_MULTILEVEL ] = 0.5f;
+
+ AttributeValue_t current = slider->GetValue();
+
+ int idx = fader.values->Find( name );
+ if ( idx != fader.values->InvalidIndex() )
+ {
+ preview = (*fader.values)[ idx ];
+ }
+ BlendFlexValues( &preview, current, preview, 1.0f, slider->IsControlActive( ANIM_CONTROL_BALANCE ) ? m_pPresetSideFilter->GetPos() : 0.5f );
+
+ bool simple = fader.isbeingdragged || ( !fader.holdingctrl && !slider->IsRampingTowardPreview() && !ctrlKeyChanged );
+
+ slider->EnablePreview( true, simple, fader.isbeingdragged );
+ if ( bFaderChanged || fader.isbeingdragged )
+ {
+ // If being dragged, slam to current value right away
+ if ( simple )
+ {
+ slider->SetPreview( preview, preview, true, true );
+ }
+ else
+ {
+ // For the "ramp down" case (just released ctrl key), we need the original values instead of the preview valuees
+ if ( ctrlKeyChanged && !fader.holdingctrl && slider->IsRampingTowardPreview() )
+ {
+ Assert( !fader.isbeingdragged );
+ slider->RampDown();
+ }
+ else
+ {
+ // Apply the left-right balance to the target
+ AttributeValue_t dest;
+ BlendFlexValues( &dest, current, preview, fader.amount );
+ slider->SetPreview( dest, preview, !fader.holdingctrl, !nameChanged );
+ }
+ }
+ }
+
+ if ( faderAmountChanged || fader.isbeingdragged || fader.holdingctrl )
+ {
+ slider->UpdateFaderAmount( fader.amount );
+ }
+ }
+
+ UpdatePreviewSliderTimes();
+
+ ApplySliderValues( false );
+
+ PerformRecomputePreview();
+}
+
+void CBaseAnimSetAttributeSliderPanel::ChangeAnimationSet( CDmeAnimationSet *newAnimSet )
+{
+ int i;
+ // Force recomputation
+ m_nActiveControlSetMode = -1;
+
+ bool rebuild = true;
+
+ if ( m_AnimSet.Get() && newAnimSet == m_AnimSet )
+ {
+ // See if every slider is the same as before
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+ int controlCount = controls.Count();
+ if ( m_SliderList.Count() == controlCount )
+ {
+ rebuild = false;
+ for ( i = 0 ; i < controlCount; ++i )
+ {
+ CDmElement *control = controls[ i ];
+ if ( !control )
+ continue;
+
+ if ( Q_stricmp( control->GetName(), m_SliderList[ i ]->GetName() ) )
+ {
+ rebuild = true;
+ break;
+ }
+
+ bool bStereo = control->GetValue< bool >( "combo" );
+ bool bIsMulti = control->GetValue< bool >( "multi" );
+ if ( m_SliderList[ i ]->IsControlActive( ANIM_CONTROL_BALANCE ) != bStereo ||
+ m_SliderList[ i ]->IsControlActive( ANIM_CONTROL_MULTILEVEL ) != bIsMulti )
+ {
+ rebuild = true;
+ break;
+ }
+ }
+ }
+ }
+
+ m_AnimSet = newAnimSet;
+
+ if ( !m_AnimSet.Get() )
+ return;
+
+ if ( !rebuild )
+ return;
+
+ int c = m_SliderList.Count();
+ for ( i = 0 ; i < c; ++i )
+ {
+ delete m_SliderList[ i ];
+ }
+ m_SliderList.RemoveAll();
+ m_Sliders->RemoveAll();
+ m_ChannelToSliderLookup.Purge();
+
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ // Now create sliders for all known controls, nothing visible by default
+ int controlCount = controls.Count();
+ for ( i = 0 ; i < controlCount; ++i )
+ {
+ CDmElement *control = controls[ i ];
+ if ( !control )
+ continue;
+
+ CAttributeSlider *slider = new CAttributeSlider( this, control->GetName(), control );
+
+ slider->SetVisible( false );
+ slider->SetValue( ANIM_CONTROL_VALUE, control->GetValue< float >( "value" ) );
+ slider->SetSize( 100, 20 );
+
+ bool bStereo = control->GetValue< bool >( "combo" );
+ slider->ActivateControl( ANIM_CONTROL_BALANCE, bStereo );
+ if ( bStereo )
+ {
+ slider->SetValue( ANIM_CONTROL_BALANCE, control->GetValue< float >( "balance" ) );
+ }
+
+ bool bMulti = control->GetValue< bool >( "multi" );
+ slider->ActivateControl( ANIM_CONTROL_MULTILEVEL, bMulti );
+ if ( bMulti )
+ {
+ slider->SetValue( ANIM_CONTROL_MULTILEVEL, control->GetValue< float >( "multilevel" ) );
+ }
+ m_SliderList.AddToTail( slider );
+
+ ChannelToSliderLookup_t lookup;
+ lookup.slider = control;
+
+ CDmeChannel *ctrlChannels[ LOG_PREVIEW_MAX_CHANNEL_COUNT ];
+ GetChannelsForControl( control, ctrlChannels );
+ for ( int j = 0 ; j < LOG_PREVIEW_MAX_CHANNEL_COUNT; ++j )
+ {
+ lookup.ch = ctrlChannels[ j ];
+ lookup.type = (AnimationControlType_t)j;
+ if ( lookup.ch )
+ {
+ Assert( m_ChannelToSliderLookup.Find( lookup) == m_ChannelToSliderLookup.InvalidIndex() );
+ m_ChannelToSliderLookup.Insert( lookup );
+ }
+ }
+ }
+
+ RecomputePreview();
+}
+
+void CBaseAnimSetAttributeSliderPanel::SetVisibleControlsForSelectionGroup( CUtlSymbolTable& visible )
+{
+ int i, c;
+
+ bool changed = false;
+
+ // Walk through all sliders and show only those in the symbol table
+ c = m_SliderList.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ const char *sliderName = slider->GetName();
+
+ bool showSlider = visible.Find( sliderName ) != UTL_INVAL_SYMBOL ? true : false;
+ if ( slider->IsVisible() != showSlider )
+ {
+ changed = true;
+ break;
+ }
+ }
+
+ if ( !changed )
+ return;
+
+ m_Sliders->RemoveAll();
+ c = m_SliderList.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ const char *sliderName = slider->GetName();
+
+ if ( visible.Find( sliderName ) != UTL_INVAL_SYMBOL )
+ {
+ slider->SetVisible( true );
+ m_Sliders->AddItem( NULL, slider );
+ }
+ else
+ {
+ slider->SetVisible( false );
+ }
+ }
+
+ // Force mode to recompute
+ m_nActiveControlSetMode = -1;
+ RecomputePreview();
+}
+
+
+void CBaseAnimSetAttributeSliderPanel::ApplyPreset( float flScale, AttributeDict_t& values )
+{
+ int c = m_SliderList.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ if ( !slider || !slider->IsVisible() )
+ continue;
+
+ if ( slider->IsTransform() )
+ continue;
+
+ AttributeValue_t current, target;
+ current = slider->GetValue( );
+
+ target.m_pValue[ ANIM_CONTROL_VALUE ] = slider->GetControlDefaultValue( ANIM_CONTROL_VALUE );
+ target.m_pValue[ ANIM_CONTROL_BALANCE ] = 0.5f;
+ target.m_pValue[ ANIM_CONTROL_MULTILEVEL ] = 0.5f;
+
+ const char *name = slider->GetName();
+ int idx = name ? values.Find( name ) : values.InvalidIndex();
+ if ( idx != values.InvalidIndex() )
+ {
+ target = values[ idx ];
+ }
+
+ // Apply the left-right balance to the target
+ AttributeValue_t blend;
+ BlendFlexValues( &blend, current, target, flScale, slider->IsControlActive( ANIM_CONTROL_BALANCE ) ? m_pPresetSideFilter->GetPos() : 0.5f );
+ slider->SetValue( blend );
+ }
+}
+
+static const char *s_pAnimControlAttribute[ANIM_CONTROL_COUNT] =
+{
+ "value", "balance", "multilevel"
+};
+
+bool CBaseAnimSetAttributeSliderPanel::ApplySliderValues( bool bForce )
+{
+ if ( !m_AnimSet.Get() )
+ return false;
+
+ if ( !bForce )
+ {
+ bForce = m_Previous.isbeingdragged;
+ }
+
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ bool valuesChanged = false;
+
+ CDisableUndoScopeGuard guard;
+
+ int c = m_SliderList.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CAttributeSlider *pSlider = m_SliderList[ i ];
+ if ( !pSlider->IsVisible() )
+ continue;
+
+ CDmElement *pControl = controls[ i ];
+ if ( !pControl )
+ continue;
+
+ // Skip these types of sliders...
+ if ( pControl->GetValue< bool >( "transform" ) )
+ continue;
+
+ CDmeChannel *ctrlChannels[ LOG_PREVIEW_MAX_CHANNEL_COUNT ];
+ GetChannelsForControl( pControl, ctrlChannels );
+
+ bool bUsePreviewValue = pSlider->IsPreviewEnabled() && ( !pSlider->IsSimplePreview() || bForce );
+
+ for ( int j = 0; j < LOG_PREVIEW_MAX_CHANNEL_COUNT; ++j )
+ {
+ AnimationControlType_t type = (AnimationControlType_t)j;
+ CDmeChannel *pChannel = ctrlChannels[ j ];
+
+ // Figure out what to do based on the channel's mode
+ ChannelMode_t mode = pChannel ? pChannel->GetMode() : CM_PASS;
+ bool bPushSlidersIntoScene = ( mode == CM_PASS || mode == CM_RECORD );
+ bool bPullSlidersFromScene = ( mode == CM_PLAY );
+
+ if ( bPullSlidersFromScene )
+ {
+ Assert( pChannel );
+
+ // If it's actively being manipulated, the UI will be up to date
+ if ( pSlider->GetDragControl() == type )
+ continue;
+
+ // If we're dragging value, we're now going to be changing balance as well
+ if ( pSlider->GetDragControl() == ANIM_CONTROL_VALUE && type == ANIM_CONTROL_BALANCE )
+ continue;
+
+ // Drive value setting based on the output data
+ // NOTE: GetCurrentPlaybackValue might not overwrite flValue.
+ float flValue = pSlider->GetControlDefaultValue( type );
+ pChannel->GetCurrentPlaybackValue< float >( flValue );
+ pSlider->SetValue( type, flValue );
+ pControl->SetValue< float >( s_pAnimControlAttribute[type], flValue );
+ }
+ else if ( bPushSlidersIntoScene )
+ {
+ float flValue = bUsePreviewValue ? pSlider->GetPreview( type ) : pSlider->GetValue( type );
+ if ( pControl->GetValue< float >( s_pAnimControlAttribute[type] ) != flValue || bForce )
+ {
+ valuesChanged = true;
+ pControl->SetValue< float >( s_pAnimControlAttribute[type], flValue );
+ }
+ }
+ }
+ }
+
+ guard.Release();
+
+ return valuesChanged;
+}
+
+void CBaseAnimSetAttributeSliderPanel::UpdatePreviewSliderTimes()
+{
+ if ( !m_AnimSet.Get() )
+ return;
+
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ float curtime = system()->GetFrameTime();
+ float dt = clamp( curtime - m_flPrevTime, 0.0f, 0.1f );
+ m_flPrevTime = curtime;
+
+ dt *= ifm_fader_timescale;
+
+ bool previewing = false;
+ bool changingvalues = false;
+
+ bool ctrlDown = input()->IsKeyDown( KEY_LCONTROL ) || input()->IsKeyDown( KEY_RCONTROL );
+ int mx, my;
+ input()->GetCursorPos( mx, my );
+ if ( ctrlDown )
+ {
+ bool bInside = m_Sliders->IsWithin( mx, my );
+ if ( !bInside )
+ {
+ ctrlDown = false;
+ }
+
+ VPANEL topMost = input()->GetMouseOver();
+ if ( topMost && !ipanel()->HasParent( topMost, GetVPanel() ) )
+ {
+ ctrlDown = false;
+ }
+ }
+
+ CAttributeSlider *dragSlider = NULL;
+ CDmElement *dragSliderElement = NULL;
+
+ m_CtrlKeyPreviewSliderElement = NULL;
+ m_CtrlKeyPreviewSlider = NULL;
+ m_flEstimatedValue = 0.0f;
+
+ int c = m_SliderList.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ slider->UpdateTime( dt );
+
+ if ( !slider->IsVisible() )
+ continue;
+
+ bool ctrlDownOnThisSlider = false;
+ if ( ctrlDown )
+ {
+ int x, y;
+ x = mx;
+ y = my;
+ slider->ScreenToLocal( x, y );
+
+ int sw, st;
+ slider->GetSize( sw, st );
+ if ( x >= 0 && x < sw && y >= 0 && y < st )
+ {
+ // Should only hit one slider!!!
+ Assert( !ctrlDownOnThisSlider );
+ ctrlDownOnThisSlider = true;
+ if ( !slider->IsTransform() )
+ {
+ m_flEstimatedValue = slider->EstimateValueAtPos( x, y );
+ }
+ }
+ }
+
+ if ( slider->IsPreviewEnabled() )
+ {
+ if ( !slider->IsSimplePreview() )
+ {
+ previewing = true;
+ }
+ }
+ // If a fader is being dragged, or we're directly manipulating the slider, then we are going to put
+ // this slider into record mode
+ if ( slider->IsFaderBeingDragged() )
+ {
+ changingvalues = true;
+ Assert( !dragSlider );
+ dragSlider = NULL;
+ dragSliderElement = NULL;
+ }
+ else if ( slider->IsDragging() )
+ {
+ Assert( !dragSlider );
+ dragSlider = slider;
+ dragSliderElement = controls[ i ];
+ changingvalues = true;
+ }
+
+ if ( ctrlDownOnThisSlider )
+ {
+ m_CtrlKeyPreviewSliderElement = controls[ i ];
+ m_CtrlKeyPreviewSlider = slider;
+ }
+ }
+
+ switch ( m_hEditor->GetRecordingState() )
+ {
+ default:
+ Assert( 0 );
+ break;
+ case AS_OFF:
+ {
+ ActivateControlSetInMode( CM_OFF, CM_OFF, CM_OFF, NULL );
+ }
+ break;
+ case AS_RECORD:
+ {
+ // Put one or all things into record mode (if dragging a single slider, other channels should be in playback mode)
+ if ( changingvalues || previewing )
+ {
+ ActivateControlSetInMode( changingvalues ? CM_RECORD : CM_PASS, CM_PLAY, CM_PLAY, dragSlider );
+ }
+ else
+ {
+ ActivateControlSetInMode( CM_PLAY, CM_PLAY, CM_PLAY, dragSlider );
+ }
+ }
+ break;
+ case AS_PLAYBACK:
+ {
+ // Put things into playback, except if dragging a slider, to preview
+ if ( changingvalues || previewing )
+ {
+ ActivateControlSetInMode( CM_PASS, CM_PLAY, CM_PLAY, NULL );
+ }
+ else
+ {
+ ActivateControlSetInMode( CM_PLAY, CM_PLAY, CM_PLAY, NULL );
+ }
+ }
+ break;
+ case AS_PREVIEW:
+ {
+ // Put things into passthru
+ ActivateControlSetInMode( CM_PASS, CM_PASS, CM_PLAY, NULL );
+ }
+ break;
+ }
+
+ if ( dragSliderElement )
+ {
+ SetLogPreviewControl( dragSliderElement );
+ }
+ else if ( m_CtrlKeyPreviewSliderElement.Get() )
+ {
+ SetLogPreviewControl( m_CtrlKeyPreviewSliderElement );
+ }
+}
+
+bool CBaseAnimSetAttributeSliderPanel::GetAttributeSliderValue( AttributeValue_t *pValue, const char *name )
+{
+ int c = m_SliderList.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ if ( Q_stricmp( slider->GetName(), name ) )
+ continue;
+
+ *pValue = slider->GetValue( );
+ return true;
+ }
+ return false;
+}
+
+void CBaseAnimSetAttributeSliderPanel::GetChannelsForControl( CDmElement *control, CDmeChannel *channels[LOG_PREVIEW_MAX_CHANNEL_COUNT] )
+{
+ if ( control->GetValue< bool >( "transform" ) )
+ {
+ CDmeChannel *ch1 = control->GetValueElement< CDmeChannel >( "position" );
+ CDmeChannel *ch2 = control->GetValueElement< CDmeChannel >( "orientation" );
+
+ channels[ LOG_PREVIEW_POSITION ] = ch1;
+ channels[ LOG_PREVIEW_ORIENTATION ] = ch2;
+ for ( int i = 2; i < LOG_PREVIEW_MAX_CHANNEL_COUNT; ++i )
+ {
+ channels[i] = NULL;
+ }
+ return;
+ }
+
+ if ( control->GetValue< bool >( "combo" ) )
+ {
+ channels[ LOG_PREVIEW_VALUE ] = control->GetValueElement< CDmeChannel >( "valuechannel" );
+ channels[ LOG_PREVIEW_BALANCE ] = control->GetValueElement< CDmeChannel >( "balancechannel" );
+ }
+ else
+ {
+ channels[ LOG_PREVIEW_VALUE ] = control->GetValueElement< CDmeChannel >( "channel" );
+ channels[ LOG_PREVIEW_BALANCE ] = 0;
+ }
+
+ if ( control->GetValue< bool >( "multi" ) )
+ {
+ channels[ LOG_PREVIEW_MULTILEVEL ] = control->GetValueElement< CDmeChannel >( "multilevelchannel" );
+ }
+ else
+ {
+ channels[ LOG_PREVIEW_MULTILEVEL ] = NULL;
+ }
+ for ( int i = 3; i < LOG_PREVIEW_MAX_CHANNEL_COUNT; ++i )
+ {
+ channels[i] = NULL;
+ }
+}
+
+void CBaseAnimSetAttributeSliderPanel::GetActiveTimeSelectionParams( DmeLog_TimeSelection_t& params )
+{
+ Assert( 0 );
+}
+
+void CBaseAnimSetAttributeSliderPanel::ActivateControlSetInMode( int mode, int otherChannelsMode, int hiddenChannelsMode, CAttributeSlider *whichSlider /*= NULL*/ )
+{
+ int i, c;
+
+ if ( !m_AnimSet.Get() )
+ return;
+
+ bool updateChannelsModeChanged = m_nActiveControlSetMode != mode ? true : false;
+ if ( !updateChannelsModeChanged )
+ return;
+
+ int previousMode = m_nActiveControlSetMode;
+ m_nActiveControlSetMode = mode;
+
+ if ( previousMode == CM_RECORD )
+ {
+ DmeLog_TimeSelection_t params;
+ GetActiveTimeSelectionParams( params );
+
+ // Finalize any previously recording layers!!!
+ g_pChannelRecordingMgr->FinishLayerRecording( params.m_flThreshold, true );
+ }
+
+ ChannelMode_t channelMode = ( ChannelMode_t )mode;
+
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ // Build the list of channels to alter
+ CUtlVector< CDmeChannel * > updateChannels;
+ CUtlVector< CDmeChannel * > otherChannels;
+ CUtlVector< CDmeChannel * > hiddenChannels;
+
+ CDisableUndoScopeGuard guard;
+
+ c = m_SliderList.Count();
+ int j;
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ CDmElement *ctrl = controls[ i ];
+ if ( !ctrl )
+ continue;
+
+ CDmeChannel *ctrlChannels[ LOG_PREVIEW_MAX_CHANNEL_COUNT ];
+ GetChannelsForControl( ctrl, ctrlChannels );
+
+ for ( j = 0 ; j < LOG_PREVIEW_MAX_CHANNEL_COUNT; ++j )
+ {
+ if ( !ctrlChannels[ j ] )
+ continue;
+
+ CUtlVector< CDmeChannel * > *useArray = NULL;;
+
+ // now characterize it
+ bool hidden = !slider->IsVisible();
+ if ( hidden )
+ {
+ useArray = &hiddenChannels;
+ }
+ else
+ {
+ if ( !whichSlider )
+ {
+ useArray = &updateChannels;
+ }
+ else if ( slider == whichSlider )
+ {
+ // this causes value and balance to get lumped together, since we're now dragging left/right values
+ if ( slider->GetDragControl() == ANIM_CONTROL_MULTILEVEL )
+ {
+ useArray = ( j == LOG_PREVIEW_MULTILEVEL ) ? &updateChannels : &otherChannels;
+ }
+ else
+ {
+ useArray = ( j != LOG_PREVIEW_MULTILEVEL ) ? &updateChannels : &otherChannels;
+ }
+ }
+ else
+ {
+ useArray = &otherChannels;
+ }
+ }
+
+ useArray->AddToTail( ctrlChannels[ j ] );
+ }
+ }
+
+ guard.Release();
+
+ c = updateChannels.Count();
+ if ( c > 0 )
+ {
+ if ( channelMode == CM_RECORD )
+ {
+ DmeLog_TimeSelection_t params;
+ GetActiveTimeSelectionParams( params );
+ params.SetRecordingMode( ( NULL == whichSlider ) ? RECORD_PRESET : RECORD_ATTRIBUTESLIDER );
+
+ g_pChannelRecordingMgr->StartLayerRecording( "Dragging Sliders", &params );
+
+ for ( i = 0; i < c; ++i )
+ {
+ // THIS PUTS THEM INTO CM_RECORD
+ g_pChannelRecordingMgr->AddChannelToRecordingLayer( updateChannels[ i ], GetCurrentMovie(), GetCurrentShot() );
+ }
+
+ SetTimeSelectionParametersForRecordingChannels( ( NULL == whichSlider ) ? m_Previous.amount : 1.0f );
+ }
+ else
+ {
+ // Don't create undo records for this
+ CDisableUndoScopeGuard guardSet;
+ for ( i = 0; i < c; ++i )
+ {
+ updateChannels[ i ]->SetMode( channelMode );
+ }
+ }
+ }
+
+ c = otherChannels.Count();
+ if ( c > 0 )
+ {
+ // Don't create undo records for this
+ CDisableUndoScopeGuard guardRecord;
+
+ for ( i = 0; i < c; ++i )
+ {
+ // These should never go into record!!!
+ Assert( (ChannelMode_t)otherChannelsMode != CM_RECORD );
+ otherChannels[ i ]->SetMode( (ChannelMode_t)otherChannelsMode );
+ }
+ }
+
+ c = hiddenChannels.Count();
+ if ( c > 0 )
+ {
+ // Don't create undo records for this
+ CDisableUndoScopeGuard guardRecord;
+
+ // For now these should only be able to go into Playback
+ //Assert( (ChannelMode_t)hiddenChannelsMode == CM_PLAY );
+
+ for ( i = 0; i < c; ++i )
+ {
+ hiddenChannels[ i ]->SetMode( (ChannelMode_t)hiddenChannelsMode );
+ }
+ }
+}
+
+static const char *s_pDefaultAttributeName[ANIM_CONTROL_COUNT] =
+{
+ "defaultValue", "defaultBalance", "defaultMultilevel"
+};
+
+void CBaseAnimSetAttributeSliderPanel::SetupForPreset( FaderPreview_t &fader, int nChangeFlags )
+{
+ // Nothing special here
+}
+
+float CBaseAnimSetAttributeSliderPanel::GetBalanceSliderValue()
+{
+ return m_pPresetSideFilter->GetPos();
+}
+
+void CBaseAnimSetAttributeSliderPanel::SetTimeSelectionParametersForRecordingChannels( float flIntensity )
+{
+ CBaseAnimSetPresetFaderPanel *pPresets = m_hEditor->GetPresetFader();
+ if ( !pPresets )
+ {
+ Assert( 0 );
+ return;
+ }
+
+ FaderPreview_t fader;
+ pPresets->GetPreviewFader( fader );
+
+ SetupForPreset( fader, m_nFaderChangeFlags );
+
+ int c = g_pChannelRecordingMgr->GetLayerRecordingChannelCount();
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmeChannel *ch = g_pChannelRecordingMgr->GetLayerRecordingChannel( i );
+ if ( !ch )
+ continue;
+
+ CDmAttribute *pPreset = NULL;
+
+ ChannelToSliderLookup_t search;
+ search.ch = ch;
+ unsigned int idx = m_ChannelToSliderLookup.Find( search );
+ if ( idx != m_ChannelToSliderLookup.InvalidIndex() && fader.values )
+ {
+ ChannelToSliderLookup_t &item = m_ChannelToSliderLookup[ idx ];
+
+ CDmElement *pControl = item.slider;
+ Assert( pControl );
+
+ int faderIndex = fader.values->Find( pControl->GetName() );
+ if ( faderIndex != fader.values->InvalidIndex() )
+ {
+ pPreset = (*fader.values)[ faderIndex ].m_pAttribute[ item.type ];
+ }
+ if ( !pPreset )
+ {
+ pPreset = pControl->GetAttribute( s_pDefaultAttributeName[item.type] );
+ }
+ }
+
+ g_pChannelRecordingMgr->SetPresetValue( ch, pPreset );
+ }
+}
+
+static bool CanPreviewType( DmAttributeType_t attType )
+{
+ switch ( attType )
+ {
+ default:
+ return false;
+ case AT_FLOAT:
+ case AT_VECTOR3:
+ case AT_QUATERNION:
+ break;
+ }
+ return true;
+}
+
+void CBaseAnimSetAttributeSliderPanel::MaybeAddPreviewLog( CDmeFilmClip *shot, CUtlVector< LogPreview_t >& list, CDmElement *control, bool bDragging, bool isActiveLog, bool bSelected )
+{
+ CDmeChannel *ctrlChannels[ LOG_PREVIEW_MAX_CHANNEL_COUNT ];
+ GetChannelsForControl( control, ctrlChannels );
+
+ LogPreview_t preview;
+
+ preview.m_bDragging = bDragging;
+ preview.m_bActiveLog = isActiveLog;
+ preview.m_bSelected = bSelected;
+
+ for ( int channel = 0; channel < LOG_PREVIEW_MAX_CHANNEL_COUNT; ++channel )
+ {
+ CDmeChannel *ch = ctrlChannels[ channel ];
+ if ( !ch )
+ continue;
+
+ CDmeLog *log = ch->GetLog();
+ if ( !log )
+ continue;
+
+ DmAttributeType_t attType = log->GetDataType();
+ if ( !CanPreviewType( attType ) )
+ continue;
+
+ Assert( control );
+
+ preview.m_hControl = control;
+ preview.m_hShot = shot;
+ preview.m_hChannels[ channel ] = ch;
+ preview.m_hOwner = ch->FindOwnerClipForChannel( shot );
+ }
+
+ list.AddToTail( preview );
+}
+
+void CBaseAnimSetAttributeSliderPanel::RecomputePreview()
+{
+ float curtime = system()->GetFrameTime();
+ m_flRecomputePreviewTime = curtime + RECOMPUTE_PREVIEW_INTERVAL;
+ m_bRequestedNewPreview = true;
+}
+
+CDmeFilmClip *CBaseAnimSetAttributeSliderPanel::GetCurrentShot()
+{
+ return NULL;
+}
+
+CDmeFilmClip *CBaseAnimSetAttributeSliderPanel::GetCurrentMovie()
+{
+ return NULL;
+}
+
+void CBaseAnimSetAttributeSliderPanel::PerformRecomputePreview()
+{
+ m_CurrentPreview.RemoveAll();
+ if ( !m_bRequestedNewPreview )
+ return;
+
+#if 0
+ // Tracker 54528: While this saves recomputing things all of the time, the delay is annoying so
+ // we'll turn it off for now
+ float curtime = system()->GetFrameTime();
+ if ( curtime < m_flRecomputePreviewTime )
+ return;
+#endif
+
+ m_bRequestedNewPreview = false;
+ m_flRecomputePreviewTime = -1.0f;
+ // list of bones/root transforms which are in the control set
+ m_ActiveTransforms.Purge();
+ if ( !m_AnimSet.Get() )
+ return;
+
+ CDmeFilmClip *shot = GetCurrentShot();
+ CDmElement *previewControl = GetLogPreviewControl();
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ int c = m_SliderList.Count();
+ int i;
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ if ( !slider->IsVisible() )
+ continue;
+ CDmElement *control = controls[ i ];
+
+ MaybeAddPreviewLog( shot, m_ActiveTransforms, control, slider->IsDragging(), false, slider->IsSelected() );
+ MaybeAddPreviewLog( shot, m_CurrentPreview, control, slider->IsDragging(), ( control == previewControl ), slider->IsSelected() );
+ }
+}
+
+CUtlVector< LogPreview_t >* CBaseAnimSetAttributeSliderPanel::GetActiveTransforms()
+{
+ return &m_ActiveTransforms;
+}
+
+CDmElement *CBaseAnimSetAttributeSliderPanel::GetElementFromSlider( CAttributeSlider *pSlider )
+{
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ int c = m_SliderList.Count();
+ int i;
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ if ( slider != pSlider )
+ continue;
+
+ CDmElement *control = controls[ i ];
+ return control;
+ }
+ return NULL;
+}
+
+CDmElement *CBaseAnimSetAttributeSliderPanel::GetLogPreviewControl()
+{
+ return m_PreviewControl.Get();
+}
+
+void CBaseAnimSetAttributeSliderPanel::SetLogPreviewControlFromSlider( CAttributeSlider *pSlider )
+{
+ CDmElement *control = GetElementFromSlider( pSlider );
+ // Note can be NULL
+ SetLogPreviewControl( control );
+}
+
+void CBaseAnimSetAttributeSliderPanel::SetLogPreviewControl( CDmElement *control )
+{
+ if ( !m_hEditor.Get() )
+ return;
+
+ bool changed = m_PreviewControl != control ? true : false;
+ m_PreviewControl = control;
+ if ( changed )
+ {
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ int itemNumber = 0;
+ int nSliders = m_SliderList.Count();
+ for ( int i = 0; i < nSliders; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ slider->SetIsLogPreviewControl( false );
+ if ( !slider->IsVisible() )
+ continue;
+
+ CDmElement *c = controls[ i ];
+ if ( c == control )
+ {
+ slider->SetIsLogPreviewControl( true );
+ slider->RequestFocus();
+ m_Sliders->ScrollToItem( itemNumber );
+ }
+
+ ++itemNumber;
+ }
+
+ RecomputePreview();
+ }
+}
+
+
+void CBaseAnimSetAttributeSliderPanel::GetVisibleControls( CUtlVector< VisItem_t>& list )
+{
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ int i, c;
+ c = m_SliderList.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ if ( !slider->IsVisible() )
+ continue;
+
+ CDmElement *ctrl = controls[ i ];
+ if ( !ctrl )
+ continue;
+
+ VisItem_t item;
+ item.element = ctrl;
+ item.selected = slider->IsSelected();
+ item.index = i;
+
+ list.AddToTail( item );
+ }
+}
+
+int CBaseAnimSetAttributeSliderPanel::BuildVisibleControlList( CUtlVector< LogPreview_t >& list )
+{
+ if ( !m_AnimSet.Get() )
+ return 0;
+
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ int i, c;
+ c = m_SliderList.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ if ( !slider->IsVisible() )
+ continue;
+
+ CDmElement *ctrl = controls[ i ];
+ if ( !ctrl )
+ continue;
+
+ MaybeAddPreviewLog( NULL, list, ctrl, slider->IsDragging(), false, slider->IsSelected() );
+ }
+
+ return list.Count();
+}
+
+int CBaseAnimSetAttributeSliderPanel::BuildFullControlList( CUtlVector< LogPreview_t >& list )
+{
+ if ( !m_AnimSet.Get() )
+ return 0;
+
+ const CDmaElementArray< CDmElement > &controls = m_AnimSet->GetControls();
+
+ int i, c;
+ c = m_SliderList.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ CAttributeSlider *slider = m_SliderList[ i ];
+ CDmElement *ctrl = controls[ i ];
+ if ( !ctrl )
+ continue;
+
+ MaybeAddPreviewLog( NULL, list, ctrl, slider->IsDragging(), false, slider->IsSelected() );
+ }
+
+ return list.Count();
+}
+
+
+
+
+void SpewLayer( const char *desc, CDmeTypedLogLayer< float > *l )
+{
+ Msg( "%s\n", desc );
+
+ int c = l->GetKeyCount();
+ for ( int i = 0; i < c; ++i )
+ {
+ DmeTime_t kt = l->GetKeyTime( i );
+ float v = l->GetKeyValue( i );
+
+ Msg( "%d %.3f = %f\n", i, kt.GetSeconds(), v );
+
+ if ( i > 20 )
+ break;
+
+ }
+}
+
+void CBaseAnimSetAttributeSliderPanel::MoveToSlider( CAttributeSlider *pCurrentSlider, int nDirection )
+{
+ Assert( pCurrentSlider );
+ if ( !pCurrentSlider )
+ return;
+
+ // Find current slider index and then move to next / previous one
+ CUtlVector< CAttributeSlider * > visible;
+
+ int c = m_SliderList.Count();
+ if ( c <= 1 )
+ return;
+
+ int i;
+ for ( i = 0; i < c; ++i )
+ {
+ if ( !m_SliderList[ i ]->IsVisible() )
+ continue;
+ visible.AddToTail( m_SliderList[ i ] );
+ }
+
+ c = visible.Count();
+
+ if ( c <= 1 )
+ return;
+
+ for ( i = 0; i < c; ++i )
+ {
+ if ( visible[ i ] != pCurrentSlider )
+ continue;
+
+ Msg( "Found slider at %d (old %s)\n", i, pCurrentSlider->GetName() );
+
+ i += nDirection;
+ if ( i < 0 )
+ {
+ i = c - 1;
+ }
+ else if ( i >= c )
+ {
+ i = 0;
+ }
+
+ Msg( "Change to slider %d %s\n", i, visible[ i ]->GetName() );
+
+ // m_SliderList[ i ]->RequestFocus();
+ SetLogPreviewControl( visible[ i ]->GetControl() );
+ break;
+ }
+}
+
+void CBaseAnimSetAttributeSliderPanel::OnKBDeselectAll()
+{
+ ClearSelectedControls();
+}
+
+void CBaseAnimSetAttributeSliderPanel::ClearSelectedControls()
+{
+ int c = m_SliderList.Count();
+ int i;
+ for ( i = 0; i < c; ++i )
+ {
+ m_SliderList[ i ]->SetSelected( false );
+ }
+ RecomputePreview();
+}
+
+void CBaseAnimSetAttributeSliderPanel::SetControlSelected( CAttributeSlider *slider, bool state )
+{
+ slider->SetSelected( state);
+ RecomputePreview();
+}
+
+void CBaseAnimSetAttributeSliderPanel::SetControlSelected( CDmElement *control, bool state )
+{
+ CAttributeSlider *slider = FindSliderForControl( control );
+ if ( !slider )
+ return;
+ SetControlSelected( slider, state );
+}
+
+CAttributeSlider *CBaseAnimSetAttributeSliderPanel::FindSliderForControl( CDmElement *control )
+{
+ int c = m_SliderList.Count();
+ int i;
+ for ( i = 0; i < c; ++i )
+ {
+ if ( m_SliderList[ i ]->GetControl() == control )
+ return m_SliderList[ i ];
+ }
+
+ return NULL;
+}
+
+bool CBaseAnimSetAttributeSliderPanel::GetSliderValues( AttributeValue_t *pValue, int nIndex )
+{
+ Assert( pValue );
+ Assert( nIndex >= 0 && nIndex < m_SliderList.Count() );
+
+ CAttributeSlider *pSlider = m_SliderList[ nIndex ];
+ bool bForce = m_Previous.isbeingdragged;
+ bool bGetPreview = ( pSlider->IsPreviewEnabled() && ( !pSlider->IsSimplePreview() || bForce ) );
+ *pValue = bGetPreview ? pSlider->GetPreview() : pSlider->GetValue();
+ return pSlider->IsVisible();
+} \ No newline at end of file