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.
2150 lines
73 KiB
2150 lines
73 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//============================================================================= |
|
|
|
#include "dme_controls/dmecombinationsystemeditorpanel.h" |
|
#include "dme_controls/dmepanel.h" |
|
#include "dme_controls/elementpropertiestree.h" |
|
#include "dme_controls/dmecontrols_utils.h" |
|
#include "movieobjects/dmecombinationoperator.h" |
|
#include "vgui_controls/ListPanel.h" |
|
#include "vgui_controls/PropertySheet.h" |
|
#include "vgui_controls/PropertyPage.h" |
|
#include "vgui_controls/Button.h" |
|
#include "vgui_controls/Menu.h" |
|
#include "vgui_controls/Splitter.h" |
|
#include "vgui_controls/MessageBox.h" |
|
#include "vgui_controls/InputDialog.h" |
|
#include "vgui_controls/TextEntry.h" |
|
#include "vgui_controls/FileOpenDialog.h" |
|
#include "vgui_controls/perforcefilelistframe.h" |
|
#include "vgui/MouseCode.h" |
|
#include "vgui/IInput.h" |
|
#include "tier1/KeyValues.h" |
|
#include "tier2/fileutils.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Hook into the dme panel editor system |
|
// |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_DMEPANEL_FACTORY( CDmeCombinationSystemEditorPanel, DmeCombinationOperator, "DmeCombinationOperatorEditor", "Combination Operator Editor", true ); |
|
|
|
|
|
// Forward declaration |
|
class CDmeCombinationControlsPanel; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Import combination rules from this operator |
|
//----------------------------------------------------------------------------- |
|
static void ImportCombinationControls( CDmeCombinationOperator *pDestComboOp, CDmeCombinationOperator *pSrcComboOp, COperationFileListFrame *pStatusFrame ) |
|
{ |
|
pDestComboOp->RemoveAllControls(); |
|
|
|
// Iterate through all controls in the imported operator. |
|
// For each control that contains at least 1 raw controls |
|
// that also exist in this combination op, create a control here also. |
|
int nCount = pSrcComboOp->GetControlCount(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
const char *pControlName = pSrcComboOp->GetControlName( i ); |
|
|
|
int nRawControls = pSrcComboOp->GetRawControlCount( i ); |
|
int nMatchCount = 0; |
|
bool *pFoundMatch = (bool*)_alloca( nRawControls * sizeof(bool) ); |
|
for ( int j = 0; j < nRawControls; ++j ) |
|
{ |
|
const char *pRawControl = pSrcComboOp->GetRawControlName( i, j ); |
|
pFoundMatch[j] = pDestComboOp->DoesTargetContainDeltaState( pRawControl ); |
|
nMatchCount += pFoundMatch[j]; |
|
} |
|
|
|
// No match? Don't import |
|
if ( nMatchCount == 0 ) |
|
{ |
|
pStatusFrame->AddOperation( pControlName, "No raw controls found!" ); |
|
continue; |
|
} |
|
|
|
bool bPartialMatch = ( nMatchCount != nRawControls ); |
|
pStatusFrame->AddOperation( pControlName, bPartialMatch ? "Partial rule match" : "Successful" ); |
|
|
|
// Found a match! Let's create the control and potentially raw control |
|
bool bIsStereo = pSrcComboOp->IsStereoControl( i ); |
|
bool bIsEyelid = pSrcComboOp->IsEyelidControl( i ); |
|
ControlIndex_t index = pDestComboOp->FindOrCreateControl( pControlName, bIsStereo ); |
|
pDestComboOp->SetEyelidControl( index, bIsEyelid ); |
|
for ( int j = 0; j < nRawControls; ++j ) |
|
{ |
|
if ( pFoundMatch[j] ) |
|
{ |
|
const char *pRawControl = pSrcComboOp->GetRawControlName( i, j ); |
|
float flWrinkleScale = pSrcComboOp->GetRawControlWrinkleScale( i, j ); |
|
|
|
pDestComboOp->AddRawControl( index, pRawControl ); |
|
pDestComboOp->SetWrinkleScale( index, pRawControl, flWrinkleScale ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Import dominance rules from this operator |
|
//----------------------------------------------------------------------------- |
|
static void ImportDominationRules( CDmeCombinationOperator *pDestComboOp, CDmeCombinationOperator *pSrcComboOp, COperationFileListFrame *pStatusFrame ) |
|
{ |
|
pDestComboOp->RemoveAllDominationRules(); |
|
|
|
// Now deal with dominance rules |
|
int nRuleCount = pSrcComboOp->DominationRuleCount(); |
|
for ( int i = 0; i < nRuleCount; ++i ) |
|
{ |
|
bool bMismatch = false; |
|
|
|
// Only add dominance rule if *all* raw controls are present |
|
CDmeCombinationDominationRule *pSrcRule = pSrcComboOp->GetDominationRule( i ); |
|
int nDominatorCount = pSrcRule->DominatorCount(); |
|
for ( int j = 0; j < nDominatorCount; ++j ) |
|
{ |
|
const char *pDominatorName = pSrcRule->GetDominator( j ); |
|
if ( !pDestComboOp->HasRawControl( pDominatorName ) ) |
|
{ |
|
bMismatch = true; |
|
pStatusFrame->AddOperation( pDominatorName, "Missing raw control for dominance rule" ); |
|
break; |
|
} |
|
} |
|
|
|
int nSuppressedCount = pSrcRule->SuppressedCount(); |
|
for ( int j = 0; j < nSuppressedCount; ++j ) |
|
{ |
|
const char *pSuppressedName = pSrcRule->GetSuppressed( j ); |
|
if ( !pDestComboOp->HasRawControl( pSuppressedName ) ) |
|
{ |
|
bMismatch = true; |
|
pStatusFrame->AddOperation( pSuppressedName, "Missing raw control for dominance rule" ); |
|
break; |
|
} |
|
} |
|
|
|
if ( bMismatch ) |
|
continue; |
|
|
|
pDestComboOp->AddDominationRule( pSrcRule ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the file open dialog for browsing source files selects something |
|
//----------------------------------------------------------------------------- |
|
static bool ImportCombinationData( vgui::Panel* pParent, CDmeCombinationOperator *pDestComboOp, KeyValues *kv ) |
|
{ |
|
const char *pFileName = kv->GetString( "fullpath", NULL ); |
|
if ( !pFileName ) |
|
return false; |
|
|
|
CDmElement *pRoot; |
|
|
|
{ |
|
CDisableUndoScopeGuard sg; |
|
g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pRoot, CR_FORCE_COPY ); |
|
} |
|
|
|
if ( !pRoot ) |
|
return false; |
|
|
|
// Try to find a combination system in the file |
|
CDmeCombinationOperator *pComboOp = CastElement<CDmeCombinationOperator>( pRoot ); |
|
if ( !pComboOp ) |
|
{ |
|
pComboOp = pRoot->GetValueElement< CDmeCombinationOperator >( "combinationOperator" ); |
|
} |
|
|
|
if ( pComboOp ) |
|
{ |
|
// Actually rename the files, build an error dialog if necessary |
|
COperationFileListFrame *pStatusFrame = new COperationFileListFrame( pParent, |
|
"Import Status", "Status", false, true ); |
|
pStatusFrame->SetOperationColumnHeaderText( "Control Name" ); |
|
|
|
CUndoScopeGuard sg( "Import Combination Rules" ); |
|
if ( kv->FindKey( "ImportControls" ) ) |
|
{ |
|
ImportCombinationControls( pDestComboOp, pComboOp, pStatusFrame ); |
|
} |
|
ImportDominationRules( pDestComboOp, pComboOp, pStatusFrame ); |
|
sg.Release(); |
|
|
|
pStatusFrame->DoModal(); |
|
} |
|
|
|
CDisableUndoScopeGuard sg; |
|
g_pDataModel->UnloadFile( pRoot->GetFileId() ); |
|
sg.Release(); |
|
|
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// |
|
// CDmeInputControlListPanel |
|
// |
|
// Implementation below because of scoping issues |
|
// |
|
// |
|
//----------------------------------------------------------------------------- |
|
class CDmeInputControlListPanel : public vgui::ListPanel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CDmeInputControlListPanel, vgui::ListPanel ); |
|
|
|
public: |
|
// constructor, destructor |
|
CDmeInputControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel ); |
|
|
|
virtual void OnCreateDragData( KeyValues *msg ); |
|
virtual bool IsDroppable( CUtlVector< KeyValues * >& msgList ); |
|
virtual void OnPanelDropped( CUtlVector< KeyValues * >& msgList ); |
|
virtual void OnKeyCodeTyped( vgui::KeyCode code ); |
|
|
|
private: |
|
CDmeCombinationControlsPanel *m_pComboPanel; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// |
|
// CDmeRawControlListPanel |
|
// |
|
// Implementation below because of scoping issues |
|
// |
|
// |
|
//----------------------------------------------------------------------------- |
|
class CDmeRawControlListPanel : public vgui::ListPanel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CDmeRawControlListPanel, vgui::ListPanel ); |
|
|
|
public: |
|
// constructor, destructor |
|
CDmeRawControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel ); |
|
|
|
virtual void OnKeyCodeTyped( vgui::KeyCode code ); |
|
virtual void OnMouseDoublePressed( vgui::MouseCode code ); |
|
|
|
private: |
|
MESSAGE_FUNC( OnNewWrinkleText, "TextNewLine" ); |
|
|
|
CDmeCombinationControlsPanel *m_pComboPanel; |
|
vgui::TextEntry *m_pWrinkleEdit; |
|
bool m_bIsWrinkle; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// |
|
// Slider panel |
|
// |
|
// |
|
//----------------------------------------------------------------------------- |
|
class CDmeCombinationControlsPanel : public vgui::EditablePanel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CDmeCombinationControlsPanel, vgui::EditablePanel ); |
|
|
|
public: |
|
// constructor, destructor |
|
CDmeCombinationControlsPanel( vgui::Panel *pParent, const char *pName ); |
|
virtual ~CDmeCombinationControlsPanel(); |
|
|
|
void SetCombinationOperator( CDmeCombinationOperator *pOp ); |
|
CDmeCombinationOperator* GetCombinationOperator(); |
|
void RefreshCombinationOperator(); |
|
void NotifyDataChanged(); |
|
|
|
const char *GetSelectedControlName(); |
|
void MoveControlInFrontOf( const char *pDragControl, const char *pDropControl ); |
|
|
|
void SetRawControlWrinkleValue( float flWrinkleValue ); |
|
|
|
int GetSelectedInputControlItemId(); |
|
void SelectedInputControlByItemId( int ); |
|
|
|
MESSAGE_FUNC( OnMoveUpInputControl, "MoveUpInputControl" ); |
|
MESSAGE_FUNC( OnMoveDownInputControl, "MoveDownInputControl" ); |
|
MESSAGE_FUNC( OnMoveUp, "MoveUp" ); |
|
MESSAGE_FUNC( OnMoveDown, "MoveDown" ); |
|
|
|
private: |
|
MESSAGE_FUNC_PARAMS( OnOpenContextMenu, "OpenContextMenu", kv ); |
|
MESSAGE_FUNC_PARAMS( OnInputCompleted, "InputCompleted", kv ); |
|
MESSAGE_FUNC( OnGroupControls, "GroupControls" ); |
|
MESSAGE_FUNC( OnUngroupControls, "UngroupControls" ); |
|
MESSAGE_FUNC( OnRenameControl, "RenameControl" ); |
|
MESSAGE_FUNC( OnImportCombination, "ImportCombination" ); |
|
MESSAGE_FUNC_PARAMS( OnFileSelected, "FileSelected", kv ); |
|
MESSAGE_FUNC( OnToggleStereoControl, "ToggleStereoControl" ); |
|
MESSAGE_FUNC( OnToggleEyelidControl, "ToggleEyelidControl" ); |
|
MESSAGE_FUNC( OnToggleWrinkleType, "ToggleWrinkleType" ); |
|
MESSAGE_FUNC_PARAMS( OnItemSelected, "ItemSelected", kv ); |
|
MESSAGE_FUNC_PARAMS( OnItemDeselected, "ItemDeselected", kv ); |
|
|
|
// Cleans up the context menu |
|
void CleanupContextMenu(); |
|
|
|
// Builds a list of selected control + raw control names, returns true if any control is stereo |
|
void BuildSelectedControlLists( bool bOnlyGroupedControls, CUtlVector< CUtlString >& controlNames, CUtlVector< CUtlString >& rawControlNames, bool *pbStereo = NULL, bool *pbEyelid = NULL ); |
|
|
|
// If it finds a duplicate control name, reports an error message and returns it found one |
|
bool HasDuplicateControlName( const char *pControlName, CUtlVector< CUtlString >& retiredControlNames ); |
|
|
|
// Refreshes the list of raw controls |
|
void RefreshRawControlNames(); |
|
|
|
// Called by OnGroupControls and OnRenameControl after we get a new group name |
|
void PerformGroupControls( const char *pGroupedControlName ); |
|
|
|
// Called by OnGroupControls after we get a new group name |
|
void PerformRenameControl( const char *pNewControlName ); |
|
|
|
// Called to open a context-sensitive menu for a particular menu item |
|
void OnOpenRawControlsContextMenu( ); |
|
|
|
// Called to open a context-sensitive menu for a particular menu item |
|
const char* GetSelectedRawControl( ControlIndex_t &nControlIndex ); |
|
|
|
CDmeHandle< CDmeCombinationOperator > m_hCombinationOperator; |
|
vgui::Splitter *m_pSplitter; |
|
CDmeInputControlListPanel *m_pControlList; |
|
CDmeRawControlListPanel *m_pRawControlList; |
|
vgui::DHANDLE< vgui::Menu > m_hContextMenu; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sort functions for list panel |
|
//----------------------------------------------------------------------------- |
|
static int __cdecl ControlNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 ) |
|
{ |
|
const char *string1 = item1.kv->GetString("name"); |
|
const char *string2 = item2.kv->GetString("name"); |
|
return Q_stricmp( string1, string2 ); |
|
} |
|
|
|
static int __cdecl PeakSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 ) |
|
{ |
|
float flPeak1 = item1.kv->GetFloat("peak"); |
|
float flPeak2 = item2.kv->GetFloat("peak"); |
|
if ( flPeak1 < flPeak2 ) |
|
return -1; |
|
if ( flPeak1 > flPeak2 ) |
|
return 1; |
|
return 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CDmeCombinationControlsPanel::CDmeCombinationControlsPanel( vgui::Panel *pParent, const char *pName ) : |
|
BaseClass( pParent, pName ) |
|
{ |
|
m_pSplitter = new vgui::Splitter( this, "ControlsSplitter", vgui::SPLITTER_MODE_VERTICAL, 1 ); |
|
vgui::Panel *pSplitterLeftSide = m_pSplitter->GetChild( 0 ); |
|
vgui::Panel *pSplitterRightSide = m_pSplitter->GetChild( 1 ); |
|
|
|
m_pControlList = new CDmeInputControlListPanel( pSplitterLeftSide, "ControlList", this ); |
|
m_pControlList->AddColumnHeader( 0, "name", "Control Name", 150, 0 ); |
|
m_pControlList->AddColumnHeader( 1, "stereo", "Stereo", 70, 0 ); |
|
m_pControlList->AddColumnHeader( 2, "eyelid", "Eyelid", 70, 0 ); |
|
m_pControlList->AddColumnHeader( 3, "default", "Default", 52, 0 ); |
|
m_pControlList->SetSelectIndividualCells( false ); |
|
m_pControlList->SetMultiselectEnabled( true ); |
|
m_pControlList->SetEmptyListText( "No controls" ); |
|
m_pControlList->AddActionSignalTarget( this ); |
|
m_pControlList->SetSortFunc( 0, NULL ); |
|
m_pControlList->SetColumnSortable( 0, false ); |
|
m_pControlList->SetSortFunc( 1, NULL ); |
|
m_pControlList->SetColumnSortable( 1, false ); |
|
m_pControlList->SetSortFunc( 2, NULL ); |
|
m_pControlList->SetColumnSortable( 2, false ); |
|
m_pControlList->SetSortFunc( 3, NULL ); |
|
m_pControlList->SetColumnSortable( 3, false ); |
|
m_pControlList->SetDragEnabled( true ); |
|
m_pControlList->SetDragEnabled( true ); |
|
m_pControlList->SetDropEnabled( true ); |
|
|
|
m_pRawControlList = new CDmeRawControlListPanel( pSplitterRightSide, "RawControlList", this ); |
|
m_pRawControlList->AddColumnHeader( 0, "name", "Raw Control Name", 150, 0 ); |
|
m_pRawControlList->AddColumnHeader( 1, "peak", "Peak", 52, 0 ); |
|
m_pRawControlList->AddColumnHeader( 2, "wrinkletype", "Wrinkle Type", 100, 0 ); |
|
m_pRawControlList->AddColumnHeader( 3, "wrinkle", "Wrinkle Amount", 100, 0 ); |
|
m_pRawControlList->SetSelectIndividualCells( false ); |
|
m_pRawControlList->SetEmptyListText( "No raw controls" ); |
|
m_pRawControlList->AddActionSignalTarget( this ); |
|
m_pRawControlList->SetSortFunc( 0, ControlNameSortFunc ); |
|
m_pRawControlList->SetSortFunc( 1, PeakSortFunc ); |
|
m_pRawControlList->SetSortFunc( 2, NULL ); |
|
m_pRawControlList->SetColumnSortable( 2, false ); |
|
m_pRawControlList->SetSortFunc( 3, NULL ); |
|
m_pRawControlList->SetColumnSortable( 3, false ); |
|
m_pRawControlList->SetSortColumn( 1 ); |
|
} |
|
|
|
|
|
CDmeCombinationControlsPanel::~CDmeCombinationControlsPanel() |
|
{ |
|
CleanupContextMenu(); |
|
SaveUserConfig(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Cleans up the context menu |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::CleanupContextMenu() |
|
{ |
|
if ( m_hContextMenu.Get() ) |
|
{ |
|
m_hContextMenu->MarkForDeletion(); |
|
m_hContextMenu = NULL; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the combination operator |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::SetCombinationOperator( CDmeCombinationOperator *pOp ) |
|
{ |
|
if ( pOp != m_hCombinationOperator.Get() ) |
|
{ |
|
m_hCombinationOperator = pOp; |
|
RefreshCombinationOperator(); |
|
} |
|
} |
|
|
|
CDmeCombinationOperator* CDmeCombinationControlsPanel::GetCombinationOperator() |
|
{ |
|
return m_hCombinationOperator; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Builds the control list for the combination operator |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::RefreshCombinationOperator() |
|
{ |
|
const CUtlString controlName = GetSelectedControlName(); |
|
|
|
m_pControlList->RemoveAll(); |
|
if ( !m_hCombinationOperator.Get() ) |
|
return; |
|
|
|
int nCount = m_hCombinationOperator->GetControlCount(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
bool bIsMultiControl = m_hCombinationOperator->GetRawControlCount(i) > 1; |
|
float flDefault = m_hCombinationOperator->GetRawControlCount(i) == 2 ? 0.5f : 0.0f; |
|
const char *pName = m_hCombinationOperator->GetControlName( i ); |
|
KeyValues *kv = new KeyValues( "node", "name", pName ); |
|
kv->SetString( "stereo", m_hCombinationOperator->IsStereoControl(i) ? "On" : "Off" ); |
|
kv->SetString( "eyelid", m_hCombinationOperator->IsEyelidControl(i) ? "On" : "Off" ); |
|
kv->SetFloat( "default", flDefault ); |
|
kv->SetColor( "cellcolor", bIsMultiControl ? Color( 192, 192, 0, 255 ) : Color( 255, 255, 255, 255 ) ); |
|
const int nItemId = m_pControlList->AddItem( kv, 0, false, false ); |
|
|
|
if ( !Q_strcmp( controlName.Get(), pName ) ) |
|
{ |
|
m_pControlList->SetSingleSelectedItem( nItemId ); |
|
} |
|
} |
|
|
|
RefreshRawControlNames(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Tells any class that cares that the data in this thing has changed |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::NotifyDataChanged() |
|
{ |
|
PostActionSignal( new KeyValues( "DmeElementChanged", "DmeCombinationControlsPanel", 1 ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Refreshes the list of raw controls |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::RefreshRawControlNames() |
|
{ |
|
m_pRawControlList->RemoveAll(); |
|
if ( !m_hCombinationOperator.Get() ) |
|
return; |
|
|
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount != 1 ) |
|
return; |
|
|
|
int nItemID = m_pControlList->GetSelectedItem( 0 ); |
|
|
|
KeyValues *pKeyValues = m_pControlList->GetItem( nItemID ); |
|
const char *pControlName = pKeyValues->GetString( "name" ); |
|
ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName ); |
|
if ( nControlIndex < 0 ) |
|
return; |
|
|
|
int nCount = m_hCombinationOperator->GetRawControlCount( nControlIndex ); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
KeyValues *kv = new KeyValues( "node", "name", m_hCombinationOperator->GetRawControlName( nControlIndex, i ) ); |
|
switch( nCount ) |
|
{ |
|
case 0: |
|
case 1: |
|
kv->SetFloat( "peak", 1.0f ); |
|
break; |
|
|
|
case 2: |
|
kv->SetFloat( "peak", i == 0 ? 0.0f : 1.0f ); |
|
break; |
|
|
|
default: |
|
kv->SetFloat( "peak", (float)i / (nCount - 1) ); |
|
break; |
|
} |
|
|
|
float flWrinkleScale = m_hCombinationOperator->GetRawControlWrinkleScale( nControlIndex, i ); |
|
kv->SetString( "wrinkletype", ( flWrinkleScale < 0.0f ) ? "Compress" : "Stretch" ); |
|
kv->SetFloat( "wrinkle", fabs( flWrinkleScale ) ); |
|
m_pRawControlList->AddItem( kv, 0, false, false ); |
|
} |
|
|
|
m_pRawControlList->SortList(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
const char* CDmeCombinationControlsPanel::GetSelectedRawControl( ControlIndex_t &nControlIndex ) |
|
{ |
|
if ( !m_hCombinationOperator.Get() ) |
|
return NULL; |
|
|
|
nControlIndex = -1; |
|
|
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount != 1 ) |
|
return NULL; |
|
|
|
int nSelectedRawItemCount = m_pRawControlList->GetSelectedItemsCount(); |
|
if ( nSelectedRawItemCount != 1 ) |
|
return NULL; |
|
|
|
int nItemID = m_pControlList->GetSelectedItem( 0 ); |
|
KeyValues *pKeyValues = m_pControlList->GetItem( nItemID ); |
|
const char *pControlName = pKeyValues->GetString( "name" ); |
|
nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName ); |
|
|
|
nItemID = m_pRawControlList->GetSelectedItem( 0 ); |
|
pKeyValues = m_pRawControlList->GetItem( nItemID ); |
|
return pKeyValues->GetString( "name" ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
const char *CDmeCombinationControlsPanel::GetSelectedControlName() |
|
{ |
|
if ( !m_hCombinationOperator.Get() ) |
|
return NULL; |
|
|
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount != 1 ) |
|
return NULL; |
|
|
|
const int nItemId = m_pControlList->GetSelectedItem( 0 ); |
|
if ( !m_pControlList->IsValidItemID( nItemId ) ) |
|
return NULL; |
|
|
|
KeyValues *pKeyValues = m_pControlList->GetItem( nItemId ); |
|
if ( !pKeyValues ) |
|
return NULL; |
|
|
|
return pKeyValues->GetString( "name" ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
int CDmeCombinationControlsPanel::GetSelectedInputControlItemId() |
|
{ |
|
return m_pControlList->GetSelectedItem( 0 ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::SelectedInputControlByItemId( int nItemId ) |
|
{ |
|
m_pControlList->SetSingleSelectedItem( nItemId ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnMoveUp() |
|
{ |
|
ControlIndex_t nControlIndex; |
|
const char *pRawControlName = GetSelectedRawControl( nControlIndex ); |
|
if ( !pRawControlName ) |
|
return; |
|
|
|
m_hCombinationOperator->MoveRawControlUp( nControlIndex, pRawControlName ); |
|
RefreshRawControlNames(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnMoveDown() |
|
{ |
|
ControlIndex_t nControlIndex; |
|
const char *pRawControlName = GetSelectedRawControl( nControlIndex ); |
|
if ( !pRawControlName ) |
|
return; |
|
|
|
m_hCombinationOperator->MoveRawControlDown( nControlIndex, pRawControlName ); |
|
RefreshRawControlNames(); |
|
|
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnMoveUpInputControl() |
|
{ |
|
const char *pControlName = GetSelectedControlName(); |
|
if ( !pControlName ) |
|
return; |
|
|
|
m_hCombinationOperator->MoveControlUp( pControlName ); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnMoveDownInputControl() |
|
{ |
|
const char *pControlName = GetSelectedControlName(); |
|
if ( !pControlName ) |
|
return; |
|
|
|
m_hCombinationOperator->MoveControlDown( pControlName ); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::MoveControlInFrontOf( |
|
const char *pDragControl, |
|
const char *pDropControl ) |
|
{ |
|
m_hCombinationOperator->MoveControlBefore( pDragControl, pDropControl ); |
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Toggles the wrinkle type |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnToggleWrinkleType() |
|
{ |
|
ControlIndex_t nControlIndex; |
|
const char *pRawControlName = GetSelectedRawControl( nControlIndex ); |
|
if ( !pRawControlName ) |
|
return; |
|
|
|
float flWrinkleScale = m_hCombinationOperator->GetRawControlWrinkleScale( nControlIndex, pRawControlName ); |
|
m_hCombinationOperator->SetWrinkleScale( nControlIndex, pRawControlName, -flWrinkleScale ); |
|
RefreshRawControlNames(); |
|
m_hCombinationOperator->GenerateWrinkleDeltas(); |
|
} |
|
|
|
|
|
void CDmeCombinationControlsPanel::SetRawControlWrinkleValue( float flWrinkleValue ) |
|
{ |
|
ControlIndex_t nControlIndex; |
|
const char *pRawControlName = GetSelectedRawControl( nControlIndex ); |
|
if ( !pRawControlName ) |
|
return; |
|
|
|
m_hCombinationOperator->SetWrinkleScale( nControlIndex, pRawControlName, flWrinkleValue ); |
|
RefreshRawControlNames(); |
|
m_hCombinationOperator->GenerateWrinkleDeltas(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnOpenRawControlsContextMenu( ) |
|
{ |
|
if ( !m_hCombinationOperator.Get() ) |
|
return; |
|
|
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount != 1 ) |
|
return; |
|
|
|
int nSelectedRawItemCount = m_pRawControlList->GetSelectedItemsCount(); |
|
if ( nSelectedRawItemCount != 1 ) |
|
return; |
|
|
|
m_hContextMenu = new vgui::Menu( this, "ActionMenu" ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveUp", new KeyValues( "MoveUp" ), this ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveDown", new KeyValues( "MoveDown" ), this ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_ToggleWrinkleType", new KeyValues( "ToggleWrinkleType" ), this ); |
|
|
|
vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnOpenContextMenu( KeyValues *kv ) |
|
{ |
|
CleanupContextMenu(); |
|
if ( !m_hCombinationOperator.Get() ) |
|
return; |
|
|
|
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); |
|
if ( pPanel == m_pRawControlList ) |
|
{ |
|
OnOpenRawControlsContextMenu(); |
|
return; |
|
} |
|
|
|
if ( pPanel != m_pControlList ) |
|
return; |
|
|
|
bool bGroupedControls = false; |
|
bool bStereoControls = false; |
|
bool bEyelidControls = false; |
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
for ( int i = 0; i < nSelectedItemCount; ++i ) |
|
{ |
|
int nItemID = m_pControlList->GetSelectedItem( i ); |
|
|
|
KeyValues *pKeyValues = m_pControlList->GetItem( nItemID ); |
|
const char *pControlName = pKeyValues->GetString( "name" ); |
|
ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName ); |
|
if ( nControlIndex < 0 ) |
|
continue; |
|
|
|
if ( m_hCombinationOperator->GetRawControlCount( nControlIndex ) > 1 ) |
|
{ |
|
bGroupedControls = true; |
|
} |
|
|
|
if ( m_hCombinationOperator->IsStereoControl( nControlIndex ) ) |
|
{ |
|
bStereoControls = true; |
|
} |
|
|
|
if ( m_hCombinationOperator->IsEyelidControl( nControlIndex ) ) |
|
{ |
|
bEyelidControls = true; |
|
} |
|
} |
|
|
|
m_hContextMenu = new vgui::Menu( this, "ActionMenu" ); |
|
|
|
if ( nSelectedItemCount > 1 ) |
|
{ |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_GroupControls", new KeyValues( "GroupControls" ), this ); |
|
} |
|
|
|
if ( bGroupedControls ) |
|
{ |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_UngroupControls", new KeyValues( "UngroupControls" ), this ); |
|
} |
|
|
|
if ( nSelectedItemCount >= 1 ) |
|
{ |
|
int nMenuItemID = m_hContextMenu->AddCheckableMenuItem( "#DmeCombinationSystemEditor_StereoControl", new KeyValues( "ToggleStereoControl" ), this ); |
|
m_hContextMenu->SetMenuItemChecked( nMenuItemID, bStereoControls ); |
|
} |
|
|
|
if ( nSelectedItemCount >= 1 ) |
|
{ |
|
int nMenuItemID = m_hContextMenu->AddCheckableMenuItem( "#DmeCombinationSystemEditor_EyelidControl", new KeyValues( "ToggleEyelidControl" ), this ); |
|
m_hContextMenu->SetMenuItemChecked( nMenuItemID, bEyelidControls ); |
|
} |
|
|
|
if ( nSelectedItemCount == 1 ) |
|
{ |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_RenameControl", new KeyValues( "RenameControl" ), this ); |
|
} |
|
|
|
if ( nSelectedItemCount >= 1 ) |
|
{ |
|
m_hContextMenu->AddSeparator(); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveUp", new KeyValues( "MoveUpInputControl" ), this ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveDown", new KeyValues( "MoveDownInputControl" ), this ); |
|
} |
|
|
|
if ( nSelectedItemCount >= 1 || bGroupedControls ) |
|
{ |
|
m_hContextMenu->AddSeparator(); |
|
} |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_Import", new KeyValues( "ImportCombination" ), this ); |
|
|
|
vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnItemSelected( KeyValues *kv ) |
|
{ |
|
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); |
|
if ( pPanel == m_pControlList ) |
|
{ |
|
RefreshRawControlNames(); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnItemDeselected( KeyValues *kv ) |
|
{ |
|
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); |
|
if ( pPanel == m_pControlList ) |
|
{ |
|
RefreshRawControlNames(); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Builds a list of selected control + raw control names, returns true if any control is stereo |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::BuildSelectedControlLists( |
|
bool bOnlyGroupedControls, |
|
CUtlVector< CUtlString >& controlNames, CUtlVector< CUtlString >& rawControlNames, |
|
bool *pbStereo, bool *pbEyelid ) |
|
{ |
|
bool bIsStereo = false; |
|
bool bIsEyelid = false; |
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
for ( int i = 0; i < nSelectedItemCount; ++i ) |
|
{ |
|
int nItemID = m_pControlList->GetSelectedItem( i ); |
|
|
|
KeyValues *pKeyValues = m_pControlList->GetItem( nItemID ); |
|
const char *pControlName = pKeyValues->GetString( "name" ); |
|
ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName ); |
|
if ( nControlIndex < 0 ) |
|
continue; |
|
|
|
int nRawControlCount = m_hCombinationOperator->GetRawControlCount( nControlIndex ); |
|
if ( bOnlyGroupedControls && ( nRawControlCount <= 1 ) ) |
|
continue; |
|
|
|
if ( m_hCombinationOperator->IsStereoControl( nControlIndex ) ) |
|
{ |
|
bIsStereo = true; |
|
} |
|
|
|
if ( m_hCombinationOperator->IsEyelidControl( nControlIndex ) ) |
|
{ |
|
bIsEyelid = true; |
|
} |
|
|
|
controlNames.AddToTail( pControlName ); |
|
for ( int j = 0; j < nRawControlCount; ++j ) |
|
{ |
|
rawControlNames.AddToTail( m_hCombinationOperator->GetRawControlName( nControlIndex, j ) ); |
|
} |
|
} |
|
|
|
if ( pbStereo ) |
|
{ |
|
*pbStereo = bIsStereo; |
|
} |
|
|
|
if ( pbEyelid ) |
|
{ |
|
*pbEyelid = bIsEyelid; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// If it finds a duplicate control name, reports an error message and returns it found one |
|
//----------------------------------------------------------------------------- |
|
bool CDmeCombinationControlsPanel::HasDuplicateControlName( const char *pControlName, CUtlVector< CUtlString >& retiredControlNames ) |
|
{ |
|
int i; |
|
int nRetiredControlNameCount = retiredControlNames.Count(); |
|
for ( i = 0; i < nRetiredControlNameCount; ++i ) |
|
{ |
|
if ( !Q_stricmp( retiredControlNames[i], pControlName ) ) |
|
break; |
|
} |
|
if ( i == nRetiredControlNameCount ) |
|
{ |
|
// no match |
|
if ( m_hCombinationOperator->FindControlIndex( pControlName ) >= 0 ) |
|
{ |
|
vgui::MessageBox *pError = new vgui::MessageBox( "#DmeCombinationSystemEditor_DuplicateNameTitle", "#DmeCombinationSystemEditor_DuplicateNameText", this ); |
|
pError->DoModal(); |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called by OnGroupControls and OnRenameControl after we get a new group name |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::PerformGroupControls( const char *pGroupedControlName ) |
|
{ |
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount <= 1 ) |
|
return; |
|
|
|
// Build lists of selected controls + raw controls |
|
CUtlVector< CUtlString > controlNames; |
|
CUtlVector< CUtlString > rawControlNames; |
|
bool bIsStereo = false; |
|
bool bIsEyelid = false; |
|
BuildSelectedControlLists( false, controlNames, rawControlNames, &bIsStereo, &bIsEyelid ); |
|
|
|
// NOTE: It's illegal to use a grouped control name which already exists |
|
// assuming it's not in the list of grouped control names we're going to group together |
|
if ( HasDuplicateControlName( pGroupedControlName, controlNames ) ) |
|
return; |
|
|
|
// Delete old controls |
|
int nRetiredControlNameCount = controlNames.Count(); |
|
for ( int i = 0; i < nRetiredControlNameCount; ++i ) |
|
{ |
|
m_hCombinationOperator->RemoveControl( controlNames[i] ); |
|
} |
|
|
|
// Create new control |
|
ControlIndex_t nNewControl = m_hCombinationOperator->FindOrCreateControl( pGroupedControlName, bIsStereo ); |
|
m_hCombinationOperator->SetEyelidControl( nNewControl, bIsEyelid ); |
|
int nGroupedControlCount = rawControlNames.Count(); |
|
for ( int i = 0; i < nGroupedControlCount; ++i ) |
|
{ |
|
m_hCombinationOperator->AddRawControl( nNewControl, rawControlNames[i] ); |
|
} |
|
|
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called by OnGroupControls after we get a new group name |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::PerformRenameControl( const char *pNewControlName ) |
|
{ |
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount != 1 ) |
|
return; |
|
|
|
int nItemID = m_pControlList->GetSelectedItem( 0 ); |
|
KeyValues *pKeyValues = m_pControlList->GetItem( nItemID ); |
|
const char *pControlName = pKeyValues->GetString( "name" ); |
|
ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName ); |
|
if ( nControlIndex < 0 ) |
|
return; |
|
|
|
// NOTE: It's illegal to use a grouped control name which already exists |
|
// assuming it's not in the list of grouped control names we're going to group together |
|
ControlIndex_t nFoundIndex = m_hCombinationOperator->FindControlIndex( pNewControlName ); |
|
if ( nFoundIndex >= 0 && nFoundIndex != nControlIndex ) |
|
return; |
|
|
|
m_hCombinationOperator->SetControlName( nControlIndex, pNewControlName ); |
|
|
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called by OnGroupControls after we get a new group name |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnInputCompleted( KeyValues *pKeyValues ) |
|
{ |
|
const char *pControlName = pKeyValues->GetString( "text", NULL ); |
|
if ( !pControlName || !pControlName[0] ) |
|
return; |
|
|
|
if ( pKeyValues->FindKey( "OnGroupControls" ) ) |
|
{ |
|
PerformGroupControls( pControlName ); |
|
return; |
|
} |
|
|
|
if ( pKeyValues->FindKey( "OnRenameControl" ) ) |
|
{ |
|
PerformRenameControl( pControlName ); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Group controls together |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnGroupControls( ) |
|
{ |
|
vgui::InputDialog *pInput = new vgui::InputDialog( this, "Group Controls", "Enter name of grouped control" ); |
|
pInput->SetMultiline( false ); |
|
pInput->DoModal( new KeyValues( "OnGroupControls" ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Ungroup controls from each other |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnUngroupControls( ) |
|
{ |
|
// Build lists of selected controls + raw controls |
|
CUtlVector< CUtlString > controlNames; |
|
CUtlVector< CUtlString > rawControlNames; |
|
bool bIsStereo = false; |
|
bool bIsEyelid = false; |
|
BuildSelectedControlLists( true, controlNames, rawControlNames, &bIsStereo, &bIsEyelid ); |
|
|
|
// NOTE: It's illegal to use a grouped control name which already exists |
|
// assuming it's not in the list of grouped control names we're going to group together |
|
int nRawControlCount = rawControlNames.Count(); |
|
for ( int i = 0; i < nRawControlCount; ++i ) |
|
{ |
|
if ( HasDuplicateControlName( rawControlNames[i], controlNames ) ) |
|
return; |
|
} |
|
|
|
// Delete old controls |
|
int nRetiredControlNameCount = controlNames.Count(); |
|
for ( int i = 0; i < nRetiredControlNameCount; ++i ) |
|
{ |
|
m_hCombinationOperator->RemoveControl( controlNames[i] ); |
|
} |
|
|
|
// Create new control (this will also create raw controls with the same name) |
|
int nGroupedControlCount = rawControlNames.Count(); |
|
for ( int i = 0; i < nGroupedControlCount; ++i ) |
|
{ |
|
const int nControlIndex = m_hCombinationOperator->FindOrCreateControl( rawControlNames[i], bIsStereo, true ); |
|
m_hCombinationOperator->SetEyelidControl( nControlIndex, bIsEyelid ); |
|
} |
|
|
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Ungroup controls from each other |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnToggleStereoControl( ) |
|
{ |
|
// Build lists of selected controls + raw controls |
|
// Yeah, this isn't super efficient, but this UI is not going to be super-polished |
|
CUtlVector< CUtlString > controlNames; |
|
CUtlVector< CUtlString > rawControlNames; |
|
|
|
bool bIsStereo = false; |
|
BuildSelectedControlLists( false, controlNames, rawControlNames, &bIsStereo ); |
|
|
|
int nControlCount = controlNames.Count(); |
|
for ( int i = 0; i < nControlCount; ++i ) |
|
{ |
|
ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( controlNames[i] ); |
|
m_hCombinationOperator->SetStereoControl( nControlIndex, !bIsStereo ); |
|
} |
|
|
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Toggle Eyelid-Ness |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnToggleEyelidControl() |
|
{ |
|
// Build lists of selected controls + raw controls |
|
// Yeah, this isn't super efficient, but this UI is not going to be super-polished |
|
CUtlVector< CUtlString > controlNames; |
|
CUtlVector< CUtlString > rawControlNames; |
|
|
|
bool bIsEyelid = false; |
|
BuildSelectedControlLists( false, controlNames, rawControlNames, NULL, &bIsEyelid ); |
|
|
|
int nControlCount = controlNames.Count(); |
|
for ( int i = 0; i < nControlCount; ++i ) |
|
{ |
|
ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( controlNames[i] ); |
|
m_hCombinationOperator->SetEyelidControl( nControlIndex, !bIsEyelid ); |
|
} |
|
|
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Rename a control |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnRenameControl() |
|
{ |
|
int nSelectedItemCount = m_pControlList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount != 1 ) |
|
return; |
|
|
|
vgui::InputDialog *pInput = new vgui::InputDialog( this, "Rename Control", "Enter new name of control" ); |
|
pInput->SetMultiline( false ); |
|
pInput->DoModal( new KeyValues( "OnRenameControl" ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the file open dialog for browsing source files selects something |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnFileSelected( KeyValues *kv ) |
|
{ |
|
if ( ImportCombinationData( this, m_hCombinationOperator, kv ) ) |
|
{ |
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Import combination controls + domination rules |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationControlsPanel::OnImportCombination() |
|
{ |
|
char pStartingDir[MAX_PATH]; |
|
GetModContentSubdirectory( "models", pStartingDir, sizeof(pStartingDir) ); |
|
|
|
vgui::FileOpenDialog *pDialog = new vgui::FileOpenDialog( this, "Select File to Import", true, new KeyValues( "ImportControls" ) ); |
|
pDialog->SetStartDirectoryContext( "combination_system_import", pStartingDir ); |
|
pDialog->AddFilter( "*.dmx", "Exported model file (*.dmx)", true ); |
|
pDialog->SetDeleteSelfOnClose( true ); |
|
pDialog->AddActionSignalTarget( this ); |
|
pDialog->DoModal( false ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// |
|
// CDmeInputControlListPanel |
|
// |
|
// Declaration above because of scoping issues |
|
// |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CDmeInputControlListPanel::CDmeInputControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel ) : |
|
BaseClass( pParent, pName ), m_pComboPanel( pComboPanel ) |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeInputControlListPanel::OnCreateDragData( KeyValues *msg ) |
|
{ |
|
const char *const pControlName = m_pComboPanel->GetSelectedControlName(); |
|
if ( pControlName ) |
|
{ |
|
msg->SetString( "inputControl", pControlName ); |
|
msg->SetInt( "selfDroppable", 1 ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
bool CDmeInputControlListPanel::IsDroppable( CUtlVector< KeyValues * >& msgList ) |
|
{ |
|
if ( msgList.Count() > 0 ) |
|
{ |
|
KeyValues *pData( msgList[ 0 ] ); |
|
if ( pData->GetPtr( "panel", NULL ) == this && m_pComboPanel ) |
|
{ |
|
if ( pData->GetString( "inputControl" ) && pData->GetInt( "selfDroppable" ) ) |
|
{ |
|
return true; |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when a list panel's selection changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeInputControlListPanel::OnPanelDropped( CUtlVector< KeyValues * >& msgList ) |
|
{ |
|
if ( msgList.Count() > 0 ) |
|
{ |
|
KeyValues *pData( msgList[ 0 ] ); |
|
if ( pData->GetPtr( "panel", NULL ) == this && m_pComboPanel ) |
|
{ |
|
const char *const pDragControl( pData->GetString( "inputControl" ) ); |
|
if ( pDragControl ) |
|
{ |
|
int x; |
|
int y; |
|
|
|
vgui::input()->GetCursorPos( x, y ); |
|
|
|
int row; |
|
int column; |
|
GetCellAtPos( x, y, row, column ); |
|
|
|
KeyValues *pKeyValues = GetItem( GetItemIDFromRow( row ) ); |
|
if ( pKeyValues ) |
|
{ |
|
const char *pDropControl = pKeyValues->GetString( "name" ); |
|
if ( pDropControl ) |
|
{ |
|
m_pComboPanel->MoveControlInFrontOf( pDragControl, pDropControl ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
void CDmeInputControlListPanel::OnKeyCodeTyped( vgui::KeyCode code ) |
|
{ |
|
// Not sure how to handle 'edit' mode... the relevant stuff is private |
|
if ( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) ) |
|
{ |
|
if ( code == KEY_UP ) |
|
{ |
|
const int nItemId = m_pComboPanel->GetSelectedInputControlItemId(); |
|
m_pComboPanel->OnMoveUpInputControl(); |
|
vgui::ListPanel::OnKeyCodeTyped( code ); |
|
m_pComboPanel->SelectedInputControlByItemId( nItemId ); |
|
return; |
|
} |
|
else if ( code == KEY_DOWN ) |
|
{ |
|
const int nItemId = m_pComboPanel->GetSelectedInputControlItemId(); |
|
m_pComboPanel->OnMoveDownInputControl(); |
|
vgui::ListPanel::OnKeyCodeTyped( code ); |
|
m_pComboPanel->SelectedInputControlByItemId( nItemId ); |
|
return; |
|
} |
|
} |
|
|
|
vgui::ListPanel::OnKeyCodeTyped( code ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// |
|
// CDmeRawControlListPanel |
|
// |
|
// Declaration above because of scoping issues |
|
// |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CDmeRawControlListPanel::CDmeRawControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel ) : |
|
BaseClass( pParent, pName ), m_pComboPanel( pComboPanel ) |
|
{ |
|
m_pWrinkleEdit = new vgui::TextEntry( this, "WrinkleEdit" ); |
|
m_pWrinkleEdit->SetVisible( false ); |
|
m_pWrinkleEdit->AddActionSignalTarget( this ); |
|
m_pWrinkleEdit->SetAllowNumericInputOnly( true ); |
|
} |
|
|
|
void CDmeRawControlListPanel::OnKeyCodeTyped( vgui::KeyCode code ) |
|
{ |
|
// Not sure how to handle 'edit' mode... the relevant stuff is private |
|
if ( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) ) |
|
{ |
|
if ( code == KEY_UP ) |
|
{ |
|
m_pComboPanel->OnMoveUp(); |
|
} |
|
else if ( code == KEY_DOWN ) |
|
{ |
|
m_pComboPanel->OnMoveDown(); |
|
} |
|
} |
|
|
|
vgui::ListPanel::OnKeyCodeTyped( code ); |
|
} |
|
|
|
void CDmeRawControlListPanel::OnMouseDoublePressed( vgui::MouseCode code ) |
|
{ |
|
if ( code != MOUSE_LEFT ) |
|
{ |
|
BaseClass::OnMouseDoublePressed( code ); |
|
return; |
|
} |
|
|
|
int nNumSelected = GetSelectedItemsCount(); |
|
if ( IsInEditMode() || nNumSelected != 1 ) |
|
return; |
|
|
|
m_pWrinkleEdit->SetVisible( true ); |
|
m_pWrinkleEdit->SendNewLine( true ); |
|
|
|
// Always edit column 3, which contains the wrinkle amount |
|
int nEditingItem = GetSelectedItem( 0 ); |
|
KeyValues *pKeyValues = GetItem( nEditingItem ); |
|
float flWrinkleValue = pKeyValues->GetFloat( "wrinkle" ); |
|
|
|
m_bIsWrinkle = !Q_stricmp( pKeyValues->GetString( "wrinkletype" ), "Wrinkle" ); |
|
|
|
char buf[64]; |
|
Q_snprintf( buf, sizeof(buf), "%f", flWrinkleValue ); |
|
m_pWrinkleEdit->SetText( buf ); |
|
|
|
EnterEditMode( nEditingItem, 3, m_pWrinkleEdit ); |
|
} |
|
|
|
void CDmeRawControlListPanel::OnNewWrinkleText() |
|
{ |
|
LeaveEditMode(); |
|
|
|
char szEditText[MAX_PATH]; |
|
m_pWrinkleEdit->GetText( szEditText, MAX_PATH ); |
|
m_pWrinkleEdit->SetVisible( false ); |
|
|
|
float flWrinkleScale = atof( szEditText ); |
|
if ( m_bIsWrinkle ) |
|
{ |
|
flWrinkleScale = -flWrinkleScale; |
|
} |
|
m_pComboPanel->SetRawControlWrinkleValue( flWrinkleScale ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Purpose: Multiselect for raw controls |
|
// |
|
//----------------------------------------------------------------------------- |
|
class CRawControlPickerFrame : public vgui::Frame |
|
{ |
|
DECLARE_CLASS_SIMPLE( CRawControlPickerFrame, vgui::Frame ); |
|
|
|
public: |
|
CRawControlPickerFrame( vgui::Panel *pParent, const char *pTitle ); |
|
~CRawControlPickerFrame(); |
|
|
|
// Sets the current scene + animation list |
|
void DoModal( CDmeCombinationOperator *pCombinationOperator, CDmeCombinationDominationRule *pRule, bool bSuppressed, KeyValues *pContextKeyValues ); |
|
|
|
// Inherited from Frame |
|
virtual void OnCommand( const char *pCommand ); |
|
|
|
private: |
|
// Refreshes the list of raw controls |
|
void RefreshRawControlNames( CDmeCombinationOperator *pCombinationOperator, CDmeCombinationDominationRule *pRule, bool bSuppressed ); |
|
void CleanUpMessage(); |
|
|
|
vgui::ListPanel *m_pRawControlList; |
|
vgui::Button *m_pOpenButton; |
|
vgui::Button *m_pCancelButton; |
|
KeyValues *m_pContextKeyValues; |
|
}; |
|
|
|
CRawControlPickerFrame::CRawControlPickerFrame( vgui::Panel *pParent, const char *pTitle ) : |
|
BaseClass( pParent, "RawControlPickerFrame" ) |
|
{ |
|
SetDeleteSelfOnClose( true ); |
|
m_pContextKeyValues = NULL; |
|
|
|
m_pRawControlList = new vgui::ListPanel( this, "RawControlList" ); |
|
m_pRawControlList->AddColumnHeader( 0, "name", "Raw Control Name", 52, 0 ); |
|
m_pRawControlList->SetSelectIndividualCells( false ); |
|
m_pRawControlList->SetEmptyListText( "No raw controls" ); |
|
m_pRawControlList->AddActionSignalTarget( this ); |
|
m_pRawControlList->SetSortFunc( 0, ControlNameSortFunc ); |
|
m_pRawControlList->SetSortColumn( 0 ); |
|
|
|
m_pOpenButton = new vgui::Button( this, "OkButton", "#MessageBox_OK", this, "Ok" ); |
|
m_pCancelButton = new vgui::Button( this, "CancelButton", "#MessageBox_Cancel", this, "Cancel" ); |
|
SetBlockDragChaining( true ); |
|
|
|
LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditor_rawcontrolpickerframe.res" ); |
|
|
|
SetTitle( pTitle, false ); |
|
} |
|
|
|
CRawControlPickerFrame::~CRawControlPickerFrame() |
|
{ |
|
CleanUpMessage(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Refreshes the list of raw controls |
|
//----------------------------------------------------------------------------- |
|
void CRawControlPickerFrame::RefreshRawControlNames( CDmeCombinationOperator *pCombinationOperator, CDmeCombinationDominationRule *pRule, bool bChooseSuppressed ) |
|
{ |
|
m_pRawControlList->RemoveAll(); |
|
if ( !pCombinationOperator ) |
|
return; |
|
|
|
int nCount = pCombinationOperator->GetRawControlCount( ); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
const char *pRawControl = pCombinationOperator->GetRawControlName( i ); |
|
|
|
// Hide controls that are in the other part of the rule |
|
bool bIsDominator = pRule->HasDominatorControl( pRawControl ); |
|
bool bIsSuppressed = pRule->HasSuppressedControl( pRawControl ); |
|
Assert( !bIsDominator || !bIsSuppressed ); |
|
if ( ( bChooseSuppressed && bIsDominator ) || ( !bChooseSuppressed && bIsSuppressed ) ) |
|
continue; |
|
|
|
KeyValues *kv = new KeyValues( "node", "name", pCombinationOperator->GetRawControlName( i ) ); |
|
int nItemID = m_pRawControlList->AddItem( kv, 0, false, false ); |
|
if ( ( bChooseSuppressed && bIsSuppressed ) || ( !bChooseSuppressed && bIsDominator ) ) |
|
{ |
|
m_pRawControlList->AddSelectedItem( nItemID ); |
|
} |
|
} |
|
|
|
m_pRawControlList->SortList(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Deletes the message |
|
//----------------------------------------------------------------------------- |
|
void CRawControlPickerFrame::CleanUpMessage() |
|
{ |
|
if ( m_pContextKeyValues ) |
|
{ |
|
m_pContextKeyValues->deleteThis(); |
|
m_pContextKeyValues = NULL; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the current scene + animation list |
|
//----------------------------------------------------------------------------- |
|
void CRawControlPickerFrame::DoModal( CDmeCombinationOperator *pCombinationOperator, |
|
CDmeCombinationDominationRule *pRule, bool bSuppressed, KeyValues *pContextKeyValues ) |
|
{ |
|
CleanUpMessage(); |
|
RefreshRawControlNames( pCombinationOperator, pRule, bSuppressed ); |
|
m_pContextKeyValues = pContextKeyValues; |
|
BaseClass::DoModal(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// On command |
|
//----------------------------------------------------------------------------- |
|
void CRawControlPickerFrame::OnCommand( const char *pCommand ) |
|
{ |
|
if ( !Q_stricmp( pCommand, "Ok" ) ) |
|
{ |
|
KeyValues *pActionKeys = new KeyValues( "RawControlPicked" ); |
|
KeyValues *pControlList = pActionKeys->FindKey( "rawControls", true ); |
|
|
|
int nSelectedItemCount = m_pRawControlList->GetSelectedItemsCount(); |
|
for ( int i = 0; i < nSelectedItemCount; ++i ) |
|
{ |
|
int nItemID = m_pRawControlList->GetSelectedItem( i ); |
|
KeyValues *pKeyValues = m_pRawControlList->GetItem( nItemID ); |
|
const char *pControlName = pKeyValues->GetString( "name" ); |
|
|
|
pControlList->SetString( pControlName, pControlName ); |
|
} |
|
|
|
if ( m_pContextKeyValues ) |
|
{ |
|
pActionKeys->AddSubKey( m_pContextKeyValues ); |
|
|
|
// This prevents them from being deleted later |
|
m_pContextKeyValues = NULL; |
|
} |
|
|
|
PostActionSignal( pActionKeys ); |
|
CloseModal(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( pCommand, "Cancel" ) ) |
|
{ |
|
CloseModal(); |
|
return; |
|
} |
|
|
|
BaseClass::OnCommand( pCommand ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Domination rules panel |
|
//----------------------------------------------------------------------------- |
|
class CDmeCombinationDominationRulesPanel : public vgui::EditablePanel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CDmeCombinationDominationRulesPanel, vgui::EditablePanel ); |
|
|
|
public: |
|
// constructor, destructor |
|
CDmeCombinationDominationRulesPanel( vgui::Panel *pParent, const char *pName ); |
|
virtual ~CDmeCombinationDominationRulesPanel(); |
|
|
|
void SetCombinationOperator( CDmeCombinationOperator *pOp ); |
|
void RefreshCombinationOperator(); |
|
void NotifyDataChanged(); |
|
|
|
private: |
|
MESSAGE_FUNC_PARAMS( OnOpenContextMenu, "OpenContextMenu", kv ); |
|
MESSAGE_FUNC_PARAMS( OnRawControlPicked, "RawControlPicked", kv ); |
|
MESSAGE_FUNC( OnAddDominationRule, "AddDominationRule" ); |
|
MESSAGE_FUNC( OnRemoveDominationRule, "RemoveDominationRule" ); |
|
MESSAGE_FUNC( OnDuplicateSuppressed, "DuplicateSuppressed" ); |
|
MESSAGE_FUNC( OnDuplicateDominators, "DuplicateDominators" ); |
|
MESSAGE_FUNC( OnSelectDominators, "SelectDominators" ); |
|
MESSAGE_FUNC( OnSelectSuppressed, "SelectSuppressed" ); |
|
MESSAGE_FUNC( OnMoveUp, "MoveUp" ); |
|
MESSAGE_FUNC( OnMoveDown, "MoveDown" ); |
|
MESSAGE_FUNC( OnImportDominationRules, "ImportDominationRules" ); |
|
MESSAGE_FUNC_PARAMS( OnFileSelected, "FileSelected", kv ); |
|
|
|
// Cleans up the context menu |
|
void CleanupContextMenu(); |
|
|
|
// Selects a particular domination rule |
|
void SelectRule( CDmeCombinationDominationRule* pRule ); |
|
|
|
// Returns the currently selected rule |
|
CDmeCombinationDominationRule* GetSelectedRule( ); |
|
|
|
CDmeHandle< CDmeCombinationOperator > m_hCombinationOperator; |
|
vgui::ListPanel *m_pDominationRulesList; |
|
vgui::DHANDLE< vgui::Menu > m_hContextMenu; |
|
}; |
|
|
|
|
|
static int __cdecl DominatorNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 ) |
|
{ |
|
int i1 = item1.kv->GetInt("index"); |
|
int i2 = item2.kv->GetInt("index"); |
|
return i1 - i2; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CDmeCombinationDominationRulesPanel::CDmeCombinationDominationRulesPanel( vgui::Panel *pParent, const char *pName ) : |
|
BaseClass( pParent, pName ) |
|
{ |
|
m_pDominationRulesList = new vgui::ListPanel( this, "DominationRulesList" ); |
|
m_pDominationRulesList->AddColumnHeader( 0, "suppressed", "Suppress", 100, 0 ); |
|
m_pDominationRulesList->AddColumnHeader( 1, "dominator", "Dominate", 100, 0 ); |
|
m_pDominationRulesList->AddActionSignalTarget( this ); |
|
m_pDominationRulesList->SetSortFunc( 0, DominatorNameSortFunc ); |
|
m_pDominationRulesList->SetSortFunc( 1, DominatorNameSortFunc ); |
|
m_pDominationRulesList->SetSortColumn( 0 ); |
|
m_pDominationRulesList->SetEmptyListText("No domination rules."); |
|
m_pDominationRulesList->SetMultiselectEnabled( false ); |
|
} |
|
|
|
CDmeCombinationDominationRulesPanel::~CDmeCombinationDominationRulesPanel() |
|
{ |
|
CleanupContextMenu(); |
|
SaveUserConfig(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Cleans up the context menu |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::CleanupContextMenu() |
|
{ |
|
if ( m_hContextMenu.Get() ) |
|
{ |
|
m_hContextMenu->MarkForDeletion(); |
|
m_hContextMenu = NULL; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the combination operator |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::SetCombinationOperator( CDmeCombinationOperator *pOp ) |
|
{ |
|
if ( pOp != m_hCombinationOperator.Get() ) |
|
{ |
|
m_hCombinationOperator = pOp; |
|
RefreshCombinationOperator(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Basic sort function, for use in qsort |
|
//----------------------------------------------------------------------------- |
|
static int __cdecl ControlNameSortFunc(const void *elem1, const void *elem2) |
|
{ |
|
const char *pItem1 = *((const char **) elem1); |
|
const char *pItem2 = *((const char **) elem2); |
|
return Q_stricmp( pItem1, pItem2 ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Builds the list of animations |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::RefreshCombinationOperator() |
|
{ |
|
m_pDominationRulesList->RemoveAll(); |
|
if ( !m_hCombinationOperator.Get() ) |
|
return; |
|
|
|
char pTemp[1024]; |
|
int nCount = m_hCombinationOperator->DominationRuleCount(); |
|
for ( int i = 0; i < nCount; ++i ) |
|
{ |
|
CDmeCombinationDominationRule *pRule = m_hCombinationOperator->GetDominationRule( i ); |
|
|
|
KeyValues *pItemKeys = new KeyValues( "node" ); |
|
|
|
int nLen = 0; |
|
int nControlCount = pRule->DominatorCount(); |
|
pTemp[0] = 0; |
|
const char **ppStrings = (const char**)_alloca( nControlCount * sizeof(const char*) ); |
|
for ( int j = 0; j < nControlCount; ++j ) |
|
{ |
|
ppStrings[j] = pRule->GetDominator(j); |
|
} |
|
qsort( ppStrings, (size_t)nControlCount, (size_t)sizeof(char*), ControlNameSortFunc ); |
|
for ( int j = 0; j < nControlCount; ++j ) |
|
{ |
|
nLen += Q_snprintf( &pTemp[nLen], sizeof(pTemp) - nLen, "%s ", ppStrings[j] ); |
|
} |
|
|
|
pItemKeys->SetString( "dominator", pTemp ); |
|
|
|
nLen = 0; |
|
nControlCount = pRule->SuppressedCount(); |
|
pTemp[0] = 0; |
|
ppStrings = (const char**)_alloca( nControlCount * sizeof(const char*) ); |
|
for ( int j = 0; j < nControlCount; ++j ) |
|
{ |
|
ppStrings[j] = pRule->GetSuppressed(j); |
|
} |
|
qsort( ppStrings, (size_t)nControlCount, (size_t)sizeof(char*), ControlNameSortFunc ); |
|
for ( int j = 0; j < nControlCount; ++j ) |
|
{ |
|
nLen += Q_snprintf( &pTemp[nLen], sizeof(pTemp) - nLen, "%s ", ppStrings[j] ); |
|
} |
|
pItemKeys->SetString( "suppressed", pTemp ); |
|
pItemKeys->SetInt( "index", i ); |
|
SetElementKeyValue( pItemKeys, "rule", pRule ); |
|
|
|
m_pDominationRulesList->AddItem( pItemKeys, 0, false, false ); |
|
} |
|
|
|
m_pDominationRulesList->SortList(); |
|
} |
|
|
|
|
|
void CDmeCombinationDominationRulesPanel::NotifyDataChanged() |
|
{ |
|
PostActionSignal( new KeyValues( "DmeElementChanged", "DmeCombinationDominationRulesPanel", 2 ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the currently selected domination rule |
|
//----------------------------------------------------------------------------- |
|
CDmeCombinationDominationRule* CDmeCombinationDominationRulesPanel::GetSelectedRule( ) |
|
{ |
|
if ( !m_hCombinationOperator.Get() ) |
|
return NULL; |
|
|
|
int nSelectedItemCount = m_pDominationRulesList->GetSelectedItemsCount(); |
|
if ( nSelectedItemCount != 1 ) |
|
return NULL; |
|
|
|
int nItemID = m_pDominationRulesList->GetSelectedItem( 0 ); |
|
KeyValues *pKeyValues = m_pDominationRulesList->GetItem( nItemID ); |
|
return GetElementKeyValue<CDmeCombinationDominationRule>( pKeyValues, "rule" ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Reorder rules |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnMoveUp( ) |
|
{ |
|
CDmeCombinationDominationRule* pRule = GetSelectedRule( ); |
|
if ( !pRule ) |
|
return; |
|
|
|
m_hCombinationOperator->MoveDominationRuleUp( pRule ); |
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
void CDmeCombinationDominationRulesPanel::OnMoveDown( ) |
|
{ |
|
CDmeCombinationDominationRule* pRule = GetSelectedRule( ); |
|
if ( !pRule ) |
|
return; |
|
|
|
m_hCombinationOperator->MoveDominationRuleDown( pRule ); |
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the file open dialog for browsing source files selects something |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnFileSelected( KeyValues *kv ) |
|
{ |
|
if ( ImportCombinationData( this, m_hCombinationOperator, kv ) ) |
|
{ |
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Import domination rules |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnImportDominationRules() |
|
{ |
|
char pStartingDir[MAX_PATH]; |
|
GetModContentSubdirectory( "models", pStartingDir, sizeof(pStartingDir) ); |
|
|
|
vgui::FileOpenDialog *pDialog = new vgui::FileOpenDialog( this, "Select File to Import", true, new KeyValues( "ImportDominationRules" ) ); |
|
pDialog->SetStartDirectoryContext( "combination_system_import", pStartingDir ); |
|
pDialog->AddFilter( "*.dmx", "Exported model file (*.dmx)", true ); |
|
pDialog->SetDeleteSelfOnClose( true ); |
|
pDialog->AddActionSignalTarget( this ); |
|
pDialog->DoModal( false ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called to open a context-sensitive menu for a particular menu item |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnOpenContextMenu( KeyValues *kv ) |
|
{ |
|
CleanupContextMenu(); |
|
if ( !m_hCombinationOperator.Get() ) |
|
return; |
|
|
|
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); |
|
if ( pPanel != m_pDominationRulesList ) |
|
return; |
|
|
|
int nSelectedItemCount = m_pDominationRulesList->GetSelectedItemsCount(); |
|
|
|
m_hContextMenu = new vgui::Menu( this, "ActionMenu" ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_AddDominationRule", new KeyValues( "AddDominationRule" ), this ); |
|
if ( nSelectedItemCount > 0 ) |
|
{ |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_RemoveDominationRule", new KeyValues( "RemoveDominationRule" ), this ); |
|
} |
|
|
|
if ( nSelectedItemCount == 1 ) |
|
{ |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_DuplicateSuppressed", new KeyValues( "DuplicateSuppressed" ), this ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_DuplicateDominators", new KeyValues( "DuplicateDominators" ), this ); |
|
m_hContextMenu->AddSeparator(); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_SelectSuppressed", new KeyValues( "SelectSuppressed" ), this ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_SelectDominators", new KeyValues( "SelectDominators" ), this ); |
|
m_hContextMenu->AddSeparator(); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveUp", new KeyValues( "MoveUp" ), this ); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveDown", new KeyValues( "MoveDown" ), this ); |
|
} |
|
|
|
m_hContextMenu->AddSeparator(); |
|
m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_ImportDomination", new KeyValues( "ImportDominationRules" ), this ); |
|
|
|
vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Selects a particular domination rule |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::SelectRule( CDmeCombinationDominationRule* pRule ) |
|
{ |
|
for ( int nItemID = m_pDominationRulesList->FirstItem(); nItemID != m_pDominationRulesList->InvalidItemID(); nItemID = m_pDominationRulesList->NextItem( nItemID ) ) |
|
{ |
|
KeyValues *pKeyValues = m_pDominationRulesList->GetItem( nItemID ); |
|
if ( pRule == GetElementKeyValue<CDmeCombinationDominationRule>( pKeyValues, "rule" ) ) |
|
{ |
|
m_pDominationRulesList->SetSingleSelectedItem( nItemID ); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Called by the context menu to add dominator rules |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnAddDominationRule( ) |
|
{ |
|
CDmeCombinationDominationRule* pRule = m_hCombinationOperator->AddDominationRule(); |
|
RefreshCombinationOperator(); |
|
SelectRule( pRule ); |
|
OnSelectSuppressed(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Duplicate suppressed |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnDuplicateSuppressed() |
|
{ |
|
CDmeCombinationDominationRule *pSrcRule = GetSelectedRule(); |
|
if ( !pSrcRule ) |
|
return; |
|
|
|
CDmeCombinationDominationRule* pRule = m_hCombinationOperator->AddDominationRule(); |
|
RefreshCombinationOperator(); |
|
SelectRule( pRule ); |
|
for ( int i = 0; i < pSrcRule->SuppressedCount(); ++i ) |
|
{ |
|
pRule->AddSuppressed( pSrcRule->GetSuppressed( i ) ); |
|
} |
|
OnSelectDominators(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
void CDmeCombinationDominationRulesPanel::OnDuplicateDominators() |
|
{ |
|
CDmeCombinationDominationRule *pSrcRule = GetSelectedRule(); |
|
if ( !pSrcRule ) |
|
return; |
|
|
|
CDmeCombinationDominationRule* pRule = m_hCombinationOperator->AddDominationRule(); |
|
RefreshCombinationOperator(); |
|
SelectRule( pRule ); |
|
for ( int i = 0; i < pSrcRule->DominatorCount(); ++i ) |
|
{ |
|
pRule->AddDominator( pSrcRule->GetDominator( i ) ); |
|
} |
|
OnSelectSuppressed(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called by the context menu to remove dominator rules |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnRemoveDominationRule( ) |
|
{ |
|
int nSelectedItemCount = m_pDominationRulesList->GetSelectedItemsCount(); |
|
for ( int i = 0; i < nSelectedItemCount; ++i ) |
|
{ |
|
int nItemID = m_pDominationRulesList->GetSelectedItem( i ); |
|
KeyValues *pKeyValues = m_pDominationRulesList->GetItem( nItemID ); |
|
|
|
CDmeCombinationDominationRule *pRule = GetElementKeyValue<CDmeCombinationDominationRule>( pKeyValues, "rule" ); |
|
if ( pRule ) |
|
{ |
|
m_hCombinationOperator->RemoveDominationRule( pRule ); |
|
} |
|
} |
|
|
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called by the pickers made in OnSelectDominators + OnSelectSuppressed |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnRawControlPicked( KeyValues *pKeyValues ) |
|
{ |
|
KeyValues *pControlList = pKeyValues->FindKey( "rawControls" ); |
|
if ( !pControlList ) |
|
return; |
|
|
|
KeyValues *pContextKeys = pKeyValues->FindKey( "OnSelectDominators" ); |
|
if ( pContextKeys ) |
|
{ |
|
CDmeCombinationDominationRule *pRule = GetElementKeyValue<CDmeCombinationDominationRule>( pContextKeys, "rule" ); |
|
if ( !pRule ) |
|
return; |
|
|
|
pRule->RemoveAllDominators(); |
|
for ( KeyValues *pKey = pControlList->GetFirstValue(); pKey; pKey = pKey->GetNextValue() ) |
|
{ |
|
pRule->AddDominator( pKey->GetName() ); |
|
} |
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
return; |
|
} |
|
|
|
pContextKeys = pKeyValues->FindKey( "OnSelectSuppressed" ); |
|
if ( pContextKeys ) |
|
{ |
|
CDmeCombinationDominationRule *pRule = GetElementKeyValue<CDmeCombinationDominationRule>( pContextKeys, "rule" ); |
|
if ( !pRule ) |
|
return; |
|
|
|
pRule->RemoveAllSuppressed(); |
|
for ( KeyValues *pKey = pControlList->GetFirstValue(); pKey; pKey = pKey->GetNextValue() ) |
|
{ |
|
pRule->AddSuppressed( pKey->GetName() ); |
|
} |
|
RefreshCombinationOperator(); |
|
NotifyDataChanged(); |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called by the context menu to change dominator rules |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationDominationRulesPanel::OnSelectDominators( ) |
|
{ |
|
CDmeCombinationDominationRule *pRule = GetSelectedRule(); |
|
if ( !pRule ) |
|
return; |
|
|
|
KeyValues *pContextKeyValues = new KeyValues( "OnSelectDominators" ); |
|
SetElementKeyValue( pContextKeyValues, "rule", pRule ); |
|
|
|
CRawControlPickerFrame *pPicker = new CRawControlPickerFrame( this, "Select Dominator(s)" ); |
|
pPicker->DoModal( m_hCombinationOperator, pRule, false, pContextKeyValues ); |
|
} |
|
|
|
void CDmeCombinationDominationRulesPanel::OnSelectSuppressed( ) |
|
{ |
|
CDmeCombinationDominationRule *pRule = GetSelectedRule(); |
|
if ( !pRule ) |
|
return; |
|
|
|
KeyValues *pContextKeyValues = new KeyValues( "OnSelectSuppressed" ); |
|
SetElementKeyValue( pContextKeyValues, "rule", pRule ); |
|
|
|
CRawControlPickerFrame *pPicker = new CRawControlPickerFrame( this, "Select Suppressed" ); |
|
pPicker->DoModal( m_hCombinationOperator, pRule, true, pContextKeyValues ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Combination system editor panel |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CDmeCombinationSystemEditorPanel::CDmeCombinationSystemEditorPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName ) |
|
{ |
|
m_pEditorSheet = new vgui::PropertySheet( this, "EditorSheet" ); |
|
m_pEditorSheet->AddActionSignalTarget( this ); |
|
|
|
m_pControlsPage = new vgui::PropertyPage( m_pEditorSheet, "ControlsPage" ); |
|
m_pDominationRulesPage = new vgui::PropertyPage( m_pEditorSheet, "DominationRulesPage" ); |
|
m_pPropertiesPage = new vgui::PropertyPage( m_pEditorSheet, "PropertiesPage" ); |
|
|
|
m_pControlsPanel = new CDmeCombinationControlsPanel( (vgui::Panel*)NULL, "CombinationControls" ); |
|
m_pControlsPanel->AddActionSignalTarget( this ); |
|
|
|
m_pDominationRulesPanel = new CDmeCombinationDominationRulesPanel( (vgui::Panel*)NULL, "DominationRules" ); |
|
m_pDominationRulesPanel->AddActionSignalTarget( this ); |
|
|
|
m_pPropertiesPanel = new CDmeElementPanel( (vgui::Panel*)NULL, "PropertiesPanel" ); |
|
m_pPropertiesPanel->AddActionSignalTarget( this ); |
|
|
|
m_pControlsPanel->LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorpanel_controlspage.res" ); |
|
m_pDominationRulesPanel->LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorpanel_dominationpage.res" ); |
|
|
|
// Load layout settings; has to happen before pinning occurs in code |
|
LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorpanel.res" ); |
|
|
|
// NOTE: Page adding happens *after* LoadControlSettingsAndUserConfig |
|
// because the layout of the sheet is correct at this point. |
|
m_pEditorSheet->AddPage( m_pControlsPanel, "Controls" ); |
|
m_pEditorSheet->AddPage( m_pDominationRulesPanel, "Domination" ); |
|
m_pEditorSheet->AddPage( m_pPropertiesPanel, "Properties" ); |
|
} |
|
|
|
CDmeCombinationSystemEditorPanel::~CDmeCombinationSystemEditorPanel() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Set the scene |
|
|
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationSystemEditorPanel::SetDmeElement( CDmeCombinationOperator *pComboOp ) |
|
{ |
|
m_pControlsPanel->SetCombinationOperator( pComboOp ); |
|
m_pDominationRulesPanel->SetCombinationOperator( pComboOp ); |
|
m_pPropertiesPanel->SetDmeElement( pComboOp ); |
|
} |
|
|
|
CDmeCombinationOperator *CDmeCombinationSystemEditorPanel::GetDmeElement() |
|
{ |
|
return m_pControlsPanel->GetCombinationOperator( ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the page changes |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationSystemEditorPanel::OnPageChanged( ) |
|
{ |
|
if ( m_pEditorSheet->GetActivePage() == m_pControlsPage ) |
|
{ |
|
return; |
|
} |
|
|
|
if ( m_pEditorSheet->GetActivePage() == m_pDominationRulesPage ) |
|
{ |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the property editor has made a change |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationSystemEditorPanel::OnDmeElementChanged( KeyValues *kv ) |
|
{ |
|
m_pControlsPanel->RefreshCombinationOperator(); |
|
m_pDominationRulesPanel->RefreshCombinationOperator(); |
|
m_pPropertiesPanel->Refresh(); |
|
|
|
PostActionSignal( new KeyValues( "DmeElementChanged" ) ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Purpose: Combination system editor frame |
|
// |
|
//----------------------------------------------------------------------------- |
|
CDmeCombinationSystemEditorFrame::CDmeCombinationSystemEditorFrame( vgui::Panel *pParent, const char *pTitle ) : |
|
BaseClass( pParent, "DmeCombinationSystemEditorFrame" ) |
|
{ |
|
SetDeleteSelfOnClose( true ); |
|
m_pEditor = new CDmeCombinationSystemEditorPanel( this, "DmeCombinationSystemEditorPanel" ); |
|
m_pEditor->AddActionSignalTarget( this ); |
|
m_pOpenButton = new vgui::Button( this, "OpenButton", "#FileOpenDialog_Open", this, "Open" ); |
|
m_pCancelButton = new vgui::Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" ); |
|
SetBlockDragChaining( true ); |
|
|
|
LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorframe.res" ); |
|
|
|
SetTitle( pTitle, false ); |
|
} |
|
|
|
CDmeCombinationSystemEditorFrame::~CDmeCombinationSystemEditorFrame() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the current scene + animation list |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationSystemEditorFrame::SetCombinationOperator( CDmeCombinationOperator *pComboSystem ) |
|
{ |
|
m_pEditor->SetDmeElement( pComboSystem ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// On command |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationSystemEditorFrame::OnCommand( const char *pCommand ) |
|
{ |
|
if ( !Q_stricmp( pCommand, "Open" ) ) |
|
{ |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( pCommand, "Cancel" ) ) |
|
{ |
|
return; |
|
} |
|
|
|
BaseClass::OnCommand( pCommand ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// On command |
|
//----------------------------------------------------------------------------- |
|
void CDmeCombinationSystemEditorFrame::OnDmeElementChanged() |
|
{ |
|
PostActionSignal( new KeyValues( "CombinationOperatorChanged" ) ); |
|
} |