summaryrefslogtreecommitdiff
path: root/vgui2/dme_controls/BaseAnimSetControlGroupPanel.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /vgui2/dme_controls/BaseAnimSetControlGroupPanel.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'vgui2/dme_controls/BaseAnimSetControlGroupPanel.cpp')
-rw-r--r--vgui2/dme_controls/BaseAnimSetControlGroupPanel.cpp523
1 files changed, 523 insertions, 0 deletions
diff --git a/vgui2/dme_controls/BaseAnimSetControlGroupPanel.cpp b/vgui2/dme_controls/BaseAnimSetControlGroupPanel.cpp
new file mode 100644
index 0000000..abbafef
--- /dev/null
+++ b/vgui2/dme_controls/BaseAnimSetControlGroupPanel.cpp
@@ -0,0 +1,523 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+#include "dme_controls/BaseAnimSetControlGroupPanel.h"
+#include "vgui_controls/TreeView.h"
+#include "vgui_controls/Menu.h"
+#include "tier1/KeyValues.h"
+#include "movieobjects/dmeanimationset.h"
+#include "dme_controls/BaseAnimSetAttributeSliderPanel.h"
+#include "dme_controls/BaseAnimationSetEditor.h"
+#include "dme_controls/dmecontrols_utils.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+
+//-----------------------------------------------------------------------------
+// Shows the tree view of the animation groups
+//-----------------------------------------------------------------------------
+class CAnimGroupTree : public TreeView
+{
+ DECLARE_CLASS_SIMPLE( CAnimGroupTree, TreeView );
+public:
+ CAnimGroupTree( Panel *parent, const char *panelName, CBaseAnimSetControlGroupPanel *groupPanel );
+ virtual ~CAnimGroupTree();
+
+ virtual bool IsItemDroppable( int itemIndex, CUtlVector< KeyValues * >& msglist );
+ virtual void OnItemDropped( int itemIndex, CUtlVector< KeyValues * >& msglist );
+ virtual void GenerateContextMenu( int itemIndex, int x, int y );
+
+private:
+ MESSAGE_FUNC( OnImportAnimation, "ImportAnimation" );
+
+ void CleanupContextMenu();
+
+ vgui::DHANDLE< vgui::Menu > m_hContextMenu;
+ CBaseAnimSetControlGroupPanel *m_pGroupPanel;
+};
+
+CAnimGroupTree::CAnimGroupTree( Panel *parent, const char *panelName, CBaseAnimSetControlGroupPanel *groupPanel ) :
+ BaseClass( parent, panelName ),
+ m_pGroupPanel( groupPanel )
+{
+}
+
+CAnimGroupTree::~CAnimGroupTree()
+{
+ CleanupContextMenu();
+}
+
+void CAnimGroupTree::CleanupContextMenu()
+{
+ if ( m_hContextMenu.Get() )
+ {
+ delete m_hContextMenu.Get();
+ m_hContextMenu = NULL;
+ }
+}
+
+bool CAnimGroupTree::IsItemDroppable( int itemIndex, CUtlVector< KeyValues * >& msglist )
+{
+ if ( msglist.Count() != 1 )
+ return false;
+
+ KeyValues *data = msglist[ 0 ];
+ if ( !data )
+ return false;
+
+ if ( !data->FindKey( "color" ) )
+ return false;
+
+ KeyValues *itemData = GetItemData( itemIndex );
+ if ( !itemData->FindKey( "handle" ) )
+ return false;
+ DmElementHandle_t handle = (DmElementHandle_t)itemData->GetInt( "handle" );
+ if ( handle == DMELEMENT_HANDLE_INVALID )
+ return false;
+
+ return true;
+}
+
+void CAnimGroupTree::OnItemDropped( int itemIndex, CUtlVector< KeyValues * >& msglist )
+{
+ if ( !IsItemDroppable( itemIndex, msglist ) )
+ return;
+
+ KeyValues *data = msglist[ 0 ];
+ if ( !data )
+ return;
+
+ KeyValues *itemData = GetItemData( itemIndex );
+
+ CDmElement *group = GetElementKeyValue< CDmElement >( itemData, "handle" );
+ Assert( m_pGroupPanel );
+ Color clr = data->GetColor( "color" );
+ SetItemFgColor( itemIndex, clr );
+ SetItemSelectionTextColor( itemIndex, clr );
+
+ if ( group )
+ {
+ CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Change Group Color" );
+ group->SetValue< Color >( "treeColor", clr );
+ }
+}
+
+void CAnimGroupTree::OnImportAnimation()
+{
+ PostMessage( m_pGroupPanel->m_hEditor, new KeyValues( "ImportAnimation", "visibleOnly", "1" ), 0.0f );
+}
+
+// override to open a custom context menu on a node being selected and right-clicked
+void CAnimGroupTree::GenerateContextMenu( int itemIndex, int x, int y )
+{
+ CleanupContextMenu();
+ m_hContextMenu = new Menu( this, "ActionMenu" );
+ m_hContextMenu->AddMenuItem( "#ImportAnimation", new KeyValues( "ImportAnimation" ), this );
+ Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
+}
+
+
+
+CBaseAnimSetControlGroupPanel::CBaseAnimSetControlGroupPanel( vgui::Panel *parent, const char *className, CBaseAnimationSetEditor *editor ) :
+ BaseClass( parent, className ),
+ m_bStartItemWasSelected( false ),
+ m_SliderNames( 0, 0, true )
+{
+ m_hEditor = editor;
+ m_hGroups = new CAnimGroupTree( this, "AnimSetGroups", this );
+ m_hGroups->SetMultipleItemDragEnabled( true );
+ m_hGroups->SetAutoResize
+ (
+ Panel::PIN_TOPLEFT,
+ Panel::AUTORESIZE_DOWNANDRIGHT,
+ 0, 0,
+ 0, 0
+ );
+ m_hGroups->SetAllowMultipleSelections( true );
+}
+
+CBaseAnimSetControlGroupPanel::~CBaseAnimSetControlGroupPanel()
+{
+}
+
+static int AddItemToTree( TreeView *tv, const char *label, int parentIndex, const Color& fg, int groupNumber, int handle )
+{
+ Color bgColor( 128, 128, 128, 128 );
+
+ KeyValues *kv = new KeyValues( "item", "text", label );
+ kv->SetInt( "groupNumber", groupNumber );
+ kv->SetInt( "droppable", 1 );
+ kv->SetInt( "handle", handle );
+ int idx = tv->AddItem( kv, parentIndex );
+ tv->SetItemFgColor( idx, fg );
+ tv->SetItemSelectionTextColor( idx, fg );
+ tv->SetItemSelectionBgColor( idx, bgColor );
+ tv->SetItemSelectionUnfocusedBgColor( idx, bgColor );
+
+ tv->RemoveSelectedItem( idx );
+ tv->ExpandItem( idx, false );
+
+ kv->deleteThis();
+
+ return idx;
+}
+
+void CBaseAnimSetControlGroupPanel::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+ m_hGroups->SetFont( pScheme->GetFont( "DefaultBold", IsProportional() ) );
+}
+
+void CBaseAnimSetControlGroupPanel::OnTreeViewItemSelectionCleared()
+{
+ // We check the entire group manually
+ OnTreeViewItemSelected( -1 );
+}
+
+void CBaseAnimSetControlGroupPanel::OnTreeViewItemDeselected( int itemIndex )
+{
+ OnTreeViewItemSelected( -1 );
+}
+
+void CBaseAnimSetControlGroupPanel::OnTreeViewItemSelected( int itemIndex )
+{
+ if ( !m_AnimSet.Get() )
+ return;
+
+ // Build the list of selected groups, and notify the attribute slider panel
+ CUtlVector< int > selection;
+ m_hGroups->GetSelectedItems( selection );
+
+ const CDmaElementArray<> &groups = m_AnimSet->GetSelectionGroups();
+ int groupCount = groups.Count();
+
+ int i;
+ int rootIndex = m_hGroups->GetRootItemIndex();
+
+ bool selectionHasRoot = false;
+ for ( i = 0 ; i < selection.Count(); ++i )
+ {
+ if ( selection[ i ] == rootIndex )
+ {
+ selectionHasRoot = true;
+ break;
+ }
+ }
+
+ m_SliderNames.RemoveAll();
+
+ if ( selectionHasRoot )
+ {
+ for ( i = 0; i < groups.Count(); ++i )
+ {
+ CDmElement *element = groups[ i ];
+ if ( !element )
+ continue;
+
+ const CDmrStringArray array( element, "selectedControls" );
+ if ( array.IsValid() )
+ {
+ for ( int j = 0 ; j < array.Count(); ++j )
+ {
+ const char *sliderName = array[ j ];
+ if ( sliderName && *sliderName )
+ {
+ m_SliderNames.AddString( sliderName );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for ( i = 0 ; i < selection.Count(); ++i )
+ {
+ if ( selection[ i ] == rootIndex )
+ continue;
+
+ KeyValues *kv = m_hGroups->GetItemData( selection[ i ] );
+ if ( !kv )
+ continue;
+
+ int groupNumber = kv->GetInt( "groupNumber" );
+ if ( groupNumber < 0 || groupNumber >= groupCount )
+ {
+ const char *sliderName = kv->GetString( "text" );
+ if ( sliderName && *sliderName )
+ {
+ m_SliderNames.AddString( sliderName );
+ }
+ continue;
+ }
+
+ CDmElement *element = groups[ groupNumber ];
+ if ( !element )
+ continue;
+
+ const CDmrStringArray array( element, "selectedControls" );
+ if ( array.IsValid() )
+ {
+ for ( int j = 0 ; j < array.Count(); ++j )
+ {
+ const char *sliderName = array[ j ];
+ if ( sliderName && *sliderName )
+ {
+ m_SliderNames.AddString( sliderName );
+ }
+ }
+ }
+ }
+ }
+
+ // now notify the attribute slider panel
+ CBaseAnimSetAttributeSliderPanel *attSliders = m_hEditor->GetAttributeSlider();
+ if ( attSliders )
+ {
+ attSliders->SetVisibleControlsForSelectionGroup( m_SliderNames );
+ }
+}
+
+void CBaseAnimSetControlGroupPanel::ChangeAnimationSet( CDmeAnimationSet *newAnimSet )
+{
+ bool changed = m_AnimSet.Get() != newAnimSet ? true : false;
+
+ m_AnimSet = newAnimSet;
+
+ if ( !m_AnimSet.Get() )
+ {
+ m_hGroups->RemoveAll();
+ m_hSelectableIndices.RemoveAll();
+ m_GroupList.RemoveAll();
+ return;
+ }
+
+ // Compare groups
+ bool bRebuildGroups = false;
+ const CDmaElementArray< CDmElement > &groups = m_AnimSet->GetSelectionGroups();
+ int c = groups.Count();
+ if ( c != m_GroupList.Count() )
+ {
+ bRebuildGroups = true;
+ }
+ else
+ {
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmElement *group = groups[ i ];
+ if ( group == m_GroupList[ i ].Get() )
+ {
+ continue;
+ }
+
+ bRebuildGroups = true;
+ break;
+ }
+ }
+
+ if ( bRebuildGroups )
+ {
+ m_hGroups->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultBold", IsProportional() ) );
+
+ // Build a tree of every open item in the tree view
+ OpenItemTree_t openItems;
+ int nRootIndex = m_hGroups->GetRootItemIndex();
+ if ( nRootIndex != -1 )
+ {
+ BuildOpenItemList( openItems, openItems.InvalidIndex(), nRootIndex );
+ }
+
+ m_hGroups->RemoveAll();
+ m_hSelectableIndices.RemoveAll();
+ m_GroupList.RemoveAll();
+
+
+ // Create root
+ int rootIndex = AddItemToTree( m_hGroups, "root", -1, Color( 128, 128, 128, 255 ), -1, (int)DMELEMENT_HANDLE_INVALID );
+
+ Color defaultColor( 0, 128, 255, 255 );
+
+ CAppUndoScopeGuard *guard = NULL;
+
+ for ( int i = 0; i < c; ++i )
+ {
+ CDmElement *group = groups[ i ];
+
+ if ( !group->HasAttribute( "treeColor" ) )
+ {
+ if ( !guard )
+ {
+ guard = new CAppUndoScopeGuard( NOTIFY_SETDIRTYFLAG, "Set Default Colors" );
+ }
+ group->SetValue< Color >( "treeColor", defaultColor );
+ }
+ int groupIndex = AddItemToTree( m_hGroups, group->GetName(), rootIndex, group->GetValue< Color >( "treeColor" ), i, (int)group->GetHandle() );
+
+ const CDmrStringArray array( group, "selectedControls" );
+ if ( array.IsValid() )
+ {
+ for ( int j = 0 ; j < array.Count(); ++j )
+ {
+ AddItemToTree( m_hGroups, array[ j ], groupIndex, Color( 200, 200, 200, 255 ), -1, (int)DMELEMENT_HANDLE_INVALID );
+ }
+ }
+ m_hSelectableIndices.AddToTail( groupIndex );
+
+ m_GroupList.AddToTail( group->GetHandle() );
+ }
+
+ if ( ( nRootIndex >= 0 ) && ( rootIndex >= 0 ) && !changed )
+ {
+ // Iterate through all previously open items and expand them if they exist
+ if ( openItems.Root() != openItems.InvalidIndex() )
+ {
+ ExpandOpenItems( openItems, openItems.Root(), rootIndex, true );
+ }
+ }
+ else
+ {
+ m_hGroups->ExpandItem( rootIndex, true );
+ }
+
+ if ( guard )
+ {
+ delete guard;
+ }
+ }
+
+ if ( changed )
+ {
+ for ( int i = 0; i < m_hSelectableIndices.Count(); ++i )
+ {
+
+ m_hGroups->AddSelectedItem( m_hSelectableIndices[ i ],
+ false, // don't clear selection
+ true, // put focus on tree
+ false ); // don't expand tree to make all of these visible...
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Expands all items in the open item tree if they exist
+//-----------------------------------------------------------------------------
+void CBaseAnimSetControlGroupPanel::ExpandOpenItems( OpenItemTree_t &tree, int nOpenTreeIndex, int nItemIndex, bool makeVisible )
+{
+ int i = tree.FirstChild( nOpenTreeIndex );
+ if ( nOpenTreeIndex != tree.InvalidIndex() )
+ {
+ TreeInfo_t& info = tree[ nOpenTreeIndex ];
+ if ( info.m_nFlags & EP_EXPANDED )
+ {
+ // Expand the item
+ m_hGroups->ExpandItem( nItemIndex , true );
+ }
+ if ( info.m_nFlags & EP_SELECTED )
+ {
+ m_hGroups->AddSelectedItem( nItemIndex, false, false );
+ if ( makeVisible )
+ {
+ m_hGroups->MakeItemVisible( nItemIndex );
+ }
+ }
+ }
+
+ while ( i != tree.InvalidIndex() )
+ {
+ TreeInfo_t& info = tree[ i ];
+ // Look for a match
+ int nChildIndex = FindTreeItem( nItemIndex, info.m_Item );
+ if ( nChildIndex != -1 )
+ {
+ ExpandOpenItems( tree, i, nChildIndex, makeVisible );
+ }
+ else
+ {
+ if ( info.m_nFlags & EP_SELECTED )
+ {
+ // Look for preserved item
+ nChildIndex = FindTreeItem( nItemIndex, info.m_Item );
+ if ( nChildIndex != -1 )
+ {
+ m_hGroups->AddSelectedItem( nChildIndex, false, false );
+ if ( makeVisible )
+ {
+ m_hGroups->MakeItemVisible( nChildIndex );
+ }
+ }
+ }
+ }
+ i = tree.NextSibling( i );
+ }
+}
+
+void CBaseAnimSetControlGroupPanel::FillInDataForItem( TreeItem_t &item, int nItemIndex )
+{
+ KeyValues *data = m_hGroups->GetItemData( nItemIndex );
+ if ( !data )
+ return;
+
+ item.m_pAttributeName = data->GetString( "text" );
+}
+
+//-----------------------------------------------------------------------------
+// Builds a list of open items
+//-----------------------------------------------------------------------------
+void CBaseAnimSetControlGroupPanel::BuildOpenItemList( OpenItemTree_t &tree, int nParent, int nItemIndex )
+{
+ KeyValues *data = m_hGroups->GetItemData( nItemIndex );
+ if ( !data )
+ return;
+
+ bool expanded = m_hGroups->IsItemExpanded( nItemIndex );
+ bool selected = m_hGroups->IsItemSelected( nItemIndex );
+
+ int flags = 0;
+ if ( expanded )
+ {
+ flags |= EP_EXPANDED;
+ }
+ if ( selected )
+ {
+ flags |= EP_SELECTED;
+ }
+
+ int nChild = tree.InsertChildAfter( nParent, tree.InvalidIndex() );
+ TreeInfo_t &info = tree[nChild];
+ FillInDataForItem( info.m_Item, nItemIndex );
+ info.m_nFlags = flags;
+
+ // Deal with children
+ int nCount = m_hGroups->GetNumChildren( nItemIndex );
+ for ( int i = 0; i < nCount; ++i )
+ {
+ int nChildIndex = m_hGroups->GetChild( nItemIndex, i );
+ BuildOpenItemList( tree, nChild, nChildIndex );
+ }
+}
+//-----------------------------------------------------------------------------
+// Finds the tree index of a child matching the particular element + attribute
+//-----------------------------------------------------------------------------
+int CBaseAnimSetControlGroupPanel::FindTreeItem( int nParentIndex, const TreeItem_t &info )
+{
+ // Look for a match
+ int nCount = m_hGroups->GetNumChildren( nParentIndex );
+ for ( int i = nCount; --i >= 0; )
+ {
+ int nChildIndex = m_hGroups->GetChild( nParentIndex, i );
+ KeyValues *data = m_hGroups->GetItemData( nChildIndex );
+ Assert( data );
+
+ const char *pAttributeName = data->GetString( "text" );
+ if ( !Q_stricmp( pAttributeName, info.m_pAttributeName ) )
+ {
+ return nChildIndex;
+ }
+ }
+ return -1;
+}