Counter Strike : Global Offensive Source Code
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.

1970 lines
65 KiB

  1. //========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "dme_controls/dmepresetgroupeditorpanel.h"
  8. #include "dme_controls/BaseAnimSetPresetFaderPanel.h"
  9. #include "dme_controls/dmecontrols_utils.h"
  10. #include "movieobjects/dmeanimationset.h"
  11. #include "vgui_controls/ListPanel.h"
  12. #include "vgui_controls/PropertySheet.h"
  13. #include "vgui_controls/PropertyPage.h"
  14. #include "vgui_controls/Button.h"
  15. #include "vgui_controls/Menu.h"
  16. #include "vgui_controls/Splitter.h"
  17. #include "vgui_controls/MessageBox.h"
  18. #include "vgui_controls/ComboBox.h"
  19. #include "vgui_controls/InputDialog.h"
  20. #include "vgui_controls/TextEntry.h"
  21. #include "vgui/MouseCode.h"
  22. #include "vgui/IInput.h"
  23. #include "vgui/ISurface.h"
  24. #include "tier1/keyvalues.h"
  25. #include "tier1/utldict.h"
  26. #include "dme_controls/presetpicker.h"
  27. #include "vgui_controls/FileOpenDialog.h"
  28. #include "tier2/fileutils.h"
  29. #include "tier1/utlbuffer.h"
  30. #include "dme_controls/inotifyui.h"
  31. #include "../game/shared/iscenetokenprocessor.h"
  32. #include "studio.h"
  33. #include "phonemeconverter.h"
  34. // Forward declaration
  35. class CDmePresetGroupEditorPanel;
  36. //-----------------------------------------------------------------------------
  37. // Utility scope guards
  38. //-----------------------------------------------------------------------------
  39. DEFINE_SOURCE_UNDO_SCOPE_GUARD( PresetGroup, NOTIFY_SOURCE_PRESET_GROUP_EDITOR );
  40. DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( PresetGroup, NOTIFY_SOURCE_PRESET_GROUP_EDITOR );
  41. #define PRESET_FILE_FORMAT "preset"
  42. //-----------------------------------------------------------------------------
  43. //
  44. // CDmePresetGroupListPanel
  45. //
  46. // Implementation below because of scoping issues
  47. //
  48. //-----------------------------------------------------------------------------
  49. class CDmePresetGroupListPanel : public vgui::ListPanel
  50. {
  51. DECLARE_CLASS_SIMPLE( CDmePresetGroupListPanel, vgui::ListPanel );
  52. public:
  53. // constructor, destructor
  54. CDmePresetGroupListPanel( vgui::Panel *pParent, const char *pName, CDmePresetGroupEditorPanel *pComboPanel );
  55. virtual void OnCreateDragData( KeyValues *msg );
  56. virtual bool IsDroppable( CUtlVector< KeyValues * >& msgList );
  57. virtual void OnPanelDropped( CUtlVector< KeyValues * >& msgList );
  58. virtual void OnKeyCodeTyped( vgui::KeyCode code );
  59. virtual void OnMouseDoublePressed( vgui::MouseCode code );
  60. virtual void OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels );
  61. private:
  62. CDmePresetGroupEditorPanel *m_pPresetGroupPanel;
  63. };
  64. //-----------------------------------------------------------------------------
  65. //
  66. // CDmePresetListPanel
  67. //
  68. // Implementation below because of scoping issues
  69. //
  70. //-----------------------------------------------------------------------------
  71. class CDmePresetListPanel : public vgui::ListPanel
  72. {
  73. DECLARE_CLASS_SIMPLE( CDmePresetListPanel, vgui::ListPanel );
  74. public:
  75. // constructor, destructor
  76. CDmePresetListPanel( vgui::Panel *pParent, const char *pName, CDmePresetGroupEditorPanel *pComboPanel );
  77. virtual void OnKeyCodeTyped( vgui::KeyCode code );
  78. virtual void OnCreateDragData( KeyValues *msg );
  79. virtual bool IsDroppable( CUtlVector< KeyValues * >& msgList );
  80. virtual void OnPanelDropped( CUtlVector< KeyValues * >& msgList );
  81. virtual void OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels );
  82. private:
  83. CDmePresetGroupEditorPanel *m_pPresetGroupPanel;
  84. };
  85. //-----------------------------------------------------------------------------
  86. // Sort functions for list panel
  87. //-----------------------------------------------------------------------------
  88. static int __cdecl IndexSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
  89. {
  90. int nIndex1 = item1.kv->GetInt("index");
  91. int nIndex2 = item2.kv->GetInt("index");
  92. return nIndex1 - nIndex2;
  93. }
  94. //-----------------------------------------------------------------------------
  95. // constructor, destructor
  96. //-----------------------------------------------------------------------------
  97. CDmePresetGroupEditorPanel::CDmePresetGroupEditorPanel( vgui::Panel *pParent, const char *pName ) :
  98. BaseClass( pParent, pName )
  99. {
  100. m_pSplitter = new vgui::Splitter( this, "PresetGroupSplitter", vgui::SPLITTER_MODE_VERTICAL, 1 );
  101. vgui::Panel *pSplitterLeftSide = m_pSplitter->GetChild( 0 );
  102. vgui::Panel *pSplitterRightSide = m_pSplitter->GetChild( 1 );
  103. m_pPresetGroupList = new CDmePresetGroupListPanel( pSplitterLeftSide, "PresetGroupList", this );
  104. m_pPresetGroupList->AddColumnHeader( 0, "name", "Preset Group Name", 150, 0 );
  105. m_pPresetGroupList->AddColumnHeader( 1, "visible", "Visible", 70, 0 );
  106. m_pPresetGroupList->AddColumnHeader( 2, "shared", "Shared", 52, 0 );
  107. m_pPresetGroupList->AddColumnHeader( 3, "readonly", "Read Only", 52, 0 );
  108. m_pPresetGroupList->SetSelectIndividualCells( false );
  109. m_pPresetGroupList->SetMultiselectEnabled( false );
  110. m_pPresetGroupList->SetEmptyListText( "No preset groups" );
  111. m_pPresetGroupList->AddActionSignalTarget( this );
  112. m_pPresetGroupList->SetSortFunc( 0, IndexSortFunc );
  113. m_pPresetGroupList->SetSortFunc( 1, NULL );
  114. m_pPresetGroupList->SetColumnSortable( 1, false );
  115. m_pPresetGroupList->SetSortFunc( 2, NULL );
  116. m_pPresetGroupList->SetColumnSortable( 2, false );
  117. m_pPresetGroupList->SetSortFunc( 3, NULL );
  118. m_pPresetGroupList->SetColumnSortable( 3, false );
  119. m_pPresetGroupList->SetDropEnabled( true );
  120. m_pPresetGroupList->SetSortColumn( 0 );
  121. m_pPresetGroupList->SetDragEnabled( true );
  122. m_pPresetGroupList->SetDropEnabled( true );
  123. m_pPresetGroupList->SetIgnoreDoubleClick( true );
  124. m_pPresetList = new CDmePresetListPanel( pSplitterRightSide, "PresetList", this );
  125. m_pPresetList->AddColumnHeader( 0, "name", "Preset Name", 150, 0 );
  126. m_pPresetList->SetSelectIndividualCells( false );
  127. m_pPresetList->SetEmptyListText( "No presets" );
  128. m_pPresetList->AddActionSignalTarget( this );
  129. m_pPresetList->SetSortFunc( 0, IndexSortFunc );
  130. m_pPresetList->SetSortColumn( 0 );
  131. m_pPresetList->SetDragEnabled( true );
  132. m_pPresetList->SetDropEnabled( true );
  133. m_pPresetList->SetIgnoreDoubleClick( true );
  134. LoadControlSettingsAndUserConfig( "resource/dmepresetgroupeditorpanel.res" );
  135. m_hFileOpenStateMachine = new vgui::FileOpenStateMachine( this, this );
  136. m_hFileOpenStateMachine->AddActionSignalTarget( this );
  137. }
  138. CDmePresetGroupEditorPanel::~CDmePresetGroupEditorPanel()
  139. {
  140. CleanupContextMenu();
  141. SaveUserConfig();
  142. }
  143. CDmeFilmClip *CDmePresetGroupEditorPanel::GetAnimationSetClip()
  144. {
  145. return m_hFilmClip;
  146. }
  147. void CDmePresetGroupEditorPanel::SetAnimationSetClip( CDmeFilmClip *pFilmClip )
  148. {
  149. m_hFilmClip = pFilmClip;
  150. RefreshAnimationSet();
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Cleans up the context menu
  154. //-----------------------------------------------------------------------------
  155. void CDmePresetGroupEditorPanel::CleanupContextMenu()
  156. {
  157. if ( m_hContextMenu.Get() )
  158. {
  159. m_hContextMenu->MarkForDeletion();
  160. m_hContextMenu = NULL;
  161. }
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Builds the preset group list for the animation set
  165. //-----------------------------------------------------------------------------
  166. void CDmePresetGroupEditorPanel::RefreshAnimationSet()
  167. {
  168. const char *pSelectedPresetGroupName = GetSelectedPresetGroupName();
  169. m_pPresetGroupList->RemoveAll();
  170. if ( !m_hFilmClip.Get() )
  171. return;
  172. CUtlVector< PresetGroupInfo_t > presetGroupInfo;
  173. CollectPresetGroupInfo( m_hFilmClip, presetGroupInfo );
  174. int nCount = presetGroupInfo.Count();
  175. for ( int i = 0; i < nCount; ++i )
  176. {
  177. PresetGroupInfo_t &info = presetGroupInfo[ i ];
  178. const char *pPresetGroupName = info.presetGroupSym.String();
  179. KeyValues *kv = new KeyValues( "node", "name", pPresetGroupName );
  180. kv->SetString( "presetGroupName", pPresetGroupName ); // TODO - determine if this extra copy of the groupname is necessary
  181. kv->SetString( "visible", info.bGroupVisible ? "Yes" : "No" );
  182. kv->SetString( "shared", info.bGroupShared ? "Yes" : "No" );
  183. kv->SetString( "readonly", info.bGroupReadOnly ? "Yes" : "No" );
  184. kv->SetColor( "cellcolor", info.bGroupReadOnly ? Color( 255, 0, 0, 255 ) : Color( 255, 255, 255, 255 ) );
  185. kv->SetInt( "index", i );
  186. int nItemID = m_pPresetGroupList->AddItem( kv, 0, false, false );
  187. if ( pSelectedPresetGroupName && !V_strcmp( pSelectedPresetGroupName, pPresetGroupName ) )
  188. {
  189. m_pPresetGroupList->AddSelectedItem( nItemID );
  190. }
  191. }
  192. m_pPresetGroupList->SortList();
  193. RefreshPresetNames();
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Tells any class that cares that the data in this thing has changed
  197. //-----------------------------------------------------------------------------
  198. void CDmePresetGroupEditorPanel::NotifyDataChanged()
  199. {
  200. PostActionSignal( new KeyValues( "PresetsChanged" ) );
  201. }
  202. //-----------------------------------------------------------------------------
  203. // Refreshes the list of presets in the selected preset group
  204. //-----------------------------------------------------------------------------
  205. void CDmePresetGroupEditorPanel::RefreshPresetNames()
  206. {
  207. const char *pSelectedPresetName = GetSelectedPresetName();
  208. m_pPresetList->RemoveAll();
  209. if ( !m_hFilmClip.Get() )
  210. return;
  211. const char *pPresetGroupName = GetSelectedPresetGroupName();
  212. if ( !pPresetGroupName )
  213. return;
  214. CUtlVector< CUtlSymbolLarge > presetNames;
  215. if ( !V_strcmp( pPresetGroupName, PROCEDURAL_PRESET_GROUP_NAME ) )
  216. {
  217. CollectProceduralPresetNames( presetNames );
  218. }
  219. else
  220. {
  221. CollectPresetNamesForGroup( m_hFilmClip, pPresetGroupName, presetNames );
  222. }
  223. int nPresets = presetNames.Count();
  224. for ( int i = 0; i < nPresets; ++i )
  225. {
  226. const char *pPresetName = presetNames[ i ].String();
  227. KeyValues *kv = new KeyValues( "node", "name", pPresetName );
  228. kv->SetString( "presetName", pPresetName ); // TODO - determine if this extra copy of the presetname is necessary
  229. kv->SetInt( "index", i );
  230. int nItemID = m_pPresetList->AddItem( kv, 0, false, false );
  231. if ( pSelectedPresetName && !V_strcmp( pSelectedPresetName, pPresetName ) )
  232. {
  233. m_pPresetList->AddSelectedItem( nItemID );
  234. }
  235. }
  236. m_pPresetList->SortList();
  237. }
  238. //-----------------------------------------------------------------------------
  239. // Called to open a context-sensitive menu for a particular menu item
  240. //-----------------------------------------------------------------------------
  241. const char* CDmePresetGroupEditorPanel::GetSelectedPresetName()
  242. {
  243. if ( !m_hFilmClip.Get() )
  244. return NULL;
  245. int nSelectedPresetCount = m_pPresetList->GetSelectedItemsCount();
  246. if ( nSelectedPresetCount != 1 )
  247. return NULL;
  248. int nItemID = m_pPresetList->GetSelectedItem( 0 );
  249. KeyValues *pKeyValues = m_pPresetList->GetItem( nItemID );
  250. return pKeyValues->GetString( "presetName" );
  251. }
  252. //-----------------------------------------------------------------------------
  253. // Selects a particular preset
  254. //-----------------------------------------------------------------------------
  255. void CDmePresetGroupEditorPanel::SetSelectedPreset( const char* pPresetName )
  256. {
  257. m_pPresetList->ClearSelectedItems();
  258. for ( int nItemID = m_pPresetList->FirstItem();
  259. nItemID != m_pPresetList->InvalidItemID();
  260. nItemID = m_pPresetList->NextItem( nItemID ) )
  261. {
  262. KeyValues* pKeyValues = m_pPresetList->GetItem( nItemID );
  263. if ( !V_strcmp( pKeyValues->GetString( "presetName" ), pPresetName ) )
  264. {
  265. m_pPresetList->AddSelectedItem( nItemID );
  266. }
  267. }
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Called to open a context-sensitive menu for a particular menu item
  271. //-----------------------------------------------------------------------------
  272. const char *CDmePresetGroupEditorPanel::GetSelectedPresetGroupName()
  273. {
  274. if ( !m_hFilmClip.Get() )
  275. return NULL;
  276. int nSelectedItemCount = m_pPresetGroupList->GetSelectedItemsCount();
  277. if ( nSelectedItemCount != 1 )
  278. return NULL;
  279. int nItemID = m_pPresetGroupList->GetSelectedItem( 0 );
  280. KeyValues *pKeyValues = m_pPresetGroupList->GetItem( nItemID );
  281. return pKeyValues->GetString( "presetGroupName" );
  282. }
  283. //-----------------------------------------------------------------------------
  284. // Selects a particular preset group
  285. //-----------------------------------------------------------------------------
  286. void CDmePresetGroupEditorPanel::SetSelectedPresetGroup( const char* pPresetGroupName )
  287. {
  288. m_pPresetGroupList->ClearSelectedItems();
  289. for ( int nItemID = m_pPresetGroupList->FirstItem();
  290. nItemID != m_pPresetGroupList->InvalidItemID();
  291. nItemID = m_pPresetGroupList->NextItem( nItemID ) )
  292. {
  293. KeyValues* pKeyValues = m_pPresetGroupList->GetItem( nItemID );
  294. if ( !V_strcmp( pKeyValues->GetString( "presetGroupName" ), pPresetGroupName ) )
  295. {
  296. m_pPresetGroupList->AddSelectedItem( nItemID );
  297. }
  298. }
  299. }
  300. //-----------------------------------------------------------------------------
  301. // If it finds a duplicate preset name, reports an error message and returns it found one
  302. //-----------------------------------------------------------------------------
  303. bool CDmePresetGroupEditorPanel::HasDuplicatePresetName( const char *pPresetName, const char *pIgnorePresetName )
  304. {
  305. const char *pPresetGroupName = GetSelectedPresetGroupName();
  306. if ( !pPresetGroupName )
  307. return false;
  308. if ( FindAnyPreset( m_hFilmClip, pPresetGroupName, pPresetName ) && V_strcmp( pPresetName, pIgnorePresetName ) )
  309. {
  310. vgui::MessageBox *pError = new vgui::MessageBox( "#DmePresetGroupEditor_DuplicatePresetNameTitle", "#DmePresetGroupEditor_DuplicatePresetNameText", this );
  311. pError->DoModal();
  312. return true;
  313. }
  314. return false;
  315. }
  316. //-----------------------------------------------------------------------------
  317. // Called by OnInputCompleted after we get a new group name
  318. //-----------------------------------------------------------------------------
  319. void CDmePresetGroupEditorPanel::PerformRenamePreset( const char *pNewPresetName )
  320. {
  321. const char *pPresetGroupName = GetSelectedPresetGroupName();
  322. if ( !pPresetGroupName )
  323. return;
  324. const char *pPresetName = GetSelectedPresetName();
  325. if ( !pPresetName )
  326. return;
  327. if ( HasDuplicatePresetName( pNewPresetName, pPresetName ) )
  328. return;
  329. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Rename Preset" );
  330. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  331. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  332. {
  333. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  334. if ( !pPresetGroup )
  335. continue;
  336. CDmePreset *pPreset = pPresetGroup->FindOrAddPreset( pPresetName );
  337. if ( !pPreset )
  338. continue;
  339. pPreset->SetName( pNewPresetName );
  340. }
  341. sg.Release();
  342. RefreshPresetNames();
  343. NotifyDataChanged();
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Rename a preset
  347. //-----------------------------------------------------------------------------
  348. void CDmePresetGroupEditorPanel::OnRenamePreset()
  349. {
  350. const char *pPresetName = GetSelectedPresetName();
  351. if ( !pPresetName )
  352. return;
  353. vgui::InputDialog *pInput = new vgui::InputDialog( this, "Rename Preset", "Enter new name of preset" );
  354. pInput->SetMultiline( false );
  355. pInput->DoModal( new KeyValues( "OnRenamePreset" ) );
  356. }
  357. //-----------------------------------------------------------------------------
  358. // Remove a preset
  359. //-----------------------------------------------------------------------------
  360. void CDmePresetGroupEditorPanel::OnRemovePreset()
  361. {
  362. const char *pPresetGroupName = GetSelectedPresetGroupName();
  363. if ( !pPresetGroupName )
  364. return;
  365. const char *pPresetName = GetSelectedPresetName();
  366. if ( !pPresetName )
  367. return;
  368. int nItemID = m_pPresetList->GetSelectedItem( 0 );
  369. int nCurrentRow = m_pPresetList->GetItemCurrentRow( nItemID );
  370. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Remove Preset" );
  371. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  372. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  373. {
  374. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  375. if ( !pPresetGroup )
  376. continue;
  377. pPresetGroup->RemovePreset( pPresetName );
  378. }
  379. sg.Release();
  380. RefreshPresetNames();
  381. if ( nCurrentRow >= m_pPresetList->GetItemCount() )
  382. {
  383. --nCurrentRow;
  384. }
  385. if ( nCurrentRow >= 0 )
  386. {
  387. nItemID = m_pPresetList->GetItemIDFromRow( nCurrentRow );
  388. m_pPresetList->ClearSelectedItems();
  389. m_pPresetList->AddSelectedItem( nItemID );
  390. }
  391. NotifyDataChanged();
  392. }
  393. //-----------------------------------------------------------------------------
  394. // Called to open a context-sensitive menu for a particular menu item
  395. //-----------------------------------------------------------------------------
  396. void CDmePresetGroupEditorPanel::OnMovePresetUp()
  397. {
  398. if ( m_pPresetList->GetSelectedItemsCount() != 1 )
  399. return;
  400. int nItemID = m_pPresetList->GetSelectedItem( 0 );
  401. int nCurrentRow = m_pPresetList->GetItemCurrentRow( nItemID );
  402. int nPrevItemID = m_pPresetList->GetItemIDFromRow( nCurrentRow - 1 );
  403. if ( nPrevItemID < 0 )
  404. return;
  405. KeyValues *pKeyValues = m_pPresetList->GetItem( nItemID );
  406. KeyValues *pPrevKeyValues = m_pPresetList->GetItem( nPrevItemID );
  407. MovePresetInFrontOf( pKeyValues->GetString( "presetName" ), pPrevKeyValues->GetString( "presetName" ) );
  408. }
  409. //-----------------------------------------------------------------------------
  410. // Called to open a context-sensitive menu for a particular menu item
  411. //-----------------------------------------------------------------------------
  412. void CDmePresetGroupEditorPanel::OnMovePresetDown()
  413. {
  414. if ( m_pPresetList->GetSelectedItemsCount() != 1 )
  415. return;
  416. int nItemID = m_pPresetList->GetSelectedItem( 0 );
  417. int nCurrentRow = m_pPresetList->GetItemCurrentRow( nItemID );
  418. int nNextItemID = m_pPresetList->GetItemIDFromRow( nCurrentRow + 1 );
  419. if ( nNextItemID < 0 )
  420. return;
  421. KeyValues *pKeyValues = m_pPresetList->GetItem( nItemID );
  422. KeyValues *pNextKeyValues = m_pPresetList->GetItem( nNextItemID );
  423. MovePresetInFrontOf( pNextKeyValues->GetString( "presetName" ), pKeyValues->GetString( "presetName" ) );
  424. }
  425. //-----------------------------------------------------------------------------
  426. // Drag/drop reordering of presets
  427. //-----------------------------------------------------------------------------
  428. void CDmePresetGroupEditorPanel::MovePresetInFrontOf( const char *pDragPresetName, const char *pDropPresetName )
  429. {
  430. const char *pPresetGroupName = GetSelectedPresetGroupName();
  431. if ( !pPresetGroupName )
  432. return;
  433. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Reorder Presets" );
  434. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  435. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  436. {
  437. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  438. if ( !pPresetGroup )
  439. continue;
  440. CDmePreset *pDragPreset = pPresetGroup->FindPreset( pDragPresetName );
  441. if ( !pDragPreset )
  442. continue;
  443. CDmePreset *pDropPreset = pPresetGroup->FindPreset( pDropPresetName );
  444. pPresetGroup->MovePresetInFrontOf( pDragPreset, pDropPreset );
  445. }
  446. sg.Release();
  447. RefreshPresetNames();
  448. SetSelectedPreset( pDragPresetName );
  449. NotifyDataChanged();
  450. }
  451. //-----------------------------------------------------------------------------
  452. // Fileopen state machine
  453. //-----------------------------------------------------------------------------
  454. void CDmePresetGroupEditorPanel::OnFileStateMachineFinished( KeyValues *pParams )
  455. {
  456. KeyValues *pContextKeyValues = pParams->GetFirstTrueSubKey();
  457. if ( Q_stricmp( pContextKeyValues->GetName(), "ImportPresets" ) )
  458. return;
  459. CDmElement *pRoot = GetElementKeyValue<CDmElement>( pContextKeyValues, "presets" );
  460. if ( !pRoot )
  461. return;
  462. if ( pParams->GetInt( "completionState", 0 ) != 0 )
  463. {
  464. CPresetPickerFrame *pPresetPicker = new CPresetPickerFrame( this, "Select Preset(s) to Import" );
  465. pPresetPicker->AddActionSignalTarget( this );
  466. KeyValues *pContextKeyValues = new KeyValues( "ImportPicked" );
  467. SetElementKeyValue( pContextKeyValues, "presets", pRoot );
  468. pPresetPicker->DoModal( pRoot, true, pContextKeyValues );
  469. }
  470. else
  471. {
  472. // Clean up the read-in file
  473. CDisableUndoScopeGuard sg;
  474. g_pDataModel->RemoveFileId( pRoot->GetFileId() );
  475. }
  476. }
  477. //-----------------------------------------------------------------------------
  478. // Fileopen state machine
  479. //-----------------------------------------------------------------------------
  480. void CDmePresetGroupEditorPanel::SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues )
  481. {
  482. if ( bOpenFile )
  483. {
  484. pDialog->SetTitle( "Import Preset File", true );
  485. }
  486. else
  487. {
  488. pDialog->SetTitle( "Export Preset File", true );
  489. }
  490. char pPresetPath[MAX_PATH];
  491. if ( !Q_stricmp( pFileFormat, PRESET_FILE_FORMAT ) )
  492. {
  493. GetModSubdirectory( "models", pPresetPath, sizeof(pPresetPath) );
  494. pDialog->SetStartDirectoryContext( "preset_importexport", pPresetPath );
  495. pDialog->AddFilter( "*.*", "All Files (*.*)", false );
  496. pDialog->AddFilter( "*.pre", "Preset File (*.pre)", true, PRESET_FILE_FORMAT );
  497. }
  498. else if ( !Q_stricmp( pFileFormat, "vfe" ) )
  499. {
  500. GetModSubdirectory( "expressions", pPresetPath, sizeof(pPresetPath) );
  501. pDialog->SetStartDirectoryContext( "preset_exportvfe", pPresetPath );
  502. pDialog->AddFilter( "*.*", "All Files (*.*)", false );
  503. pDialog->AddFilter( "*.vfe", "Expression File (*.vfe)", true, "vfe" );
  504. }
  505. else if ( !Q_stricmp( pFileFormat, "txt" ) )
  506. {
  507. GetModSubdirectory( "expressions", pPresetPath, sizeof(pPresetPath) );
  508. pDialog->SetStartDirectoryContext( "preset_exportvfe", pPresetPath );
  509. pDialog->AddFilter( "*.*", "All Files (*.*)", false );
  510. pDialog->AddFilter( "*.txt", "Faceposer Expression File (*.txt)", true, "txt" );
  511. }
  512. }
  513. bool CDmePresetGroupEditorPanel::OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  514. {
  515. CDmElement *pRoot;
  516. CDisableUndoScopeGuard sg;
  517. DmFileId_t fileId = g_pDataModel->RestoreFromFile( pFileName, NULL, pFileFormat, &pRoot, CR_FORCE_COPY );
  518. sg.Release();
  519. if ( fileId == DMFILEID_INVALID )
  520. return false;
  521. // When importing an entire group, we can do it all right here
  522. if ( !Q_stricmp( pContextKeyValues->GetName(), "ImportPresetGroup" ) )
  523. {
  524. CDmePresetGroup *pPresetGroup = CastElement< CDmePresetGroup >( pRoot );
  525. if ( !pPresetGroup )
  526. return false;
  527. // TODO - we should be storing which animationset an item is associated with
  528. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  529. CDmeAnimationSet *pAnimSet = traversal.Next();
  530. Assert( !traversal.IsValid() );
  531. // TODO - make copy if shared bit is set?
  532. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Import Preset Group" );
  533. pPresetGroup->SetFileId( pAnimSet->GetFileId(), TD_DEEP );
  534. pAnimSet->RemovePresetGroup( pPresetGroup->GetName() );
  535. pAnimSet->GetPresetGroups().AddToTail( pPresetGroup );
  536. sg.Release();
  537. RefreshAnimationSet();
  538. NotifyDataChanged();
  539. return true;
  540. }
  541. CDmAttribute* pPresets = pRoot->GetAttribute( "presets", AT_ELEMENT_ARRAY );
  542. if ( !pPresets )
  543. return false;
  544. SetElementKeyValue( pContextKeyValues, "presets", pRoot );
  545. return true;
  546. }
  547. bool CDmePresetGroupEditorPanel::OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  548. {
  549. const char *pPresetGroupName = pContextKeyValues->GetString( "presetGroupName" );
  550. CDmeAnimationSet *pAnimSet = GetElementKeyValue< CDmeAnimationSet >( pContextKeyValues, "animSet" );
  551. CDmePresetGroup *pPresetGroup = ( pAnimSet && pPresetGroupName ) ? pAnimSet->FindPresetGroup( pPresetGroupName ) : NULL;
  552. // Used when exporting an entire preset group
  553. if ( !Q_stricmp( pContextKeyValues->GetName(), "ExportPresetGroup" ) )
  554. {
  555. if ( !pPresetGroup )
  556. return false;
  557. bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, g_pDataModel->GetDefaultEncoding( pFileFormat ), pFileFormat, pPresetGroup );
  558. return bOk;
  559. }
  560. // Used when exporting an entire preset group
  561. if ( !Q_stricmp( pContextKeyValues->GetName(), "ExportPresetGroupToVFE" ) )
  562. {
  563. if ( !pPresetGroup )
  564. return false;
  565. bool bOk = pPresetGroup->ExportToVFE( pFileName, pAnimSet );
  566. return bOk;
  567. }
  568. // Used when exporting an entire preset group
  569. if ( !Q_stricmp( pContextKeyValues->GetName(), "ExportPresetGroupToTXT" ) )
  570. {
  571. if ( !pPresetGroup )
  572. return false;
  573. bool bOk = pPresetGroup->ExportToTXT( pFileName, pAnimSet );
  574. return bOk;
  575. }
  576. // Used when exporting a subset of a preset group
  577. int nCount = pContextKeyValues->GetInt( "count" );
  578. if ( nCount == 0 )
  579. return true;
  580. Assert( pPresetGroupName == NULL );
  581. pPresetGroupName = GetSelectedPresetGroupName();
  582. if ( !pPresetGroupName )
  583. {
  584. pPresetGroupName = "root";
  585. }
  586. CDisableUndoScopeGuard sg;
  587. CDmePresetGroup *pRoot = CreateElement< CDmePresetGroup >( pPresetGroupName, DMFILEID_INVALID );
  588. CDmaElementArray< CDmePreset >& presets = pRoot->GetPresets( );
  589. // TODO - we should be storing which animationset an item is associated with
  590. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  591. pAnimSet = traversal.Next();
  592. Assert( !traversal.IsValid() );
  593. CDmePresetGroup *pSrcPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  594. // Build list of selected presets
  595. for ( int i = 0; i < nCount; ++i )
  596. {
  597. char pBuf[32];
  598. Q_snprintf( pBuf, sizeof(pBuf), "%d", i );
  599. const char *pPresetName = pContextKeyValues->GetString( pBuf );
  600. CDmePreset *pPreset = pSrcPresetGroup->FindPreset( pPresetName );
  601. if ( !pPreset )
  602. continue;
  603. presets.AddToTail( pPreset );
  604. }
  605. bool bOk = g_pDataModel->SaveToFile( pFileName, NULL, g_pDataModel->GetDefaultEncoding( pFileFormat ), pFileFormat, pRoot );
  606. g_pDataModel->DestroyElement( pRoot->GetHandle() );
  607. return bOk;
  608. }
  609. //-----------------------------------------------------------------------------
  610. // Called when preset picking is cancelled
  611. //-----------------------------------------------------------------------------
  612. void CDmePresetGroupEditorPanel::OnPresetPickCancelled( KeyValues *pParams )
  613. {
  614. KeyValues *pContextKeyValues = pParams->FindKey( "ImportPicked" );
  615. if ( pContextKeyValues )
  616. {
  617. // Clean up the read-in file
  618. CDisableUndoScopeGuard sg;
  619. CDmElement *pRoot = GetElementKeyValue<CDmElement>( pContextKeyValues, "presets" );
  620. g_pDataModel->RemoveFileId( pRoot->GetFileId() );
  621. return;
  622. }
  623. }
  624. //-----------------------------------------------------------------------------
  625. // Actually imports the presets from a file
  626. //-----------------------------------------------------------------------------
  627. void CDmePresetGroupEditorPanel::ImportPresets( CUtlVector< const char * >& presetNames, CDmElement *pRoot )
  628. {
  629. // TODO - we should be storing which animationset an item is associated with
  630. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  631. CDmeAnimationSet *pAnimSet = traversal.Next();
  632. Assert( !traversal.IsValid() );
  633. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( GetSelectedPresetGroupName() );
  634. if ( !pPresetGroup )
  635. return;
  636. CDmrElementArray< CDmePreset > srcPresets( pRoot->GetAttribute( "presets" ) );
  637. if ( !srcPresets.IsValid() || srcPresets.Count() == 0 )
  638. return;
  639. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Import Presets" );
  640. int nPresetCount = presetNames.Count();
  641. for ( int i = 0; i < nPresetCount; ++i )
  642. {
  643. const char *pPresetName = presetNames[i];
  644. CDmePreset *pPreset = pPresetGroup->FindOrAddPreset( pPresetName );
  645. CDmePreset *pSrcPreset = NULL;
  646. int nSrcPresets = srcPresets.Count();
  647. for ( int j = 0; j < nSrcPresets; ++j )
  648. {
  649. CDmePreset *p = srcPresets[ j ];
  650. if ( p && !V_strcmp( p->GetName(), pPresetName ) )
  651. {
  652. pSrcPreset = p;
  653. break;
  654. }
  655. }
  656. const CDmaElementArray< CDmElement > &srcValues = pSrcPreset->GetControlValues();
  657. CDmaElementArray< CDmElement > &values = pPreset->GetControlValues( );
  658. values.RemoveAll();
  659. int nValueCount = srcValues.Count();
  660. for ( int j = 0; j < nValueCount; ++j )
  661. {
  662. CDmElement *pSrcControlValue = srcValues[j];
  663. CDmElement *pControlValue = pSrcControlValue->Copy( );
  664. pControlValue->SetFileId( pPresetGroup->GetFileId(), TD_DEEP );
  665. values.AddToTail( pControlValue );
  666. }
  667. }
  668. RefreshAnimationSet();
  669. NotifyDataChanged();
  670. }
  671. //-----------------------------------------------------------------------------
  672. // The 'export presets' context menu option
  673. //-----------------------------------------------------------------------------
  674. void CDmePresetGroupEditorPanel::OnPresetPicked( KeyValues *pParams )
  675. {
  676. CUtlVector< const char * > presetNames;
  677. int nCount = pParams->GetInt( "count" );
  678. if ( nCount == 0 )
  679. return;
  680. // Build list of selected presets
  681. for ( int i = 0; i < nCount; ++i )
  682. {
  683. char pBuf[32];
  684. Q_snprintf( pBuf, sizeof(pBuf), "%d", i );
  685. const char *pPresetName = pParams->GetString( pBuf );
  686. presetNames.AddToTail( pPresetName );
  687. }
  688. if ( pParams->FindKey( "ExportPicked" ) )
  689. {
  690. KeyValues *pContextKeyValues = new KeyValues( "ExportPresets" );
  691. pContextKeyValues->SetInt( "count", nCount );
  692. for ( int i = 0; i < nCount; ++i )
  693. {
  694. char pBuf[32];
  695. Q_snprintf( pBuf, sizeof(pBuf), "%d", i );
  696. pContextKeyValues->SetString( pBuf, presetNames[ i ] );
  697. }
  698. m_hFileOpenStateMachine->SaveFile( pContextKeyValues, NULL, PRESET_FILE_FORMAT, vgui::FOSM_SHOW_PERFORCE_DIALOGS );
  699. return;
  700. }
  701. KeyValues *pContextKeyValues = pParams->FindKey( "ImportPicked" );
  702. if ( pContextKeyValues )
  703. {
  704. CDmElement *pRoot = GetElementKeyValue< CDmElement >( pContextKeyValues, "presets" );
  705. ImportPresets( presetNames, pRoot );
  706. // Clean up the read-in file
  707. {
  708. CDisableUndoScopeGuard sg;
  709. CDmElement *pRoot = GetElementKeyValue<CDmElement>( pContextKeyValues, "presets" );
  710. g_pDataModel->RemoveFileId( pRoot->GetFileId() );
  711. return;
  712. }
  713. }
  714. }
  715. //-----------------------------------------------------------------------------
  716. // The 'export presets' context menu option
  717. //-----------------------------------------------------------------------------
  718. void CDmePresetGroupEditorPanel::OnExportPresets()
  719. {
  720. // TODO - we should be storing which animationset an item is associated with
  721. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  722. CDmeAnimationSet *pAnimSet = traversal.Next();
  723. Assert( !traversal.IsValid() );
  724. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( GetSelectedPresetGroupName() );
  725. if ( !pPresetGroup )
  726. return;
  727. CPresetPickerFrame *pPresetPicker = new CPresetPickerFrame( this, "Select Preset(s) to Export" );
  728. pPresetPicker->AddActionSignalTarget( this );
  729. pPresetPicker->DoModal( pPresetGroup, true, new KeyValues( "ExportPicked" ) );
  730. }
  731. //-----------------------------------------------------------------------------
  732. // The 'import presets' context menu option
  733. //-----------------------------------------------------------------------------
  734. void CDmePresetGroupEditorPanel::OnImportPresets()
  735. {
  736. KeyValues *pContextKeyValues = new KeyValues( "ImportPresets" );
  737. m_hFileOpenStateMachine->OpenFile( PRESET_FILE_FORMAT, pContextKeyValues );
  738. }
  739. //-----------------------------------------------------------------------------
  740. // The 'export preset groups to VFE' context menu option
  741. //-----------------------------------------------------------------------------
  742. void CDmePresetGroupEditorPanel::OnExportPresetGroupToVFE()
  743. {
  744. // TODO - we should be storing which animationset an item is associated with
  745. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  746. CDmeAnimationSet *pAnimSet = traversal.Next();
  747. Assert( !traversal.IsValid() );
  748. const char *pPresetGroupName = GetSelectedPresetGroupName();
  749. if ( !pAnimSet->FindPresetGroup( pPresetGroupName ) )
  750. return;
  751. KeyValues *pContextKeyValues = new KeyValues( "ExportPresetGroupToVFE" );
  752. SetElementKeyValue( pContextKeyValues, "animSet", pAnimSet );
  753. pContextKeyValues->SetString( "presetGroupName", pPresetGroupName );
  754. m_hFileOpenStateMachine->SaveFile( pContextKeyValues, NULL, "vfe", vgui::FOSM_SHOW_PERFORCE_DIALOGS );
  755. }
  756. //-----------------------------------------------------------------------------
  757. // The 'export preset groups to TXT' context menu option
  758. //-----------------------------------------------------------------------------
  759. void CDmePresetGroupEditorPanel::OnExportPresetGroupToTXT()
  760. {
  761. // TODO - we should be storing which animationset an item is associated with
  762. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  763. CDmeAnimationSet *pAnimSet = traversal.Next();
  764. Assert( !traversal.IsValid() );
  765. const char *pPresetGroupName = GetSelectedPresetGroupName();
  766. if ( !pAnimSet->FindPresetGroup( pPresetGroupName ) )
  767. return;
  768. KeyValues *pContextKeyValues = new KeyValues( "ExportPresetGroupToTXT" );
  769. SetElementKeyValue( pContextKeyValues, "animSet", pAnimSet );
  770. pContextKeyValues->SetString( "presetGroupName", pPresetGroupName );
  771. m_hFileOpenStateMachine->SaveFile( pContextKeyValues, NULL, "txt", vgui::FOSM_SHOW_PERFORCE_DIALOGS );
  772. }
  773. //-----------------------------------------------------------------------------
  774. // The 'export preset groups' context menu option
  775. //-----------------------------------------------------------------------------
  776. void CDmePresetGroupEditorPanel::OnExportPresetGroups()
  777. {
  778. // TODO - we should be storing which animationset an item is associated with
  779. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  780. CDmeAnimationSet *pAnimSet = traversal.Next();
  781. Assert( !traversal.IsValid() );
  782. const char *pPresetGroupName = GetSelectedPresetGroupName();
  783. if ( !pAnimSet->FindPresetGroup( pPresetGroupName ) )
  784. return;
  785. KeyValues *pContextKeyValues = new KeyValues( "ExportPresetGroup" );
  786. SetElementKeyValue( pContextKeyValues, "animSet", pAnimSet );
  787. pContextKeyValues->SetString( "presetGroupName", pPresetGroupName );
  788. m_hFileOpenStateMachine->SaveFile( pContextKeyValues, NULL, PRESET_FILE_FORMAT, vgui::FOSM_SHOW_PERFORCE_DIALOGS );
  789. }
  790. //-----------------------------------------------------------------------------
  791. // The 'import preset groups' context menu option
  792. //-----------------------------------------------------------------------------
  793. void CDmePresetGroupEditorPanel::OnImportPresetGroups()
  794. {
  795. KeyValues *pContextKeyValues = new KeyValues( "ImportPresetGroup" );
  796. m_hFileOpenStateMachine->OpenFile( PRESET_FILE_FORMAT, pContextKeyValues );
  797. }
  798. //-----------------------------------------------------------------------------
  799. // Preset remap editor
  800. //-----------------------------------------------------------------------------
  801. void CDmePresetGroupEditorPanel::OnRemoveDefaultControls()
  802. {
  803. const char *pPresetGroupName = GetSelectedPresetGroupName();
  804. if ( !pPresetGroupName )
  805. return;
  806. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Remove Default Controls" );
  807. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  808. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  809. {
  810. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  811. if ( !pPresetGroup )
  812. continue;
  813. CDmrElementArray< CDmePreset > presets = pPresetGroup->GetPresets();
  814. int nPresetCount = presets.Count();
  815. for ( int i = 0; i < nPresetCount; ++i )
  816. {
  817. CDmePreset *pPreset = presets[i];
  818. Assert( !pPreset->IsAnimated() ); // deal with this after GDC
  819. if ( pPreset->IsAnimated() )
  820. continue;
  821. CDmrElementArray< CDmElement > controls = pPreset->GetControlValues();
  822. int nControlCount = controls.Count();
  823. for ( int j = nControlCount; --j >= 0; )
  824. {
  825. CDmElement *pControlValue = controls[j];
  826. CDmElement *pControl = pAnimSet->FindControl( pControlValue->GetName() );
  827. if ( !pControl )
  828. {
  829. controls.Remove( j );
  830. continue;
  831. }
  832. bool bIsDefault = true;
  833. float flDefaultValue = pControl->GetValue< float >( DEFAULT_FLOAT_ATTR );
  834. if ( IsStereoControl( pControl ) )
  835. {
  836. if ( flDefaultValue != pControlValue->GetValue<float>( "leftValue" ) )
  837. {
  838. bIsDefault = false;
  839. }
  840. if ( flDefaultValue != pControlValue->GetValue<float>( "rightValue" ) )
  841. {
  842. bIsDefault = false;
  843. }
  844. }
  845. else
  846. {
  847. if ( flDefaultValue != pControlValue->GetValue<float>( "value" ) )
  848. {
  849. bIsDefault = false;
  850. }
  851. }
  852. if ( bIsDefault )
  853. {
  854. controls.Remove( j );
  855. }
  856. }
  857. }
  858. }
  859. }
  860. //-----------------------------------------------------------------------------
  861. // Called to open a context-sensitive menu for a particular preset
  862. //-----------------------------------------------------------------------------
  863. void CDmePresetGroupEditorPanel::OnOpenPresetContextMenu()
  864. {
  865. if ( !m_hFilmClip.Get() )
  866. return;
  867. const char *pPresetGroupName = GetSelectedPresetGroupName();
  868. if ( !pPresetGroupName )
  869. return;
  870. m_hContextMenu = new vgui::Menu( this, "ActionMenu" );
  871. // NOTE - we're assuming that presetgroups that are readonly in one animationset are readonly in others
  872. CDmePresetGroup *pPresetGroup = FindAnyPresetGroup( m_hFilmClip, pPresetGroupName );
  873. if ( !pPresetGroup )
  874. return;
  875. if ( !pPresetGroup->m_bIsReadOnly )
  876. {
  877. if ( GetSelectedPresetName() )
  878. {
  879. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_RenamePreset", new KeyValues( "RenamePreset" ), this );
  880. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_RemovePreset", new KeyValues( "RemovePreset" ), this );
  881. m_hContextMenu->AddSeparator();
  882. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_MoveUp", new KeyValues( "MovePresetUp" ), this );
  883. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_MoveDown", new KeyValues( "MovePresetDown" ), this );
  884. }
  885. m_hContextMenu->AddSeparator();
  886. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ImportPresets", new KeyValues( "ImportPresets" ), this );
  887. }
  888. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ExportPresets", new KeyValues( "ExportPresets" ), this );
  889. vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
  890. }
  891. //-----------------------------------------------------------------------------
  892. // Called to open a context-sensitive menu for a particular menu item
  893. //-----------------------------------------------------------------------------
  894. void CDmePresetGroupEditorPanel::OnOpenContextMenu( KeyValues *kv )
  895. {
  896. CleanupContextMenu();
  897. if ( !m_hFilmClip.Get() )
  898. return;
  899. Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
  900. if ( pPanel == m_pPresetList )
  901. {
  902. OnOpenPresetContextMenu();
  903. return;
  904. }
  905. if ( pPanel != m_pPresetGroupList )
  906. return;
  907. m_hContextMenu = new vgui::Menu( this, "ActionMenu" );
  908. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_AddGroup", new KeyValues( "AddGroup" ), this );
  909. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_AddPhonemeGroup", new KeyValues( "AddPhonemeGroup" ), this );
  910. const char *pPresetGroupName = GetSelectedPresetGroupName();
  911. if ( pPresetGroupName )
  912. {
  913. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_RenameGroup", new KeyValues( "RenameGroup" ), this );
  914. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_RemoveGroup", new KeyValues( "RemoveGroup" ), this );
  915. m_hContextMenu->AddSeparator();
  916. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ToggleVisibility", new KeyValues( "ToggleGroupVisibility" ), this );
  917. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ToggleSharing", new KeyValues( "ToggleGroupSharing" ), this );
  918. m_hContextMenu->AddSeparator();
  919. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_MoveUp", new KeyValues( "MoveGroupUp" ), this );
  920. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_MoveDown", new KeyValues( "MoveGroupDown" ), this );
  921. // NOTE - we're assuming that presetgroups that are readonly in one animationset are readonly in others
  922. CDmePresetGroup *pPresetGroup = FindAnyPresetGroup( m_hFilmClip, pPresetGroupName );
  923. if ( !pPresetGroup )
  924. return;
  925. if ( !pPresetGroup->m_bIsReadOnly )
  926. {
  927. m_hContextMenu->AddSeparator();
  928. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_RemoveDefaultControls", new KeyValues( "RemoveDefaultControls" ), this );
  929. }
  930. }
  931. m_hContextMenu->AddSeparator();
  932. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ImportPresets", new KeyValues( "ImportPresetGroups" ), this );
  933. if ( pPresetGroupName )
  934. {
  935. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ExportPresets", new KeyValues( "ExportPresetGroups" ), this );
  936. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ExportPresetsToFaceposer", new KeyValues( "ExportPresetGroupsToTXT" ), this );
  937. m_hContextMenu->AddMenuItem( "#DmePresetGroupEditor_ExportPresetsToExpression", new KeyValues( "ExportPresetGroupsToVFE" ), this );
  938. }
  939. vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
  940. }
  941. //-----------------------------------------------------------------------------
  942. // Called when a list panel's selection changes
  943. //-----------------------------------------------------------------------------
  944. void CDmePresetGroupEditorPanel::OnItemSelected( KeyValues *kv )
  945. {
  946. Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
  947. if ( pPanel == m_pPresetGroupList )
  948. {
  949. RefreshPresetNames();
  950. return;
  951. }
  952. }
  953. //-----------------------------------------------------------------------------
  954. // Called when a list panel's selection changes
  955. //-----------------------------------------------------------------------------
  956. void CDmePresetGroupEditorPanel::OnItemDeselected( KeyValues *kv )
  957. {
  958. Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
  959. if ( pPanel == m_pPresetGroupList )
  960. {
  961. RefreshPresetNames();
  962. return;
  963. }
  964. }
  965. //-----------------------------------------------------------------------------
  966. // If it finds a duplicate control name, reports an error message and returns it found one
  967. //-----------------------------------------------------------------------------
  968. bool CDmePresetGroupEditorPanel::HasDuplicateGroupName( const char *pGroupName, const char *pIgnorePresetGroupName )
  969. {
  970. if ( !m_hFilmClip )
  971. return false;
  972. if ( FindAnyPresetGroup( m_hFilmClip, pGroupName ) && V_strcmp( pGroupName, pIgnorePresetGroupName ) )
  973. {
  974. vgui::MessageBox *pError = new vgui::MessageBox( "#DmePresetGroupEditor_DuplicateNameTitle", "#DmePresetGroupEditor_DuplicateNameText", this );
  975. pError->DoModal();
  976. return true;
  977. }
  978. return false;
  979. }
  980. //-----------------------------------------------------------------------------
  981. // Called by OnInputCompleted after we get a new group name
  982. //-----------------------------------------------------------------------------
  983. void CDmePresetGroupEditorPanel::PerformAddGroup( const char *pNewGroupName )
  984. {
  985. if ( !m_hFilmClip )
  986. return;
  987. if ( HasDuplicateGroupName( pNewGroupName ) )
  988. return;
  989. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Add Preset Group" );
  990. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  991. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  992. {
  993. pAnimSet->FindOrAddPresetGroup( pNewGroupName );
  994. }
  995. sg.Release();
  996. RefreshAnimationSet();
  997. SetSelectedPresetGroup( pNewGroupName );
  998. NotifyDataChanged();
  999. }
  1000. //-----------------------------------------------------------------------------
  1001. // Called by OnInputCompleted after we get a new group name
  1002. //-----------------------------------------------------------------------------
  1003. void CDmePresetGroupEditorPanel::PerformAddPhonemeGroup( const char *pNewGroupName )
  1004. {
  1005. if ( !m_hFilmClip )
  1006. return;
  1007. if ( HasDuplicateGroupName( pNewGroupName ) )
  1008. return;
  1009. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Add Phoneme Preset Group" );
  1010. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  1011. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  1012. {
  1013. CDmePresetGroup *pPresetGroup = pAnimSet->FindOrAddPresetGroup( pNewGroupName );
  1014. int nPhonemeCount = NumPhonemes();
  1015. for ( int i = 0; i < nPhonemeCount; ++i )
  1016. {
  1017. if ( !IsStandardPhoneme( i ) )
  1018. continue;
  1019. char pTempBuf[256];
  1020. const char *pPhonemeName = NameForPhonemeByIndex( i );
  1021. if ( !Q_stricmp( pPhonemeName, "<sil>" ) )
  1022. {
  1023. pPhonemeName = "silence";
  1024. }
  1025. Q_snprintf( pTempBuf, sizeof(pTempBuf), "p_%s", pPhonemeName );
  1026. pPresetGroup->FindOrAddPreset( pTempBuf );
  1027. }
  1028. }
  1029. sg.Release();
  1030. RefreshAnimationSet();
  1031. SetSelectedPresetGroup( pNewGroupName );
  1032. NotifyDataChanged();
  1033. }
  1034. //-----------------------------------------------------------------------------
  1035. // Called by OnInputCompleted after we get a new group name
  1036. //-----------------------------------------------------------------------------
  1037. void CDmePresetGroupEditorPanel::PerformRenameGroup( const char *pNewGroupName )
  1038. {
  1039. const char *pPresetGroupName = GetSelectedPresetGroupName();
  1040. if ( !pPresetGroupName )
  1041. return;
  1042. if ( HasDuplicateGroupName( pNewGroupName, pPresetGroupName ) )
  1043. return;
  1044. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Rename Preset Group" );
  1045. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  1046. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  1047. {
  1048. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  1049. if ( !pPresetGroup )
  1050. continue;
  1051. pPresetGroup->SetName( pNewGroupName );
  1052. }
  1053. sg.Release();
  1054. RefreshAnimationSet();
  1055. NotifyDataChanged();
  1056. }
  1057. //-----------------------------------------------------------------------------
  1058. // Called by OnGroupControls after we get a new group name
  1059. //-----------------------------------------------------------------------------
  1060. void CDmePresetGroupEditorPanel::OnInputCompleted( KeyValues *pKeyValues )
  1061. {
  1062. const char *pName = pKeyValues->GetString( "text", NULL );
  1063. if ( !pName || !pName[0] )
  1064. return;
  1065. if ( pKeyValues->FindKey( "OnAddGroup" ) )
  1066. {
  1067. PerformAddGroup( pName );
  1068. return;
  1069. }
  1070. if ( pKeyValues->FindKey( "OnAddPhonemeGroup" ) )
  1071. {
  1072. PerformAddPhonemeGroup( pName );
  1073. return;
  1074. }
  1075. if ( pKeyValues->FindKey( "OnRenameGroup" ) )
  1076. {
  1077. PerformRenameGroup( pName );
  1078. return;
  1079. }
  1080. if ( pKeyValues->FindKey( "OnRenamePreset" ) )
  1081. {
  1082. PerformRenamePreset( pName );
  1083. return;
  1084. }
  1085. }
  1086. //-----------------------------------------------------------------------------
  1087. // Toggle group visibility
  1088. //-----------------------------------------------------------------------------
  1089. void CDmePresetGroupEditorPanel::ToggleGroupVisibility( const char *pPresetGroupName )
  1090. {
  1091. if ( !pPresetGroupName )
  1092. return;
  1093. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Toggle Preset Group Visibility" );
  1094. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  1095. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  1096. {
  1097. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  1098. if ( !pPresetGroup )
  1099. continue;
  1100. pPresetGroup->m_bIsVisible = !pPresetGroup->m_bIsVisible;
  1101. }
  1102. RefreshAnimationSet();
  1103. NotifyDataChanged();
  1104. }
  1105. //-----------------------------------------------------------------------------
  1106. // Ungroup controls from each other
  1107. //-----------------------------------------------------------------------------
  1108. void CDmePresetGroupEditorPanel::OnToggleGroupVisibility()
  1109. {
  1110. const char *pPresetGroupName = GetSelectedPresetGroupName();
  1111. if ( !pPresetGroupName )
  1112. return;
  1113. ToggleGroupVisibility( pPresetGroupName );
  1114. }
  1115. //-----------------------------------------------------------------------------
  1116. // Ungroup controls from each other
  1117. //-----------------------------------------------------------------------------
  1118. void CDmePresetGroupEditorPanel::OnToggleGroupSharing()
  1119. {
  1120. const char *pPresetGroupName = GetSelectedPresetGroupName();
  1121. if ( !pPresetGroupName )
  1122. return;
  1123. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Toggle Preset Group Sharing" );
  1124. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  1125. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  1126. {
  1127. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName );
  1128. if ( !pPresetGroup )
  1129. continue;
  1130. pPresetGroup->SetShared( !pPresetGroup->IsShared() );
  1131. }
  1132. RefreshAnimationSet();
  1133. }
  1134. //-----------------------------------------------------------------------------
  1135. // Add a preset group
  1136. //-----------------------------------------------------------------------------
  1137. void CDmePresetGroupEditorPanel::OnAddGroup()
  1138. {
  1139. vgui::InputDialog *pInput = new vgui::InputDialog( this, "Add Preset Group", "Enter name of new preset group" );
  1140. pInput->SetMultiline( false );
  1141. pInput->DoModal( new KeyValues( "OnAddGroup" ) );
  1142. }
  1143. //-----------------------------------------------------------------------------
  1144. // Add a preset group
  1145. //-----------------------------------------------------------------------------
  1146. void CDmePresetGroupEditorPanel::OnAddPhonemeGroup()
  1147. {
  1148. vgui::InputDialog *pInput = new vgui::InputDialog( this, "Add Phoneme Preset Group", "Enter name of new preset group", "phoneme" );
  1149. pInput->SetMultiline( false );
  1150. pInput->DoModal( new KeyValues( "OnAddPhonemeGroup" ) );
  1151. }
  1152. //-----------------------------------------------------------------------------
  1153. // Rename a preset group
  1154. //-----------------------------------------------------------------------------
  1155. void CDmePresetGroupEditorPanel::OnRenameGroup()
  1156. {
  1157. const char *pPresetGroupName = GetSelectedPresetGroupName();
  1158. if ( !pPresetGroupName )
  1159. return;
  1160. vgui::InputDialog *pInput = new vgui::InputDialog( this, "Rename Preset Group", "Enter new name of preset group" );
  1161. pInput->SetMultiline( false );
  1162. pInput->DoModal( new KeyValues( "OnRenameGroup" ) );
  1163. }
  1164. //-----------------------------------------------------------------------------
  1165. // Remove a preset group
  1166. //-----------------------------------------------------------------------------
  1167. void CDmePresetGroupEditorPanel::OnRemoveGroup()
  1168. {
  1169. if ( !m_hFilmClip.Get() )
  1170. return;
  1171. const char *pPresetGroupName = GetSelectedPresetGroupName();
  1172. if ( !pPresetGroupName )
  1173. return;
  1174. if ( !Q_stricmp( pPresetGroupName, "procedural" ) )
  1175. {
  1176. vgui::MessageBox *pError = new vgui::MessageBox( "#DmePresetGroupEditor_CannotRemovePresetGroupTitle", "#DmePresetGroupEditor_CannotRemovePresetGroupText", this );
  1177. pError->DoModal();
  1178. return;
  1179. }
  1180. int nItemID = m_pPresetGroupList->GetSelectedItem( 0 );
  1181. int nCurrentRow = m_pPresetGroupList->GetItemCurrentRow( nItemID );
  1182. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Remove Preset Group" );
  1183. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  1184. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  1185. {
  1186. pAnimSet->RemovePresetGroup( pPresetGroupName );
  1187. }
  1188. sg.Release();
  1189. RefreshAnimationSet();
  1190. if ( nCurrentRow >= m_pPresetGroupList->GetItemCount() )
  1191. {
  1192. --nCurrentRow;
  1193. }
  1194. if ( nCurrentRow >= 0 )
  1195. {
  1196. nItemID = m_pPresetGroupList->GetItemIDFromRow( nCurrentRow );
  1197. m_pPresetGroupList->ClearSelectedItems();
  1198. m_pPresetGroupList->AddSelectedItem( nItemID );
  1199. }
  1200. NotifyDataChanged();
  1201. }
  1202. //-----------------------------------------------------------------------------
  1203. // Called to open a context-sensitive menu for a particular menu item
  1204. //-----------------------------------------------------------------------------
  1205. void CDmePresetGroupEditorPanel::OnMoveGroupUp()
  1206. {
  1207. if ( m_pPresetGroupList->GetSelectedItemsCount() != 1 )
  1208. return;
  1209. int nItemID = m_pPresetGroupList->GetSelectedItem( 0 );
  1210. int nCurrentRow = m_pPresetGroupList->GetItemCurrentRow( nItemID );
  1211. int nPrevItemID = m_pPresetGroupList->GetItemIDFromRow( nCurrentRow - 1 );
  1212. if ( nPrevItemID < 0 )
  1213. return;
  1214. KeyValues *pKeyValues = m_pPresetGroupList->GetItem( nItemID );
  1215. KeyValues *pPrevKeyValues = m_pPresetGroupList->GetItem( nPrevItemID );
  1216. MovePresetGroupInFrontOf( pKeyValues->GetString( "presetGroupName" ), pPrevKeyValues->GetString( "presetGroupName" ) );
  1217. }
  1218. //-----------------------------------------------------------------------------
  1219. // Called to open a context-sensitive menu for a particular menu item
  1220. //-----------------------------------------------------------------------------
  1221. void CDmePresetGroupEditorPanel::OnMoveGroupDown()
  1222. {
  1223. if ( m_pPresetGroupList->GetSelectedItemsCount() != 1 )
  1224. return;
  1225. int nItemID = m_pPresetGroupList->GetSelectedItem( 0 );
  1226. int nCurrentRow = m_pPresetGroupList->GetItemCurrentRow( nItemID );
  1227. int nNextItemID = m_pPresetGroupList->GetItemIDFromRow( nCurrentRow + 1 );
  1228. if ( nNextItemID < 0 )
  1229. return;
  1230. KeyValues *pKeyValues = m_pPresetGroupList->GetItem( nItemID );
  1231. KeyValues *pNextKeyValues = m_pPresetGroupList->GetItem( nNextItemID );
  1232. MovePresetGroupInFrontOf( pNextKeyValues->GetString( "presetGroupName" ), pKeyValues->GetString( "presetGroupName" ) );
  1233. }
  1234. //-----------------------------------------------------------------------------
  1235. // Drag/drop reordering of preset groups
  1236. //-----------------------------------------------------------------------------
  1237. void CDmePresetGroupEditorPanel::MovePresetGroupInFrontOf( const char *pDragGroupName, const char *pDropGroupName )
  1238. {
  1239. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Reorder Preset Groups" );
  1240. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  1241. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  1242. {
  1243. CDmePresetGroup *pDragPresetGroup = pAnimSet->FindPresetGroup( pDragGroupName );
  1244. if ( !pDragPresetGroup )
  1245. continue;
  1246. CDmePresetGroup *pDropPresetGroup = pAnimSet->FindPresetGroup( pDropGroupName );
  1247. pAnimSet->MovePresetGroupInFrontOf( pDragPresetGroup, pDropPresetGroup );
  1248. }
  1249. sg.Release();
  1250. RefreshAnimationSet();
  1251. SetSelectedPresetGroup( pDragGroupName );
  1252. NotifyDataChanged();
  1253. }
  1254. //-----------------------------------------------------------------------------
  1255. // Drag/drop preset moving
  1256. //-----------------------------------------------------------------------------
  1257. void CDmePresetGroupEditorPanel::MovePresetIntoGroup( const char *pPresetName, const char *pSrcGroupName, const char *pDstGroupName )
  1258. {
  1259. if ( !m_hFilmClip.Get() || !pPresetName || !pSrcGroupName || !pDstGroupName )
  1260. return;
  1261. CPresetGroupUndoScopeGuard sg( NOTIFY_SETDIRTYFLAG, "Change Preset Group" );
  1262. CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip );
  1263. while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
  1264. {
  1265. CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pSrcGroupName );
  1266. if ( !pPresetGroup )
  1267. continue;
  1268. CDmePreset *pPreset = pPresetGroup->FindPreset( pPresetName );
  1269. if ( !pPreset )
  1270. continue;
  1271. pPresetGroup->RemovePreset( pPresetName );
  1272. CDmePresetGroup *pDstPresetGroup = pAnimSet->FindOrAddPresetGroup( pDstGroupName );
  1273. pDstPresetGroup->FindOrAddPreset( pPresetName );
  1274. }
  1275. sg.Release();
  1276. RefreshPresetNames();
  1277. NotifyDataChanged();
  1278. }
  1279. //-----------------------------------------------------------------------------
  1280. //
  1281. //
  1282. // CDmePresetGroupListPanel
  1283. //
  1284. // Declaration above because of scoping issues
  1285. //
  1286. //
  1287. //-----------------------------------------------------------------------------
  1288. //-----------------------------------------------------------------------------
  1289. // Constructor, destructor
  1290. //-----------------------------------------------------------------------------
  1291. CDmePresetGroupListPanel::CDmePresetGroupListPanel( vgui::Panel *pParent, const char *pName, CDmePresetGroupEditorPanel *pComboPanel ) :
  1292. BaseClass( pParent, pName ), m_pPresetGroupPanel( pComboPanel )
  1293. {
  1294. }
  1295. //-----------------------------------------------------------------------------
  1296. // Handle keypresses
  1297. //-----------------------------------------------------------------------------
  1298. void CDmePresetGroupListPanel::OnMouseDoublePressed( vgui::MouseCode code )
  1299. {
  1300. if ( code == MOUSE_LEFT )
  1301. {
  1302. int x, y, row, column;
  1303. vgui::input()->GetCursorPos( x, y );
  1304. GetCellAtPos( x, y, row, column );
  1305. int itemId = GetItemIDFromRow( row );
  1306. KeyValues *pKeyValues = GetItem( itemId );
  1307. m_pPresetGroupPanel->ToggleGroupVisibility( pKeyValues->GetString( "presetGroupName" ) );
  1308. return;
  1309. }
  1310. BaseClass::OnMouseDoublePressed( code );
  1311. }
  1312. //-----------------------------------------------------------------------------
  1313. // Handle keypresses
  1314. //-----------------------------------------------------------------------------
  1315. void CDmePresetGroupListPanel::OnKeyCodeTyped( vgui::KeyCode code )
  1316. {
  1317. if ( code == KEY_DELETE || code == KEY_BACKSPACE )
  1318. {
  1319. m_pPresetGroupPanel->OnRemoveGroup();
  1320. return;
  1321. }
  1322. if ( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) )
  1323. {
  1324. if ( code == KEY_UP )
  1325. {
  1326. m_pPresetGroupPanel->OnMoveGroupUp();
  1327. return;
  1328. }
  1329. if ( code == KEY_DOWN )
  1330. {
  1331. m_pPresetGroupPanel->OnMoveGroupDown();
  1332. return;
  1333. }
  1334. }
  1335. vgui::ListPanel::OnKeyCodeTyped( code );
  1336. }
  1337. //-----------------------------------------------------------------------------
  1338. // Called when a list panel's selection changes
  1339. //-----------------------------------------------------------------------------
  1340. void CDmePresetGroupListPanel::OnCreateDragData( KeyValues *msg )
  1341. {
  1342. const char *pPresetGroupName = m_pPresetGroupPanel->GetSelectedPresetGroupName();
  1343. if ( !pPresetGroupName )
  1344. return;
  1345. msg->SetString( "presetGroupName", pPresetGroupName );
  1346. msg->SetInt( "selfDroppable", 1 );
  1347. }
  1348. //-----------------------------------------------------------------------------
  1349. // Called when a list panel's selection changes
  1350. //-----------------------------------------------------------------------------
  1351. bool CDmePresetGroupListPanel::IsDroppable( CUtlVector< KeyValues * >& msgList )
  1352. {
  1353. if ( msgList.Count() > 0 )
  1354. {
  1355. KeyValues *pData( msgList[ 0 ] );
  1356. if ( m_pPresetGroupPanel )
  1357. {
  1358. const char *pPresetGroupName = pData->GetString( "presetGroupName" );
  1359. if ( pPresetGroupName )
  1360. return true;
  1361. const char *pPresetName = pData->GetString( "presetName" );
  1362. if ( pPresetName )
  1363. {
  1364. // Can't drop presets onto read-only preset groups
  1365. int x, y, row, column;
  1366. vgui::input()->GetCursorPos( x, y );
  1367. GetCellAtPos( x, y, row, column );
  1368. KeyValues *pKeyValues = GetItem( row );
  1369. const char *pDropGroupName = pKeyValues ? pKeyValues->GetString( "presetGroupName" ) : NULL;
  1370. CDmePresetGroup *pDropGroup = FindAnyPresetGroup( m_pPresetGroupPanel->GetAnimationSetClip(), pDropGroupName );
  1371. if ( pDropGroup && !pDropGroup->m_bIsReadOnly )
  1372. return true;
  1373. }
  1374. }
  1375. }
  1376. return false;
  1377. }
  1378. //-----------------------------------------------------------------------------
  1379. // Called when a list panel's selection changes
  1380. //-----------------------------------------------------------------------------
  1381. void CDmePresetGroupListPanel::OnPanelDropped( CUtlVector< KeyValues * >& msgList )
  1382. {
  1383. if ( msgList.Count() == 0 )
  1384. return;
  1385. KeyValues *pData = msgList[ 0 ];
  1386. if ( !m_pPresetGroupPanel )
  1387. return;
  1388. // Discover the cell the panel is over
  1389. int x, y, row, column;
  1390. vgui::input()->GetCursorPos( x, y );
  1391. GetCellAtPos( x, y, row, column );
  1392. int nItemID = GetItemIDFromRow( row );
  1393. KeyValues *pKeyValues = GetItem( nItemID );
  1394. if ( !pKeyValues )
  1395. return;
  1396. const char *pDropGroupName = pKeyValues->GetString( "presetGroupName" );
  1397. const char *pDragGroupName = pData->GetString( "presetGroupName" );
  1398. if ( pDragGroupName )
  1399. {
  1400. m_pPresetGroupPanel->MovePresetGroupInFrontOf( pDragGroupName, pDropGroupName );
  1401. return;
  1402. }
  1403. const char *pDragPresetName = pData->GetString( "presetName" );
  1404. if ( pDragPresetName )
  1405. {
  1406. m_pPresetGroupPanel->MovePresetIntoGroup( pDragPresetName, pDragGroupName, pDropGroupName );
  1407. }
  1408. }
  1409. //-----------------------------------------------------------------------------
  1410. // Mouse is now over a droppable panel
  1411. //-----------------------------------------------------------------------------
  1412. void CDmePresetGroupListPanel::OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels )
  1413. {
  1414. // Discover the cell the panel is over
  1415. int x, y, w, h, row, column;
  1416. vgui::input()->GetCursorPos( x, y );
  1417. GetCellAtPos( x, y, row, column );
  1418. GetCellBounds( row, 0, x, y, w, h );
  1419. int x2, y2, w2, h2;
  1420. GetCellBounds( row, 3, x2, y2, w2, h2 );
  1421. w = x2 + w2 - x;
  1422. LocalToScreen( x, y );
  1423. surface()->DrawSetColor( GetDropFrameColor() );
  1424. // Draw insertion point
  1425. surface()->DrawFilledRect( x, y, x + w, y + 2 );
  1426. surface()->DrawFilledRect( x, y + h - 2, x + w, y + h );
  1427. surface()->DrawFilledRect( x, y, x + 2, y + h );
  1428. surface()->DrawFilledRect( x + w - 2, y, x + w, y + h );
  1429. }
  1430. //-----------------------------------------------------------------------------
  1431. //
  1432. //
  1433. // CDmePresetListPanel
  1434. //
  1435. // Declaration above because of scoping issues
  1436. //
  1437. //
  1438. //-----------------------------------------------------------------------------
  1439. //-----------------------------------------------------------------------------
  1440. // Constructor, destructor
  1441. //-----------------------------------------------------------------------------
  1442. CDmePresetListPanel::CDmePresetListPanel( vgui::Panel *pParent, const char *pName, CDmePresetGroupEditorPanel *pComboPanel ) :
  1443. BaseClass( pParent, pName ), m_pPresetGroupPanel( pComboPanel )
  1444. {
  1445. }
  1446. void CDmePresetListPanel::OnKeyCodeTyped( vgui::KeyCode code )
  1447. {
  1448. const char *pPresetGroupName = m_pPresetGroupPanel->GetSelectedPresetGroupName();
  1449. if ( !pPresetGroupName )
  1450. return;
  1451. // NOTE - we're assuming that presetgroups that are readonly in one animationset are readonly in others
  1452. CDmePresetGroup *pPresetGroup = FindAnyPresetGroup( m_pPresetGroupPanel->GetAnimationSetClip(), pPresetGroupName );
  1453. if ( pPresetGroup && !pPresetGroup->m_bIsReadOnly )
  1454. {
  1455. if ( code == KEY_DELETE || code == KEY_BACKSPACE )
  1456. {
  1457. m_pPresetGroupPanel->OnRemovePreset();
  1458. return;
  1459. }
  1460. // Not sure how to handle 'edit' mode... the relevant stuff is private
  1461. if ( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) )
  1462. {
  1463. if ( code == KEY_UP )
  1464. {
  1465. m_pPresetGroupPanel->OnMovePresetUp();
  1466. return;
  1467. }
  1468. if ( code == KEY_DOWN )
  1469. {
  1470. m_pPresetGroupPanel->OnMovePresetDown();
  1471. return;
  1472. }
  1473. }
  1474. }
  1475. vgui::ListPanel::OnKeyCodeTyped( code );
  1476. }
  1477. //-----------------------------------------------------------------------------
  1478. // Called when a list panel's selection changes
  1479. //-----------------------------------------------------------------------------
  1480. void CDmePresetListPanel::OnCreateDragData( KeyValues *msg )
  1481. {
  1482. const char *pPresetGroupName = m_pPresetGroupPanel->GetSelectedPresetGroupName();
  1483. if ( !pPresetGroupName )
  1484. return;
  1485. // NOTE - we're assuming that presetgroups that are readonly in one animationset are readonly in others
  1486. CDmePresetGroup *pPresetGroup = FindAnyPresetGroup( m_pPresetGroupPanel->GetAnimationSetClip(), pPresetGroupName );
  1487. if ( pPresetGroup->m_bIsReadOnly )
  1488. return;
  1489. const char *pPresetName = m_pPresetGroupPanel->GetSelectedPresetName();
  1490. if ( !pPresetName )
  1491. return;
  1492. msg->SetString( "presetName", pPresetName );
  1493. msg->SetString( "presetGroupName", pPresetGroupName );
  1494. msg->SetInt( "selfDroppable", 1 );
  1495. }
  1496. //-----------------------------------------------------------------------------
  1497. // Called when a list panel's selection changes
  1498. //-----------------------------------------------------------------------------
  1499. bool CDmePresetListPanel::IsDroppable( CUtlVector< KeyValues * >& msgList )
  1500. {
  1501. if ( msgList.Count() > 0 )
  1502. {
  1503. KeyValues *pData( msgList[ 0 ] );
  1504. if ( pData->GetPtr( "panel", NULL ) == this && m_pPresetGroupPanel )
  1505. {
  1506. if ( pData->GetString( "presetName", NULL ) )
  1507. return true;
  1508. }
  1509. }
  1510. return false;
  1511. }
  1512. //-----------------------------------------------------------------------------
  1513. // Called when a list panel's selection changes
  1514. //-----------------------------------------------------------------------------
  1515. void CDmePresetListPanel::OnPanelDropped( CUtlVector< KeyValues * >& msgList )
  1516. {
  1517. if ( msgList.Count() == 0 )
  1518. return;
  1519. KeyValues *pData = msgList[ 0 ];
  1520. if ( pData->GetPtr( "panel", NULL ) != this || !m_pPresetGroupPanel )
  1521. return;
  1522. // Discover the cell the panel is over
  1523. int x, y, row, column;
  1524. vgui::input()->GetCursorPos( x, y );
  1525. GetCellAtPos( x, y, row, column );
  1526. int nItemID = GetItemIDFromRow( row );
  1527. KeyValues *pKeyValues = GetItem( nItemID );
  1528. const char *pDragPresetName = pData ->GetString( "presetName", NULL );
  1529. const char *pDropPresetName = pKeyValues->GetString( "presetName", NULL );
  1530. if ( pDragPresetName && pDropPresetName )
  1531. {
  1532. m_pPresetGroupPanel->MovePresetInFrontOf( pDragPresetName, pDropPresetName );
  1533. }
  1534. }
  1535. //-----------------------------------------------------------------------------
  1536. // Mouse is now over a droppable panel
  1537. //-----------------------------------------------------------------------------
  1538. void CDmePresetListPanel::OnDroppablePanelPaint( CUtlVector< KeyValues * >& msglist, CUtlVector< Panel * >& dragPanels )
  1539. {
  1540. // Discover the cell the panel is over
  1541. int x, y, w, h, row, column;
  1542. vgui::input()->GetCursorPos( x, y );
  1543. GetCellAtPos( x, y, row, column );
  1544. GetCellBounds( row, column, x, y, w, h );
  1545. LocalToScreen( x, y );
  1546. surface()->DrawSetColor( GetDropFrameColor() );
  1547. // Draw insertion point
  1548. surface()->DrawFilledRect( x, y, x + w, y + 2 );
  1549. surface()->DrawFilledRect( x, y + h - 2, x + w, y + h );
  1550. surface()->DrawFilledRect( x, y, x + 2, y + h );
  1551. surface()->DrawFilledRect( x + w - 2, y, x + w, y + h );
  1552. }
  1553. //-----------------------------------------------------------------------------
  1554. //
  1555. // Purpose: Combination system editor frame
  1556. //
  1557. //-----------------------------------------------------------------------------
  1558. CDmePresetGroupEditorFrame::CDmePresetGroupEditorFrame( vgui::Panel *pParent, const char *pTitle ) :
  1559. BaseClass( pParent, "DmePresetGroupEditorFrame" )
  1560. {
  1561. SetDeleteSelfOnClose( true );
  1562. m_pEditor = new CDmePresetGroupEditorPanel( this, "DmePresetGroupEditorPanel" );
  1563. m_pEditor->AddActionSignalTarget( this );
  1564. m_pOkButton = new vgui::Button( this, "OkButton", "#VGui_OK", this, "Ok" );
  1565. SetBlockDragChaining( true );
  1566. LoadControlSettingsAndUserConfig( "resource/dmepresetgroupeditorframe.res" );
  1567. SetTitle( pTitle, false );
  1568. g_pDataModel->InstallNotificationCallback( this );
  1569. }
  1570. CDmePresetGroupEditorFrame::~CDmePresetGroupEditorFrame()
  1571. {
  1572. g_pDataModel->RemoveNotificationCallback( this );
  1573. }
  1574. //-----------------------------------------------------------------------------
  1575. // On command
  1576. //-----------------------------------------------------------------------------
  1577. void CDmePresetGroupEditorFrame::OnCommand( const char *pCommand )
  1578. {
  1579. if ( !Q_stricmp( pCommand, "Ok" ) )
  1580. {
  1581. CloseModal();
  1582. return;
  1583. }
  1584. BaseClass::OnCommand( pCommand );
  1585. }
  1586. //-----------------------------------------------------------------------------
  1587. // Inherited from IDmNotify
  1588. //-----------------------------------------------------------------------------
  1589. void CDmePresetGroupEditorFrame::NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags )
  1590. {
  1591. if ( !IsVisible() )
  1592. return;
  1593. if ( nNotifySource == NOTIFY_SOURCE_PRESET_GROUP_EDITOR )
  1594. return;
  1595. m_pEditor->RefreshAnimationSet();
  1596. }
  1597. //-----------------------------------------------------------------------------
  1598. // Chains notification messages from the contained panel to external clients
  1599. //-----------------------------------------------------------------------------
  1600. void CDmePresetGroupEditorFrame::OnPresetsChanged()
  1601. {
  1602. PostActionSignal( new KeyValues( "PresetsChanged" ) );
  1603. }
  1604. //-----------------------------------------------------------------------------
  1605. // Various command handlers related to the Edit menu
  1606. //-----------------------------------------------------------------------------
  1607. void CDmePresetGroupEditorFrame::OnUndo()
  1608. {
  1609. if ( g_pDataModel->CanUndo() )
  1610. {
  1611. CDisableUndoScopeGuard guard;
  1612. g_pDataModel->Undo();
  1613. }
  1614. }
  1615. void CDmePresetGroupEditorFrame::OnRedo()
  1616. {
  1617. if ( g_pDataModel->CanRedo() )
  1618. {
  1619. CDisableUndoScopeGuard guard;
  1620. g_pDataModel->Redo();
  1621. }
  1622. }