diff options
Diffstat (limited to 'vgui2/dme_controls/AttributeTextEntry.cpp')
| -rw-r--r-- | vgui2/dme_controls/AttributeTextEntry.cpp | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/vgui2/dme_controls/AttributeTextEntry.cpp b/vgui2/dme_controls/AttributeTextEntry.cpp new file mode 100644 index 0000000..ade6ff3 --- /dev/null +++ b/vgui2/dme_controls/AttributeTextEntry.cpp @@ -0,0 +1,500 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "dme_controls/AttributeTextEntry.h" +#include "tier1/KeyValues.h" +#include "vgui_controls/Menu.h" +#include "datamodel/dmelement.h" +#include "dme_controls/AttributeTextPanel.h" +#include "vgui/MouseCode.h" +#include "vgui/KeyCode.h" +#include "vgui/IInput.h" +#include "movieobjects/dmeeditortypedictionary.h" +#include "dme_controls/inotifyui.h" + +using namespace vgui; + +// ---------------------------------------------------------------------------- +// CAttributeTextEntry + +CAttributeTextEntry::CAttributeTextEntry( Panel *parent, const char *panelName ) : + BaseClass( parent, panelName ), + m_bValueStored( false ), + m_flOriginalValue( 0.0f ) +{ + SetDragEnabled( true ); + SetDropEnabled( true, 0.5f ); + m_szOriginalText[ 0 ] = 0; + AddActionSignalTarget( this ); +} + +void CAttributeTextEntry::ApplySchemeSettings( IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + SetBorder(NULL); + + //HFont font = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() ); + //SetFont(font); +} + + +//----------------------------------------------------------------------------- +// Returns the parent panel +//----------------------------------------------------------------------------- +inline CAttributeTextPanel *CAttributeTextEntry::GetParentAttributePanel() +{ + return static_cast< CAttributeTextPanel * >( GetParent() ); +} + + +//----------------------------------------------------------------------------- +// Drag + drop +//----------------------------------------------------------------------------- +bool CAttributeTextEntry::GetDropContextMenu( Menu *menu, CUtlVector< KeyValues * >& msglist ) +{ + menu->AddMenuItem( "Drop as Text", "#BxDropText", "droptext", this ); + return true; +} + +bool CAttributeTextEntry::IsDroppable( CUtlVector< KeyValues * >& msglist ) +{ + if ( !IsEnabled() ) + return false; + + if ( msglist.Count() != 1 ) + return false; + + KeyValues *msg = msglist[ 0 ]; + + Panel *draggedPanel = ( Panel * )msg->GetPtr( "panel", NULL ); + if ( draggedPanel == GetParent() ) + return false; + + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + if ( !pPanel ) + return false; + + // If a specific text type is specified, then filter if it doesn't match + const char *pTextType = pPanel->GetTextType(); + if ( pTextType[0] ) + { + const char *pMsgTextType = msg->GetString( "texttype" ); + if ( Q_stricmp( pTextType, pMsgTextType ) ) + return false; + } + + DmAttributeType_t t = pPanel->GetAttributeType(); + switch ( t ) + { + default: + break; + case AT_ELEMENT: + { + CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( msg->GetInt( "root" ) ) ) ); + if ( ptr ) + { + return true; + } + return false; + } + break; + + case AT_ELEMENT_ARRAY: + return false; + } + + return true; +} + +void CAttributeTextEntry::OnPanelDropped( CUtlVector< KeyValues * >& msglist ) +{ + if ( msglist.Count() != 1 ) + return; + + KeyValues *data = msglist[ 0 ]; + Panel *draggedPanel = ( Panel * )data->GetPtr( "panel", NULL ); + if ( draggedPanel == GetParent() ) + return; + + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + if ( !pPanel ) + return; + + // If a specific text type is specified, then filter if it doesn't match + const char *pTextType = pPanel->GetTextType(); + if ( pTextType[0] ) + { + const char *pMsgTextType = data->GetString( "texttype" ); + if ( Q_stricmp( pTextType, pMsgTextType ) ) + return; + } + + const char *cmd = data->GetString( "command" ); + if ( !Q_stricmp( cmd, "droptext" ) || !Q_stricmp( cmd, "default" ) ) + { + DmAttributeType_t t = pPanel->GetAttributeType(); + switch ( t ) + { + default: + { + pPanel->SetDirty( true ); + SetText( data->GetString( "text" ) ); + if ( pPanel->IsAutoApply() ) + { + pPanel->Apply(); + } + } + break; + + case AT_ELEMENT: + { + CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( data->GetInt( "root" ) ) ) ); + if ( !ptr ) + { + break; + } + pPanel->SetDirty( true ); + SetText( data->GetString( "text" ) ); + if ( pPanel->IsAutoApply() ) + { + pPanel->Apply(); + } + } + break; + case AT_ELEMENT_ARRAY: + Assert( 0 ); + break; + } + } + + StoreInitialValue( true ); +} + + +//----------------------------------------------------------------------------- +// Enter causes changes to be applied +//----------------------------------------------------------------------------- +void CAttributeTextEntry::OnKeyCodeTyped(KeyCode code) +{ + bool bCtrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL)); + + switch ( code ) + { + case KEY_ENTER: + { + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + if ( !pPanel->IsAutoApply() ) + { + pPanel->Apply(); + StoreInitialValue( true ); + } + else + { + WriteValueToAttribute(); + } + } + break; + + // Override the base class undo feature, it behaves poorly when typing in data + case KEY_Z: + if ( bCtrl ) + { + WriteInitialValueToAttribute( ); + break; + } + + // NOTE: Fall through to default if it's not Ctrl-Z + + default: + BaseClass::OnKeyCodeTyped(code); + break; + } +} + + +void CAttributeTextEntry::OnTextChanged( KeyValues *data ) +{ + m_bValueStored = true; +} + + +//----------------------------------------------------------------------------- +// We'll only create an "undo" record if the values differ upon focus change +//----------------------------------------------------------------------------- +void CAttributeTextEntry::StoreInitialValue( bool bForce ) +{ + // Already storing value??? + if ( m_bValueStored && !bForce ) + return; + + m_bValueStored = true; + + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + Assert( pPanel ); + + switch ( pPanel->GetAttributeType() ) + { + case AT_FLOAT: + m_flOriginalValue = pPanel->GetAttributeValue<float>( ); + break; + case AT_INT: + m_nOriginalValue = pPanel->GetAttributeValue<int>( ); + break; + case AT_BOOL: + m_bOriginalValue = pPanel->GetAttributeValue<bool>( ); + break; + default: + GetText( m_szOriginalText, sizeof( m_szOriginalText ) ); + break; + } +} + + +//----------------------------------------------------------------------------- +// Performs undo +//----------------------------------------------------------------------------- +void CAttributeTextEntry::WriteInitialValueToAttribute( ) +{ + // Already storing value??? + if ( !m_bValueStored ) + return; + + CDisableUndoScopeGuard guard; + + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + Assert( pPanel ); + + switch ( pPanel->GetAttributeType() ) + { + case AT_FLOAT: + pPanel->SetAttributeValue( m_flOriginalValue ); + break; + case AT_INT: + pPanel->SetAttributeValue( m_nOriginalValue ); + break; + case AT_BOOL: + pPanel->SetAttributeValue<bool>( m_bOriginalValue ); + break; + default: + pPanel->SetAttributeValueFromString( m_szOriginalText ); + break; + } + + pPanel->SetDirty( false ); + pPanel->Refresh(); +} + + +//----------------------------------------------------------------------------- +// We'll only create an "undo" record if the values differ upon focus change +//----------------------------------------------------------------------------- +void CAttributeTextEntry::OnSetFocus() +{ + BaseClass::OnSetFocus(); + StoreInitialValue(); +} + + +//----------------------------------------------------------------------------- +// Called when focus is lost +//----------------------------------------------------------------------------- +template<class T> +void CAttributeTextEntry::ApplyMouseWheel( T newValue, T originalValue ) +{ + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + + // Kind of an evil hack, but "undo" copies the "old value" off for doing undo, and that value is the new value because + // we haven't been tracking undo while manipulating this. So we'll turn off undo and set the value to the original value. + + // In effect, all of the wheeling will drop out and it'll look just like we started at the original value and ended up at the + // final value... + { + CDisableUndoScopeGuard guard; + pPanel->SetAttributeValue( originalValue ); + } + + if ( pPanel->IsAutoApply() ) + { + pPanel->Apply(); + } + else + { + CElementTreeUndoScopeGuard guard( 0, pPanel->GetNotify(), "Set Attribute Value", "Set Attribute Value" ); + pPanel->SetAttributeValue( newValue ); + } +} + + +void CAttributeTextEntry::WriteValueToAttribute() +{ + if ( !m_bValueStored ) + return; + + m_bValueStored = false; + + char newText[ MAX_TEXT_LENGTH ]; + GetText( newText, sizeof( newText ) ); + + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + Assert( pPanel ); + switch (pPanel->GetAttributeType() ) + { + case AT_FLOAT: + ApplyMouseWheel( (float)atof(newText), m_flOriginalValue ); + break; + case AT_INT: + ApplyMouseWheel( atoi(newText), m_nOriginalValue ); + break; + case AT_BOOL: + ApplyMouseWheel( atoi(newText) != 0, m_bOriginalValue ); + break; + default: + if ( Q_strcmp( newText, m_szOriginalText ) ) + { + pPanel->SetDirty( true ); + if ( pPanel->IsAutoApply() ) + { + pPanel->Apply(); + StoreInitialValue( true ); + } + } + else + { + pPanel->SetDirty( false ); + } + break; + } +} + + +//----------------------------------------------------------------------------- +// Called when focus is lost +//----------------------------------------------------------------------------- +void CAttributeTextEntry::OnKillFocus() +{ + BaseClass::OnKillFocus(); + WriteValueToAttribute(); + StoreInitialValue(); +} + +void CAttributeTextEntry::OnMouseWheeled( int delta ) +{ + // Must have *keyboard* focus for it to work + if ( !HasFocus() ) + { + // Otherwise, let the base class scroll up + down + BaseClass::OnMouseWheeled( delta ); + return; + } + + CAttributeTextPanel *pPanel = GetParentAttributePanel(); + if ( pPanel->GetDirty() ) + { + if ( pPanel->IsAutoApply() ) + { + pPanel->Apply(); + StoreInitialValue( true ); + } + else + { + // FIXME: Make this work for non-auto-apply panels + } + } + + switch ( pPanel->GetAttributeType() ) + { + case AT_FLOAT: + { + float deltaFactor; + if ( input()->IsKeyDown(KEY_LSHIFT) ) + { + deltaFactor = ((float)delta) * 10.0f; + } + else if ( input()->IsKeyDown(KEY_LCONTROL) ) + { + deltaFactor = ((float)delta) / 100.0; + } + else + { + deltaFactor = ((float)delta) / 10.0; + } + + float val = pPanel->GetAttributeValue<float>() + deltaFactor; + + if ( input()->IsKeyDown(KEY_LALT) ) + { + //val = clamp(val, 0.0, 1.0); + val = (val > 1) ? 1 : ((val < 0) ? 0 : val); + } + + { + // Note, these calls to Set won't create Undo Records, + // since we'll check the value in SetFocus/KillFocus so that we + // don't gum up the undo system with hundreds of records... + CDisableUndoScopeGuard guard; + pPanel->SetAttributeValue( val ); + } + } + break; + + case AT_INT: + { + if ( input()->IsKeyDown(KEY_LSHIFT) ) + { + delta *= 10; + } + + int val = pPanel->GetAttributeValue<int>() + delta; + + { + // Note, these calls to Set won't create Undo Records, + // since we'll check the value in SetFocus/KillFocus so that we + // don't gum up the undo system with hundreds of records... + CDisableUndoScopeGuard guard; + pPanel->SetAttributeValue( val ); + } + } + break; + + case AT_BOOL: + { + bool val = !pPanel->GetAttributeValue<bool>(); + + { + // Note, these calls to Set won't create Undo Records, + // since we'll check the value in SetFocus/KillFocus so that we + // don't gum up the undo system with hundreds of records... + CDisableUndoScopeGuard guard; + pPanel->SetAttributeValue( val ); + } + } + break; + + default: + return; + } + + pPanel->Refresh(); + if ( pPanel->IsAutoApply() ) + { + // NOTE: Don't call Apply since that generates an undo record + CElementTreeNotifyScopeGuard notify( "CAttributeTextEntry::OnMouseWheeled", NOTIFY_CHANGE_ATTRIBUTE_VALUE | NOTIFY_SETDIRTYFLAG, pPanel->GetNotify() ); + } + else + { + pPanel->SetDirty( true ); + } + + //SetDirty(true); + //UpdateTime( m_flLastMouseTime ); + //UpdateZoom( -10.0f * delta ); + //UpdateTransform(); +} + +// ---------------------------------------------------------------------------- |