diff options
Diffstat (limited to 'utils/hlfaceposer/curveeditorhelpers.h')
| -rw-r--r-- | utils/hlfaceposer/curveeditorhelpers.h | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/utils/hlfaceposer/curveeditorhelpers.h b/utils/hlfaceposer/curveeditorhelpers.h new file mode 100644 index 0000000..7a3e22e --- /dev/null +++ b/utils/hlfaceposer/curveeditorhelpers.h @@ -0,0 +1,370 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef CURVEEDITORHELPERS_H +#define CURVEEDITORHELPERS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mxtk/mx.h" + +struct CExpressionSample; + +template< class T > +class CCurveEditorHelper +{ +public: + CCurveEditorHelper( T *outer ); + + int GetBestCurveTypeForSelectedSamples( bool reflect ); + int CountSelected( bool reflect ); + void ChangeCurveType( bool forward, bool shiftdown, bool altdown ); + void SetCurveTypeForSelectedSamples( bool reflect, int curvetype ); + void SetCurveTypeForSample( int curvetype, CExpressionSample *sample ); + void ToggleHoldTypeForSelectedSamples( bool reflect ); + void ToggleHoldTypeForSample( CExpressionSample *sample ); + + bool HelperHandleEvent( mxEvent *event ); + +private: + T *GetOuter(); + +private: + + T *m_pOuter; +}; + +template< class T > +CCurveEditorHelper<T>::CCurveEditorHelper( T *pOuter ) : + m_pOuter( pOuter ) +{ + Assert( pOuter ); +} + +template< class T > +T *CCurveEditorHelper<T>::GetOuter() +{ + return m_pOuter; +} + +template< class T > +int CCurveEditorHelper<T>::GetBestCurveTypeForSelectedSamples( bool reflect ) +{ + int numSelected = CountSelected( reflect ); + if ( !numSelected ) + return CURVE_DEFAULT; + + CUtlMap< int, int > counts( 0, 0, DefLessFunc( int ) ); + + CUtlVector< T * > workList; + GetOuter()->GetWorkList( reflect, workList ); + + for ( int w = 0; w < workList.Count(); ++w ) + { + int numSamples = workList[ w ]->NumSamples(); + if ( !numSamples ) + continue; + + for ( int i = numSamples - 1; i >= 0 ; i-- ) + { + CExpressionSample *sample = workList[ w ]->GetSample( i ); + if ( !sample->selected ) + continue; + + int curveType = sample->GetCurveType(); + int idx = counts.Find( curveType ); + if ( idx == counts.InvalidIndex() ) + { + idx = counts.Insert( curveType, 0 ); + } + + counts[ idx ]++; + } + } + + int maxType = CURVE_DEFAULT; + int maxCount = -1; + + for ( int i = counts.FirstInorder(); i != counts.InvalidIndex(); i = counts.NextInorder( i ) ) + { + if ( counts[ i ] > maxType ) + { + maxCount = counts[ i ]; + maxType = counts.Key( i ); + } + } + + return maxType; +} + +template< class T > +int CCurveEditorHelper<T>::CountSelected( bool reflect ) +{ + int numSelected = 0; + + CUtlVector< T * > workList; + GetOuter()->GetWorkList( reflect, workList ); + + for ( int w = 0; w < workList.Count(); ++w ) + { + int numSamples = workList[ w ]->NumSamples(); + if ( !numSamples ) + continue; + + for ( int i = 0 ; i < numSamples; ++i ) + { + CExpressionSample *sample = workList[ w ]->GetSample( i ); + if ( !sample || !sample->selected ) + continue; + + ++numSelected; + } + } + + return numSelected; +} + +template< class T > +void CCurveEditorHelper<T>::ChangeCurveType( bool forward, bool shiftdown, bool altdown ) +{ + // If holding ctrl and shift, only do inbound + bool inbound = shiftdown; + // if holding ctrl, shift + alt, do both inbound and outbound + bool outbound = !shiftdown || altdown; + // if holding ctrl + alt, do outbound + // if holding just ctrl, do outbound + + int numSelected = CountSelected( false ); + if ( !numSelected ) + return; + + int curveType = GetBestCurveTypeForSelectedSamples( false ); + + int sides[ 2 ]; + Interpolator_CurveInterpolatorsForType( curveType, sides[ 0 ], sides[ 1 ] ); + + int dir = forward ? 1 : -1; + for ( int i = 0; i < 2; ++i ) + { + if ( i == 0 && !inbound ) + continue; + if ( i == 1 && !outbound ) + continue; + + sides[ i ] += dir; + if ( sides[ i ] < 0 ) + { + sides[ i ] = NUM_INTERPOLATE_TYPES - 1; + } + else if ( sides[ i ] >= NUM_INTERPOLATE_TYPES ) + { + sides[ i ] = INTERPOLATE_DEFAULT; + } + } + + curveType = MAKE_CURVE_TYPE( sides[ 0 ], sides[ 1 ] ); + SetCurveTypeForSelectedSamples( false, curveType ); +} + +template< class T > +void CCurveEditorHelper<T>::SetCurveTypeForSelectedSamples( bool reflect, int curvetype ) +{ + int numSelected = CountSelected( reflect ); + if ( !numSelected ) + return; + + GetOuter()->PreDataChanged( "Set curve type" ); + + CUtlVector< T * > workList; + GetOuter()->GetWorkList( reflect, workList ); + + for ( int w = 0; w < workList.Count(); ++w ) + { + int numSamples = workList[ w ]->NumSamples(); + + for ( int i = 0 ; i < numSamples; ++i ) + { + CExpressionSample *sample = workList[ w ]->GetSample( i ); + if ( !sample->selected ) + continue; + + sample->SetCurveType( curvetype ); + } + } + + GetOuter()->PostDataChanged( "Set curve type" ); +} + +template< class T > +void CCurveEditorHelper<T>::SetCurveTypeForSample( int curvetype, CExpressionSample *sample ) +{ + GetOuter()->PreDataChanged( "Set curve type" ); + + sample->SetCurveType( curvetype ); + + GetOuter()->PostDataChanged( "Set curve type" ); +} + +template< class T > +void CCurveEditorHelper<T>::ToggleHoldTypeForSelectedSamples( bool reflect ) +{ + int numSelected = CountSelected( reflect ); + if ( !numSelected ) + return; + + GetOuter()->PreDataChanged( "Set hold out value" ); + + CUtlVector< T * > workList; + GetOuter()->GetWorkList( reflect, workList ); + + for ( int w = 0; w < workList.Count(); ++w ) + { + int numSamples = workList[ w ]->NumSamples(); + + int newValue = -1; + + for ( int i = 0 ; i < numSamples; ++i ) + { + CExpressionSample *sample = workList[ w ]->GetSample( i ); + if ( !sample->selected ) + continue; + + // First one controls setting + int l, r; + Interpolator_CurveInterpolatorsForType( sample->GetCurveType(), l, r ); + + if ( newValue == -1 ) + { + newValue = ( r == INTERPOLATE_HOLD ) ? 0 : 1; + } + + int newCurveType = MAKE_CURVE_TYPE( l, newValue == 1 ? INTERPOLATE_HOLD : l ); + sample->SetCurveType( newCurveType ); + } + } + + GetOuter()->PostDataChanged( "Set hold out value" ); +} + +template< class T > +void CCurveEditorHelper<T>::ToggleHoldTypeForSample( CExpressionSample *sample ) +{ + GetOuter()->PreDataChanged( "Set hold out value" ); + + int l, r; + Interpolator_CurveInterpolatorsForType( sample->GetCurveType(), l, r ); + + if ( r == INTERPOLATE_HOLD ) + { + r = l; + } + else + { + r = INTERPOLATE_HOLD; + } + + int newCurveType = MAKE_CURVE_TYPE( l, r ); + sample->SetCurveType( newCurveType ); + + GetOuter()->PostDataChanged( "Set hold out value" ); +} + +template< class T > +bool CCurveEditorHelper<T>::HelperHandleEvent( mxEvent *event ) +{ + bool handled = false; + + switch ( event->event ) + { + case mxEvent::KeyDown: + { + switch ( event->key ) + { + default: + // Hotkey pressed + if ( event->key >= '0' && + event->key <= '9' ) + { + bool shiftdown = GetAsyncKeyState( VK_SHIFT ) ? true : false; + + handled = true; + // Get curve type + int curveType = Interpolator_CurveTypeForHotkey( event->key ); + if ( curveType >= 0 ) + { + if ( CountSelected( shiftdown ) <= 0 ) + { + GetOuter()->SetMousePositionForEvent( event ); + + CExpressionSample *hover = GetOuter()->GetSampleUnderMouse( event->x, event->y, 0.0f ); + + // Deal with highlighted item + if ( hover ) + { + SetCurveTypeForSample( curveType, hover ); + } + } + else + { + SetCurveTypeForSelectedSamples( shiftdown, curveType ); + } + } + } + break; + case 'H': + { + handled = true; + + bool shiftdown = GetAsyncKeyState( VK_SHIFT ) ? true : false; + + if ( CountSelected( shiftdown ) <= 0 ) + { + GetOuter()->SetMousePositionForEvent( event ); + + CExpressionSample *hover = GetOuter()->GetSampleUnderMouse( event->x, event->y, 0.0f ); + + // Deal with highlighted item + if ( hover ) + { + ToggleHoldTypeForSample( hover ); + } + } + else + { + ToggleHoldTypeForSelectedSamples( shiftdown ); + } + } + break; + case VK_UP: + { + bool shiftdown = GetAsyncKeyState( VK_SHIFT ) ? true : false; + bool altdown = GetAsyncKeyState( VK_MENU ) ? true : false; + if ( GetAsyncKeyState( VK_CONTROL ) ) + { + ChangeCurveType( false, shiftdown, altdown ); + } + } + break; + case VK_DOWN: + { + bool shiftdown = GetAsyncKeyState( VK_SHIFT ) ? true : false; + bool altdown = GetAsyncKeyState( VK_MENU ) ? true : false; + if ( GetAsyncKeyState( VK_CONTROL ) ) + { + ChangeCurveType( true, shiftdown, altdown ); + } + } + break; + } + } + } + + return handled; +} + +#endif // CURVEEDITORHELPERS_H + |