Team Fortress 2 Source Code as on 22/4/2020
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.

2149 lines
73 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "dme_controls/dmecombinationsystemeditorpanel.h"
  8. #include "dme_controls/dmepanel.h"
  9. #include "dme_controls/elementpropertiestree.h"
  10. #include "dme_controls/dmecontrols_utils.h"
  11. #include "movieobjects/dmecombinationoperator.h"
  12. #include "vgui_controls/ListPanel.h"
  13. #include "vgui_controls/PropertySheet.h"
  14. #include "vgui_controls/PropertyPage.h"
  15. #include "vgui_controls/Button.h"
  16. #include "vgui_controls/Menu.h"
  17. #include "vgui_controls/Splitter.h"
  18. #include "vgui_controls/MessageBox.h"
  19. #include "vgui_controls/InputDialog.h"
  20. #include "vgui_controls/TextEntry.h"
  21. #include "vgui_controls/FileOpenDialog.h"
  22. #include "vgui_controls/perforcefilelistframe.h"
  23. #include "vgui/MouseCode.h"
  24. #include "vgui/IInput.h"
  25. #include "tier1/KeyValues.h"
  26. #include "tier2/fileutils.h"
  27. //-----------------------------------------------------------------------------
  28. //
  29. // Hook into the dme panel editor system
  30. //
  31. //-----------------------------------------------------------------------------
  32. IMPLEMENT_DMEPANEL_FACTORY( CDmeCombinationSystemEditorPanel, DmeCombinationOperator, "DmeCombinationOperatorEditor", "Combination Operator Editor", true );
  33. // Forward declaration
  34. class CDmeCombinationControlsPanel;
  35. //-----------------------------------------------------------------------------
  36. // Import combination rules from this operator
  37. //-----------------------------------------------------------------------------
  38. static void ImportCombinationControls( CDmeCombinationOperator *pDestComboOp, CDmeCombinationOperator *pSrcComboOp, COperationFileListFrame *pStatusFrame )
  39. {
  40. pDestComboOp->RemoveAllControls();
  41. // Iterate through all controls in the imported operator.
  42. // For each control that contains at least 1 raw controls
  43. // that also exist in this combination op, create a control here also.
  44. int nCount = pSrcComboOp->GetControlCount();
  45. for ( int i = 0; i < nCount; ++i )
  46. {
  47. const char *pControlName = pSrcComboOp->GetControlName( i );
  48. int nRawControls = pSrcComboOp->GetRawControlCount( i );
  49. int nMatchCount = 0;
  50. bool *pFoundMatch = (bool*)_alloca( nRawControls * sizeof(bool) );
  51. for ( int j = 0; j < nRawControls; ++j )
  52. {
  53. const char *pRawControl = pSrcComboOp->GetRawControlName( i, j );
  54. pFoundMatch[j] = pDestComboOp->DoesTargetContainDeltaState( pRawControl );
  55. nMatchCount += pFoundMatch[j];
  56. }
  57. // No match? Don't import
  58. if ( nMatchCount == 0 )
  59. {
  60. pStatusFrame->AddOperation( pControlName, "No raw controls found!" );
  61. continue;
  62. }
  63. bool bPartialMatch = ( nMatchCount != nRawControls );
  64. pStatusFrame->AddOperation( pControlName, bPartialMatch ? "Partial rule match" : "Successful" );
  65. // Found a match! Let's create the control and potentially raw control
  66. bool bIsStereo = pSrcComboOp->IsStereoControl( i );
  67. bool bIsEyelid = pSrcComboOp->IsEyelidControl( i );
  68. ControlIndex_t index = pDestComboOp->FindOrCreateControl( pControlName, bIsStereo );
  69. pDestComboOp->SetEyelidControl( index, bIsEyelid );
  70. for ( int j = 0; j < nRawControls; ++j )
  71. {
  72. if ( pFoundMatch[j] )
  73. {
  74. const char *pRawControl = pSrcComboOp->GetRawControlName( i, j );
  75. float flWrinkleScale = pSrcComboOp->GetRawControlWrinkleScale( i, j );
  76. pDestComboOp->AddRawControl( index, pRawControl );
  77. pDestComboOp->SetWrinkleScale( index, pRawControl, flWrinkleScale );
  78. }
  79. }
  80. }
  81. }
  82. //-----------------------------------------------------------------------------
  83. // Import dominance rules from this operator
  84. //-----------------------------------------------------------------------------
  85. static void ImportDominationRules( CDmeCombinationOperator *pDestComboOp, CDmeCombinationOperator *pSrcComboOp, COperationFileListFrame *pStatusFrame )
  86. {
  87. pDestComboOp->RemoveAllDominationRules();
  88. // Now deal with dominance rules
  89. int nRuleCount = pSrcComboOp->DominationRuleCount();
  90. for ( int i = 0; i < nRuleCount; ++i )
  91. {
  92. bool bMismatch = false;
  93. // Only add dominance rule if *all* raw controls are present
  94. CDmeCombinationDominationRule *pSrcRule = pSrcComboOp->GetDominationRule( i );
  95. int nDominatorCount = pSrcRule->DominatorCount();
  96. for ( int j = 0; j < nDominatorCount; ++j )
  97. {
  98. const char *pDominatorName = pSrcRule->GetDominator( j );
  99. if ( !pDestComboOp->HasRawControl( pDominatorName ) )
  100. {
  101. bMismatch = true;
  102. pStatusFrame->AddOperation( pDominatorName, "Missing raw control for dominance rule" );
  103. break;
  104. }
  105. }
  106. int nSuppressedCount = pSrcRule->SuppressedCount();
  107. for ( int j = 0; j < nSuppressedCount; ++j )
  108. {
  109. const char *pSuppressedName = pSrcRule->GetSuppressed( j );
  110. if ( !pDestComboOp->HasRawControl( pSuppressedName ) )
  111. {
  112. bMismatch = true;
  113. pStatusFrame->AddOperation( pSuppressedName, "Missing raw control for dominance rule" );
  114. break;
  115. }
  116. }
  117. if ( bMismatch )
  118. continue;
  119. pDestComboOp->AddDominationRule( pSrcRule );
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Called when the file open dialog for browsing source files selects something
  124. //-----------------------------------------------------------------------------
  125. static bool ImportCombinationData( vgui::Panel* pParent, CDmeCombinationOperator *pDestComboOp, KeyValues *kv )
  126. {
  127. const char *pFileName = kv->GetString( "fullpath", NULL );
  128. if ( !pFileName )
  129. return false;
  130. CDmElement *pRoot;
  131. {
  132. CDisableUndoScopeGuard sg;
  133. g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pRoot, CR_FORCE_COPY );
  134. }
  135. if ( !pRoot )
  136. return false;
  137. // Try to find a combination system in the file
  138. CDmeCombinationOperator *pComboOp = CastElement<CDmeCombinationOperator>( pRoot );
  139. if ( !pComboOp )
  140. {
  141. pComboOp = pRoot->GetValueElement< CDmeCombinationOperator >( "combinationOperator" );
  142. }
  143. if ( pComboOp )
  144. {
  145. // Actually rename the files, build an error dialog if necessary
  146. COperationFileListFrame *pStatusFrame = new COperationFileListFrame( pParent,
  147. "Import Status", "Status", false, true );
  148. pStatusFrame->SetOperationColumnHeaderText( "Control Name" );
  149. CUndoScopeGuard sg( "Import Combination Rules" );
  150. if ( kv->FindKey( "ImportControls" ) )
  151. {
  152. ImportCombinationControls( pDestComboOp, pComboOp, pStatusFrame );
  153. }
  154. ImportDominationRules( pDestComboOp, pComboOp, pStatusFrame );
  155. sg.Release();
  156. pStatusFrame->DoModal();
  157. }
  158. CDisableUndoScopeGuard sg;
  159. g_pDataModel->UnloadFile( pRoot->GetFileId() );
  160. sg.Release();
  161. return true;
  162. }
  163. //-----------------------------------------------------------------------------
  164. //
  165. //
  166. // CDmeInputControlListPanel
  167. //
  168. // Implementation below because of scoping issues
  169. //
  170. //
  171. //-----------------------------------------------------------------------------
  172. class CDmeInputControlListPanel : public vgui::ListPanel
  173. {
  174. DECLARE_CLASS_SIMPLE( CDmeInputControlListPanel, vgui::ListPanel );
  175. public:
  176. // constructor, destructor
  177. CDmeInputControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel );
  178. virtual void OnCreateDragData( KeyValues *msg );
  179. virtual bool IsDroppable( CUtlVector< KeyValues * >& msgList );
  180. virtual void OnPanelDropped( CUtlVector< KeyValues * >& msgList );
  181. virtual void OnKeyCodeTyped( vgui::KeyCode code );
  182. private:
  183. CDmeCombinationControlsPanel *m_pComboPanel;
  184. };
  185. //-----------------------------------------------------------------------------
  186. //
  187. //
  188. // CDmeRawControlListPanel
  189. //
  190. // Implementation below because of scoping issues
  191. //
  192. //
  193. //-----------------------------------------------------------------------------
  194. class CDmeRawControlListPanel : public vgui::ListPanel
  195. {
  196. DECLARE_CLASS_SIMPLE( CDmeRawControlListPanel, vgui::ListPanel );
  197. public:
  198. // constructor, destructor
  199. CDmeRawControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel );
  200. virtual void OnKeyCodeTyped( vgui::KeyCode code );
  201. virtual void OnMouseDoublePressed( vgui::MouseCode code );
  202. private:
  203. MESSAGE_FUNC( OnNewWrinkleText, "TextNewLine" );
  204. CDmeCombinationControlsPanel *m_pComboPanel;
  205. vgui::TextEntry *m_pWrinkleEdit;
  206. bool m_bIsWrinkle;
  207. };
  208. //-----------------------------------------------------------------------------
  209. //
  210. //
  211. // Slider panel
  212. //
  213. //
  214. //-----------------------------------------------------------------------------
  215. class CDmeCombinationControlsPanel : public vgui::EditablePanel
  216. {
  217. DECLARE_CLASS_SIMPLE( CDmeCombinationControlsPanel, vgui::EditablePanel );
  218. public:
  219. // constructor, destructor
  220. CDmeCombinationControlsPanel( vgui::Panel *pParent, const char *pName );
  221. virtual ~CDmeCombinationControlsPanel();
  222. void SetCombinationOperator( CDmeCombinationOperator *pOp );
  223. CDmeCombinationOperator* GetCombinationOperator();
  224. void RefreshCombinationOperator();
  225. void NotifyDataChanged();
  226. const char *GetSelectedControlName();
  227. void MoveControlInFrontOf( const char *pDragControl, const char *pDropControl );
  228. void SetRawControlWrinkleValue( float flWrinkleValue );
  229. int GetSelectedInputControlItemId();
  230. void SelectedInputControlByItemId( int );
  231. MESSAGE_FUNC( OnMoveUpInputControl, "MoveUpInputControl" );
  232. MESSAGE_FUNC( OnMoveDownInputControl, "MoveDownInputControl" );
  233. MESSAGE_FUNC( OnMoveUp, "MoveUp" );
  234. MESSAGE_FUNC( OnMoveDown, "MoveDown" );
  235. private:
  236. MESSAGE_FUNC_PARAMS( OnOpenContextMenu, "OpenContextMenu", kv );
  237. MESSAGE_FUNC_PARAMS( OnInputCompleted, "InputCompleted", kv );
  238. MESSAGE_FUNC( OnGroupControls, "GroupControls" );
  239. MESSAGE_FUNC( OnUngroupControls, "UngroupControls" );
  240. MESSAGE_FUNC( OnRenameControl, "RenameControl" );
  241. MESSAGE_FUNC( OnImportCombination, "ImportCombination" );
  242. MESSAGE_FUNC_PARAMS( OnFileSelected, "FileSelected", kv );
  243. MESSAGE_FUNC( OnToggleStereoControl, "ToggleStereoControl" );
  244. MESSAGE_FUNC( OnToggleEyelidControl, "ToggleEyelidControl" );
  245. MESSAGE_FUNC( OnToggleWrinkleType, "ToggleWrinkleType" );
  246. MESSAGE_FUNC_PARAMS( OnItemSelected, "ItemSelected", kv );
  247. MESSAGE_FUNC_PARAMS( OnItemDeselected, "ItemDeselected", kv );
  248. // Cleans up the context menu
  249. void CleanupContextMenu();
  250. // Builds a list of selected control + raw control names, returns true if any control is stereo
  251. void BuildSelectedControlLists( bool bOnlyGroupedControls, CUtlVector< CUtlString >& controlNames, CUtlVector< CUtlString >& rawControlNames, bool *pbStereo = NULL, bool *pbEyelid = NULL );
  252. // If it finds a duplicate control name, reports an error message and returns it found one
  253. bool HasDuplicateControlName( const char *pControlName, CUtlVector< CUtlString >& retiredControlNames );
  254. // Refreshes the list of raw controls
  255. void RefreshRawControlNames();
  256. // Called by OnGroupControls and OnRenameControl after we get a new group name
  257. void PerformGroupControls( const char *pGroupedControlName );
  258. // Called by OnGroupControls after we get a new group name
  259. void PerformRenameControl( const char *pNewControlName );
  260. // Called to open a context-sensitive menu for a particular menu item
  261. void OnOpenRawControlsContextMenu( );
  262. // Called to open a context-sensitive menu for a particular menu item
  263. const char* GetSelectedRawControl( ControlIndex_t &nControlIndex );
  264. CDmeHandle< CDmeCombinationOperator > m_hCombinationOperator;
  265. vgui::Splitter *m_pSplitter;
  266. CDmeInputControlListPanel *m_pControlList;
  267. CDmeRawControlListPanel *m_pRawControlList;
  268. vgui::DHANDLE< vgui::Menu > m_hContextMenu;
  269. };
  270. //-----------------------------------------------------------------------------
  271. // Sort functions for list panel
  272. //-----------------------------------------------------------------------------
  273. static int __cdecl ControlNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
  274. {
  275. const char *string1 = item1.kv->GetString("name");
  276. const char *string2 = item2.kv->GetString("name");
  277. return Q_stricmp( string1, string2 );
  278. }
  279. static int __cdecl PeakSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
  280. {
  281. float flPeak1 = item1.kv->GetFloat("peak");
  282. float flPeak2 = item2.kv->GetFloat("peak");
  283. if ( flPeak1 < flPeak2 )
  284. return -1;
  285. if ( flPeak1 > flPeak2 )
  286. return 1;
  287. return 0;
  288. }
  289. //-----------------------------------------------------------------------------
  290. // constructor, destructor
  291. //-----------------------------------------------------------------------------
  292. CDmeCombinationControlsPanel::CDmeCombinationControlsPanel( vgui::Panel *pParent, const char *pName ) :
  293. BaseClass( pParent, pName )
  294. {
  295. m_pSplitter = new vgui::Splitter( this, "ControlsSplitter", vgui::SPLITTER_MODE_VERTICAL, 1 );
  296. vgui::Panel *pSplitterLeftSide = m_pSplitter->GetChild( 0 );
  297. vgui::Panel *pSplitterRightSide = m_pSplitter->GetChild( 1 );
  298. m_pControlList = new CDmeInputControlListPanel( pSplitterLeftSide, "ControlList", this );
  299. m_pControlList->AddColumnHeader( 0, "name", "Control Name", 150, 0 );
  300. m_pControlList->AddColumnHeader( 1, "stereo", "Stereo", 70, 0 );
  301. m_pControlList->AddColumnHeader( 2, "eyelid", "Eyelid", 70, 0 );
  302. m_pControlList->AddColumnHeader( 3, "default", "Default", 52, 0 );
  303. m_pControlList->SetSelectIndividualCells( false );
  304. m_pControlList->SetMultiselectEnabled( true );
  305. m_pControlList->SetEmptyListText( "No controls" );
  306. m_pControlList->AddActionSignalTarget( this );
  307. m_pControlList->SetSortFunc( 0, NULL );
  308. m_pControlList->SetColumnSortable( 0, false );
  309. m_pControlList->SetSortFunc( 1, NULL );
  310. m_pControlList->SetColumnSortable( 1, false );
  311. m_pControlList->SetSortFunc( 2, NULL );
  312. m_pControlList->SetColumnSortable( 2, false );
  313. m_pControlList->SetSortFunc( 3, NULL );
  314. m_pControlList->SetColumnSortable( 3, false );
  315. m_pControlList->SetDragEnabled( true );
  316. m_pControlList->SetDragEnabled( true );
  317. m_pControlList->SetDropEnabled( true );
  318. m_pRawControlList = new CDmeRawControlListPanel( pSplitterRightSide, "RawControlList", this );
  319. m_pRawControlList->AddColumnHeader( 0, "name", "Raw Control Name", 150, 0 );
  320. m_pRawControlList->AddColumnHeader( 1, "peak", "Peak", 52, 0 );
  321. m_pRawControlList->AddColumnHeader( 2, "wrinkletype", "Wrinkle Type", 100, 0 );
  322. m_pRawControlList->AddColumnHeader( 3, "wrinkle", "Wrinkle Amount", 100, 0 );
  323. m_pRawControlList->SetSelectIndividualCells( false );
  324. m_pRawControlList->SetEmptyListText( "No raw controls" );
  325. m_pRawControlList->AddActionSignalTarget( this );
  326. m_pRawControlList->SetSortFunc( 0, ControlNameSortFunc );
  327. m_pRawControlList->SetSortFunc( 1, PeakSortFunc );
  328. m_pRawControlList->SetSortFunc( 2, NULL );
  329. m_pRawControlList->SetColumnSortable( 2, false );
  330. m_pRawControlList->SetSortFunc( 3, NULL );
  331. m_pRawControlList->SetColumnSortable( 3, false );
  332. m_pRawControlList->SetSortColumn( 1 );
  333. }
  334. CDmeCombinationControlsPanel::~CDmeCombinationControlsPanel()
  335. {
  336. CleanupContextMenu();
  337. SaveUserConfig();
  338. }
  339. //-----------------------------------------------------------------------------
  340. // Cleans up the context menu
  341. //-----------------------------------------------------------------------------
  342. void CDmeCombinationControlsPanel::CleanupContextMenu()
  343. {
  344. if ( m_hContextMenu.Get() )
  345. {
  346. m_hContextMenu->MarkForDeletion();
  347. m_hContextMenu = NULL;
  348. }
  349. }
  350. //-----------------------------------------------------------------------------
  351. // Sets the combination operator
  352. //-----------------------------------------------------------------------------
  353. void CDmeCombinationControlsPanel::SetCombinationOperator( CDmeCombinationOperator *pOp )
  354. {
  355. if ( pOp != m_hCombinationOperator.Get() )
  356. {
  357. m_hCombinationOperator = pOp;
  358. RefreshCombinationOperator();
  359. }
  360. }
  361. CDmeCombinationOperator* CDmeCombinationControlsPanel::GetCombinationOperator()
  362. {
  363. return m_hCombinationOperator;
  364. }
  365. //-----------------------------------------------------------------------------
  366. // Builds the control list for the combination operator
  367. //-----------------------------------------------------------------------------
  368. void CDmeCombinationControlsPanel::RefreshCombinationOperator()
  369. {
  370. const CUtlString controlName = GetSelectedControlName();
  371. m_pControlList->RemoveAll();
  372. if ( !m_hCombinationOperator.Get() )
  373. return;
  374. int nCount = m_hCombinationOperator->GetControlCount();
  375. for ( int i = 0; i < nCount; ++i )
  376. {
  377. bool bIsMultiControl = m_hCombinationOperator->GetRawControlCount(i) > 1;
  378. float flDefault = m_hCombinationOperator->GetRawControlCount(i) == 2 ? 0.5f : 0.0f;
  379. const char *pName = m_hCombinationOperator->GetControlName( i );
  380. KeyValues *kv = new KeyValues( "node", "name", pName );
  381. kv->SetString( "stereo", m_hCombinationOperator->IsStereoControl(i) ? "On" : "Off" );
  382. kv->SetString( "eyelid", m_hCombinationOperator->IsEyelidControl(i) ? "On" : "Off" );
  383. kv->SetFloat( "default", flDefault );
  384. kv->SetColor( "cellcolor", bIsMultiControl ? Color( 192, 192, 0, 255 ) : Color( 255, 255, 255, 255 ) );
  385. const int nItemId = m_pControlList->AddItem( kv, 0, false, false );
  386. if ( !Q_strcmp( controlName.Get(), pName ) )
  387. {
  388. m_pControlList->SetSingleSelectedItem( nItemId );
  389. }
  390. }
  391. RefreshRawControlNames();
  392. }
  393. //-----------------------------------------------------------------------------
  394. // Tells any class that cares that the data in this thing has changed
  395. //-----------------------------------------------------------------------------
  396. void CDmeCombinationControlsPanel::NotifyDataChanged()
  397. {
  398. PostActionSignal( new KeyValues( "DmeElementChanged", "DmeCombinationControlsPanel", 1 ) );
  399. }
  400. //-----------------------------------------------------------------------------
  401. // Refreshes the list of raw controls
  402. //-----------------------------------------------------------------------------
  403. void CDmeCombinationControlsPanel::RefreshRawControlNames()
  404. {
  405. m_pRawControlList->RemoveAll();
  406. if ( !m_hCombinationOperator.Get() )
  407. return;
  408. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  409. if ( nSelectedItemCount != 1 )
  410. return;
  411. int nItemID = m_pControlList->GetSelectedItem( 0 );
  412. KeyValues *pKeyValues = m_pControlList->GetItem( nItemID );
  413. const char *pControlName = pKeyValues->GetString( "name" );
  414. ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName );
  415. if ( nControlIndex < 0 )
  416. return;
  417. int nCount = m_hCombinationOperator->GetRawControlCount( nControlIndex );
  418. for ( int i = 0; i < nCount; ++i )
  419. {
  420. KeyValues *kv = new KeyValues( "node", "name", m_hCombinationOperator->GetRawControlName( nControlIndex, i ) );
  421. switch( nCount )
  422. {
  423. case 0:
  424. case 1:
  425. kv->SetFloat( "peak", 1.0f );
  426. break;
  427. case 2:
  428. kv->SetFloat( "peak", i == 0 ? 0.0f : 1.0f );
  429. break;
  430. default:
  431. kv->SetFloat( "peak", (float)i / (nCount - 1) );
  432. break;
  433. }
  434. float flWrinkleScale = m_hCombinationOperator->GetRawControlWrinkleScale( nControlIndex, i );
  435. kv->SetString( "wrinkletype", ( flWrinkleScale < 0.0f ) ? "Compress" : "Stretch" );
  436. kv->SetFloat( "wrinkle", fabs( flWrinkleScale ) );
  437. m_pRawControlList->AddItem( kv, 0, false, false );
  438. }
  439. m_pRawControlList->SortList();
  440. }
  441. //-----------------------------------------------------------------------------
  442. // Called to open a context-sensitive menu for a particular menu item
  443. //-----------------------------------------------------------------------------
  444. const char* CDmeCombinationControlsPanel::GetSelectedRawControl( ControlIndex_t &nControlIndex )
  445. {
  446. if ( !m_hCombinationOperator.Get() )
  447. return NULL;
  448. nControlIndex = -1;
  449. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  450. if ( nSelectedItemCount != 1 )
  451. return NULL;
  452. int nSelectedRawItemCount = m_pRawControlList->GetSelectedItemsCount();
  453. if ( nSelectedRawItemCount != 1 )
  454. return NULL;
  455. int nItemID = m_pControlList->GetSelectedItem( 0 );
  456. KeyValues *pKeyValues = m_pControlList->GetItem( nItemID );
  457. const char *pControlName = pKeyValues->GetString( "name" );
  458. nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName );
  459. nItemID = m_pRawControlList->GetSelectedItem( 0 );
  460. pKeyValues = m_pRawControlList->GetItem( nItemID );
  461. return pKeyValues->GetString( "name" );
  462. }
  463. //-----------------------------------------------------------------------------
  464. // Called to open a context-sensitive menu for a particular menu item
  465. //-----------------------------------------------------------------------------
  466. const char *CDmeCombinationControlsPanel::GetSelectedControlName()
  467. {
  468. if ( !m_hCombinationOperator.Get() )
  469. return NULL;
  470. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  471. if ( nSelectedItemCount != 1 )
  472. return NULL;
  473. const int nItemId = m_pControlList->GetSelectedItem( 0 );
  474. if ( !m_pControlList->IsValidItemID( nItemId ) )
  475. return NULL;
  476. KeyValues *pKeyValues = m_pControlList->GetItem( nItemId );
  477. if ( !pKeyValues )
  478. return NULL;
  479. return pKeyValues->GetString( "name" );
  480. }
  481. //-----------------------------------------------------------------------------
  482. //
  483. //-----------------------------------------------------------------------------
  484. int CDmeCombinationControlsPanel::GetSelectedInputControlItemId()
  485. {
  486. return m_pControlList->GetSelectedItem( 0 );
  487. }
  488. //-----------------------------------------------------------------------------
  489. //
  490. //-----------------------------------------------------------------------------
  491. void CDmeCombinationControlsPanel::SelectedInputControlByItemId( int nItemId )
  492. {
  493. m_pControlList->SetSingleSelectedItem( nItemId );
  494. }
  495. //-----------------------------------------------------------------------------
  496. // Called to open a context-sensitive menu for a particular menu item
  497. //-----------------------------------------------------------------------------
  498. void CDmeCombinationControlsPanel::OnMoveUp()
  499. {
  500. ControlIndex_t nControlIndex;
  501. const char *pRawControlName = GetSelectedRawControl( nControlIndex );
  502. if ( !pRawControlName )
  503. return;
  504. m_hCombinationOperator->MoveRawControlUp( nControlIndex, pRawControlName );
  505. RefreshRawControlNames();
  506. }
  507. //-----------------------------------------------------------------------------
  508. // Called to open a context-sensitive menu for a particular menu item
  509. //-----------------------------------------------------------------------------
  510. void CDmeCombinationControlsPanel::OnMoveDown()
  511. {
  512. ControlIndex_t nControlIndex;
  513. const char *pRawControlName = GetSelectedRawControl( nControlIndex );
  514. if ( !pRawControlName )
  515. return;
  516. m_hCombinationOperator->MoveRawControlDown( nControlIndex, pRawControlName );
  517. RefreshRawControlNames();
  518. NotifyDataChanged();
  519. }
  520. //-----------------------------------------------------------------------------
  521. // Called to open a context-sensitive menu for a particular menu item
  522. //-----------------------------------------------------------------------------
  523. void CDmeCombinationControlsPanel::OnMoveUpInputControl()
  524. {
  525. const char *pControlName = GetSelectedControlName();
  526. if ( !pControlName )
  527. return;
  528. m_hCombinationOperator->MoveControlUp( pControlName );
  529. NotifyDataChanged();
  530. }
  531. //-----------------------------------------------------------------------------
  532. // Called to open a context-sensitive menu for a particular menu item
  533. //-----------------------------------------------------------------------------
  534. void CDmeCombinationControlsPanel::OnMoveDownInputControl()
  535. {
  536. const char *pControlName = GetSelectedControlName();
  537. if ( !pControlName )
  538. return;
  539. m_hCombinationOperator->MoveControlDown( pControlName );
  540. NotifyDataChanged();
  541. }
  542. //-----------------------------------------------------------------------------
  543. // Called to open a context-sensitive menu for a particular menu item
  544. //-----------------------------------------------------------------------------
  545. void CDmeCombinationControlsPanel::MoveControlInFrontOf(
  546. const char *pDragControl,
  547. const char *pDropControl )
  548. {
  549. m_hCombinationOperator->MoveControlBefore( pDragControl, pDropControl );
  550. RefreshCombinationOperator();
  551. NotifyDataChanged();
  552. }
  553. //-----------------------------------------------------------------------------
  554. // Toggles the wrinkle type
  555. //-----------------------------------------------------------------------------
  556. void CDmeCombinationControlsPanel::OnToggleWrinkleType()
  557. {
  558. ControlIndex_t nControlIndex;
  559. const char *pRawControlName = GetSelectedRawControl( nControlIndex );
  560. if ( !pRawControlName )
  561. return;
  562. float flWrinkleScale = m_hCombinationOperator->GetRawControlWrinkleScale( nControlIndex, pRawControlName );
  563. m_hCombinationOperator->SetWrinkleScale( nControlIndex, pRawControlName, -flWrinkleScale );
  564. RefreshRawControlNames();
  565. m_hCombinationOperator->GenerateWrinkleDeltas();
  566. }
  567. void CDmeCombinationControlsPanel::SetRawControlWrinkleValue( float flWrinkleValue )
  568. {
  569. ControlIndex_t nControlIndex;
  570. const char *pRawControlName = GetSelectedRawControl( nControlIndex );
  571. if ( !pRawControlName )
  572. return;
  573. m_hCombinationOperator->SetWrinkleScale( nControlIndex, pRawControlName, flWrinkleValue );
  574. RefreshRawControlNames();
  575. m_hCombinationOperator->GenerateWrinkleDeltas();
  576. }
  577. //-----------------------------------------------------------------------------
  578. // Called to open a context-sensitive menu for a particular menu item
  579. //-----------------------------------------------------------------------------
  580. void CDmeCombinationControlsPanel::OnOpenRawControlsContextMenu( )
  581. {
  582. if ( !m_hCombinationOperator.Get() )
  583. return;
  584. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  585. if ( nSelectedItemCount != 1 )
  586. return;
  587. int nSelectedRawItemCount = m_pRawControlList->GetSelectedItemsCount();
  588. if ( nSelectedRawItemCount != 1 )
  589. return;
  590. m_hContextMenu = new vgui::Menu( this, "ActionMenu" );
  591. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveUp", new KeyValues( "MoveUp" ), this );
  592. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveDown", new KeyValues( "MoveDown" ), this );
  593. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_ToggleWrinkleType", new KeyValues( "ToggleWrinkleType" ), this );
  594. vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
  595. }
  596. //-----------------------------------------------------------------------------
  597. // Called to open a context-sensitive menu for a particular menu item
  598. //-----------------------------------------------------------------------------
  599. void CDmeCombinationControlsPanel::OnOpenContextMenu( KeyValues *kv )
  600. {
  601. CleanupContextMenu();
  602. if ( !m_hCombinationOperator.Get() )
  603. return;
  604. Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
  605. if ( pPanel == m_pRawControlList )
  606. {
  607. OnOpenRawControlsContextMenu();
  608. return;
  609. }
  610. if ( pPanel != m_pControlList )
  611. return;
  612. bool bGroupedControls = false;
  613. bool bStereoControls = false;
  614. bool bEyelidControls = false;
  615. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  616. for ( int i = 0; i < nSelectedItemCount; ++i )
  617. {
  618. int nItemID = m_pControlList->GetSelectedItem( i );
  619. KeyValues *pKeyValues = m_pControlList->GetItem( nItemID );
  620. const char *pControlName = pKeyValues->GetString( "name" );
  621. ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName );
  622. if ( nControlIndex < 0 )
  623. continue;
  624. if ( m_hCombinationOperator->GetRawControlCount( nControlIndex ) > 1 )
  625. {
  626. bGroupedControls = true;
  627. }
  628. if ( m_hCombinationOperator->IsStereoControl( nControlIndex ) )
  629. {
  630. bStereoControls = true;
  631. }
  632. if ( m_hCombinationOperator->IsEyelidControl( nControlIndex ) )
  633. {
  634. bEyelidControls = true;
  635. }
  636. }
  637. m_hContextMenu = new vgui::Menu( this, "ActionMenu" );
  638. if ( nSelectedItemCount > 1 )
  639. {
  640. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_GroupControls", new KeyValues( "GroupControls" ), this );
  641. }
  642. if ( bGroupedControls )
  643. {
  644. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_UngroupControls", new KeyValues( "UngroupControls" ), this );
  645. }
  646. if ( nSelectedItemCount >= 1 )
  647. {
  648. int nMenuItemID = m_hContextMenu->AddCheckableMenuItem( "#DmeCombinationSystemEditor_StereoControl", new KeyValues( "ToggleStereoControl" ), this );
  649. m_hContextMenu->SetMenuItemChecked( nMenuItemID, bStereoControls );
  650. }
  651. if ( nSelectedItemCount >= 1 )
  652. {
  653. int nMenuItemID = m_hContextMenu->AddCheckableMenuItem( "#DmeCombinationSystemEditor_EyelidControl", new KeyValues( "ToggleEyelidControl" ), this );
  654. m_hContextMenu->SetMenuItemChecked( nMenuItemID, bEyelidControls );
  655. }
  656. if ( nSelectedItemCount == 1 )
  657. {
  658. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_RenameControl", new KeyValues( "RenameControl" ), this );
  659. }
  660. if ( nSelectedItemCount >= 1 )
  661. {
  662. m_hContextMenu->AddSeparator();
  663. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveUp", new KeyValues( "MoveUpInputControl" ), this );
  664. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveDown", new KeyValues( "MoveDownInputControl" ), this );
  665. }
  666. if ( nSelectedItemCount >= 1 || bGroupedControls )
  667. {
  668. m_hContextMenu->AddSeparator();
  669. }
  670. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_Import", new KeyValues( "ImportCombination" ), this );
  671. vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
  672. }
  673. //-----------------------------------------------------------------------------
  674. // Called when a list panel's selection changes
  675. //-----------------------------------------------------------------------------
  676. void CDmeCombinationControlsPanel::OnItemSelected( KeyValues *kv )
  677. {
  678. Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
  679. if ( pPanel == m_pControlList )
  680. {
  681. RefreshRawControlNames();
  682. return;
  683. }
  684. }
  685. //-----------------------------------------------------------------------------
  686. // Called when a list panel's selection changes
  687. //-----------------------------------------------------------------------------
  688. void CDmeCombinationControlsPanel::OnItemDeselected( KeyValues *kv )
  689. {
  690. Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
  691. if ( pPanel == m_pControlList )
  692. {
  693. RefreshRawControlNames();
  694. return;
  695. }
  696. }
  697. //-----------------------------------------------------------------------------
  698. // Builds a list of selected control + raw control names, returns true if any control is stereo
  699. //-----------------------------------------------------------------------------
  700. void CDmeCombinationControlsPanel::BuildSelectedControlLists(
  701. bool bOnlyGroupedControls,
  702. CUtlVector< CUtlString >& controlNames, CUtlVector< CUtlString >& rawControlNames,
  703. bool *pbStereo, bool *pbEyelid )
  704. {
  705. bool bIsStereo = false;
  706. bool bIsEyelid = false;
  707. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  708. for ( int i = 0; i < nSelectedItemCount; ++i )
  709. {
  710. int nItemID = m_pControlList->GetSelectedItem( i );
  711. KeyValues *pKeyValues = m_pControlList->GetItem( nItemID );
  712. const char *pControlName = pKeyValues->GetString( "name" );
  713. ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName );
  714. if ( nControlIndex < 0 )
  715. continue;
  716. int nRawControlCount = m_hCombinationOperator->GetRawControlCount( nControlIndex );
  717. if ( bOnlyGroupedControls && ( nRawControlCount <= 1 ) )
  718. continue;
  719. if ( m_hCombinationOperator->IsStereoControl( nControlIndex ) )
  720. {
  721. bIsStereo = true;
  722. }
  723. if ( m_hCombinationOperator->IsEyelidControl( nControlIndex ) )
  724. {
  725. bIsEyelid = true;
  726. }
  727. controlNames.AddToTail( pControlName );
  728. for ( int j = 0; j < nRawControlCount; ++j )
  729. {
  730. rawControlNames.AddToTail( m_hCombinationOperator->GetRawControlName( nControlIndex, j ) );
  731. }
  732. }
  733. if ( pbStereo )
  734. {
  735. *pbStereo = bIsStereo;
  736. }
  737. if ( pbEyelid )
  738. {
  739. *pbEyelid = bIsEyelid;
  740. }
  741. }
  742. //-----------------------------------------------------------------------------
  743. // If it finds a duplicate control name, reports an error message and returns it found one
  744. //-----------------------------------------------------------------------------
  745. bool CDmeCombinationControlsPanel::HasDuplicateControlName( const char *pControlName, CUtlVector< CUtlString >& retiredControlNames )
  746. {
  747. int i;
  748. int nRetiredControlNameCount = retiredControlNames.Count();
  749. for ( i = 0; i < nRetiredControlNameCount; ++i )
  750. {
  751. if ( !Q_stricmp( retiredControlNames[i], pControlName ) )
  752. break;
  753. }
  754. if ( i == nRetiredControlNameCount )
  755. {
  756. // no match
  757. if ( m_hCombinationOperator->FindControlIndex( pControlName ) >= 0 )
  758. {
  759. vgui::MessageBox *pError = new vgui::MessageBox( "#DmeCombinationSystemEditor_DuplicateNameTitle", "#DmeCombinationSystemEditor_DuplicateNameText", this );
  760. pError->DoModal();
  761. return true;
  762. }
  763. }
  764. return false;
  765. }
  766. //-----------------------------------------------------------------------------
  767. // Called by OnGroupControls and OnRenameControl after we get a new group name
  768. //-----------------------------------------------------------------------------
  769. void CDmeCombinationControlsPanel::PerformGroupControls( const char *pGroupedControlName )
  770. {
  771. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  772. if ( nSelectedItemCount <= 1 )
  773. return;
  774. // Build lists of selected controls + raw controls
  775. CUtlVector< CUtlString > controlNames;
  776. CUtlVector< CUtlString > rawControlNames;
  777. bool bIsStereo = false;
  778. bool bIsEyelid = false;
  779. BuildSelectedControlLists( false, controlNames, rawControlNames, &bIsStereo, &bIsEyelid );
  780. // NOTE: It's illegal to use a grouped control name which already exists
  781. // assuming it's not in the list of grouped control names we're going to group together
  782. if ( HasDuplicateControlName( pGroupedControlName, controlNames ) )
  783. return;
  784. // Delete old controls
  785. int nRetiredControlNameCount = controlNames.Count();
  786. for ( int i = 0; i < nRetiredControlNameCount; ++i )
  787. {
  788. m_hCombinationOperator->RemoveControl( controlNames[i] );
  789. }
  790. // Create new control
  791. ControlIndex_t nNewControl = m_hCombinationOperator->FindOrCreateControl( pGroupedControlName, bIsStereo );
  792. m_hCombinationOperator->SetEyelidControl( nNewControl, bIsEyelid );
  793. int nGroupedControlCount = rawControlNames.Count();
  794. for ( int i = 0; i < nGroupedControlCount; ++i )
  795. {
  796. m_hCombinationOperator->AddRawControl( nNewControl, rawControlNames[i] );
  797. }
  798. RefreshCombinationOperator();
  799. NotifyDataChanged();
  800. }
  801. //-----------------------------------------------------------------------------
  802. // Called by OnGroupControls after we get a new group name
  803. //-----------------------------------------------------------------------------
  804. void CDmeCombinationControlsPanel::PerformRenameControl( const char *pNewControlName )
  805. {
  806. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  807. if ( nSelectedItemCount != 1 )
  808. return;
  809. int nItemID = m_pControlList->GetSelectedItem( 0 );
  810. KeyValues *pKeyValues = m_pControlList->GetItem( nItemID );
  811. const char *pControlName = pKeyValues->GetString( "name" );
  812. ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( pControlName );
  813. if ( nControlIndex < 0 )
  814. return;
  815. // NOTE: It's illegal to use a grouped control name which already exists
  816. // assuming it's not in the list of grouped control names we're going to group together
  817. ControlIndex_t nFoundIndex = m_hCombinationOperator->FindControlIndex( pNewControlName );
  818. if ( nFoundIndex >= 0 && nFoundIndex != nControlIndex )
  819. return;
  820. m_hCombinationOperator->SetControlName( nControlIndex, pNewControlName );
  821. RefreshCombinationOperator();
  822. NotifyDataChanged();
  823. }
  824. //-----------------------------------------------------------------------------
  825. // Called by OnGroupControls after we get a new group name
  826. //-----------------------------------------------------------------------------
  827. void CDmeCombinationControlsPanel::OnInputCompleted( KeyValues *pKeyValues )
  828. {
  829. const char *pControlName = pKeyValues->GetString( "text", NULL );
  830. if ( !pControlName || !pControlName[0] )
  831. return;
  832. if ( pKeyValues->FindKey( "OnGroupControls" ) )
  833. {
  834. PerformGroupControls( pControlName );
  835. return;
  836. }
  837. if ( pKeyValues->FindKey( "OnRenameControl" ) )
  838. {
  839. PerformRenameControl( pControlName );
  840. return;
  841. }
  842. }
  843. //-----------------------------------------------------------------------------
  844. // Group controls together
  845. //-----------------------------------------------------------------------------
  846. void CDmeCombinationControlsPanel::OnGroupControls( )
  847. {
  848. vgui::InputDialog *pInput = new vgui::InputDialog( this, "Group Controls", "Enter name of grouped control" );
  849. pInput->SetMultiline( false );
  850. pInput->DoModal( new KeyValues( "OnGroupControls" ) );
  851. }
  852. //-----------------------------------------------------------------------------
  853. // Ungroup controls from each other
  854. //-----------------------------------------------------------------------------
  855. void CDmeCombinationControlsPanel::OnUngroupControls( )
  856. {
  857. // Build lists of selected controls + raw controls
  858. CUtlVector< CUtlString > controlNames;
  859. CUtlVector< CUtlString > rawControlNames;
  860. bool bIsStereo = false;
  861. bool bIsEyelid = false;
  862. BuildSelectedControlLists( true, controlNames, rawControlNames, &bIsStereo, &bIsEyelid );
  863. // NOTE: It's illegal to use a grouped control name which already exists
  864. // assuming it's not in the list of grouped control names we're going to group together
  865. int nRawControlCount = rawControlNames.Count();
  866. for ( int i = 0; i < nRawControlCount; ++i )
  867. {
  868. if ( HasDuplicateControlName( rawControlNames[i], controlNames ) )
  869. return;
  870. }
  871. // Delete old controls
  872. int nRetiredControlNameCount = controlNames.Count();
  873. for ( int i = 0; i < nRetiredControlNameCount; ++i )
  874. {
  875. m_hCombinationOperator->RemoveControl( controlNames[i] );
  876. }
  877. // Create new control (this will also create raw controls with the same name)
  878. int nGroupedControlCount = rawControlNames.Count();
  879. for ( int i = 0; i < nGroupedControlCount; ++i )
  880. {
  881. const int nControlIndex = m_hCombinationOperator->FindOrCreateControl( rawControlNames[i], bIsStereo, true );
  882. m_hCombinationOperator->SetEyelidControl( nControlIndex, bIsEyelid );
  883. }
  884. RefreshCombinationOperator();
  885. NotifyDataChanged();
  886. }
  887. //-----------------------------------------------------------------------------
  888. // Ungroup controls from each other
  889. //-----------------------------------------------------------------------------
  890. void CDmeCombinationControlsPanel::OnToggleStereoControl( )
  891. {
  892. // Build lists of selected controls + raw controls
  893. // Yeah, this isn't super efficient, but this UI is not going to be super-polished
  894. CUtlVector< CUtlString > controlNames;
  895. CUtlVector< CUtlString > rawControlNames;
  896. bool bIsStereo = false;
  897. BuildSelectedControlLists( false, controlNames, rawControlNames, &bIsStereo );
  898. int nControlCount = controlNames.Count();
  899. for ( int i = 0; i < nControlCount; ++i )
  900. {
  901. ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( controlNames[i] );
  902. m_hCombinationOperator->SetStereoControl( nControlIndex, !bIsStereo );
  903. }
  904. RefreshCombinationOperator();
  905. NotifyDataChanged();
  906. }
  907. //-----------------------------------------------------------------------------
  908. // Toggle Eyelid-Ness
  909. //-----------------------------------------------------------------------------
  910. void CDmeCombinationControlsPanel::OnToggleEyelidControl()
  911. {
  912. // Build lists of selected controls + raw controls
  913. // Yeah, this isn't super efficient, but this UI is not going to be super-polished
  914. CUtlVector< CUtlString > controlNames;
  915. CUtlVector< CUtlString > rawControlNames;
  916. bool bIsEyelid = false;
  917. BuildSelectedControlLists( false, controlNames, rawControlNames, NULL, &bIsEyelid );
  918. int nControlCount = controlNames.Count();
  919. for ( int i = 0; i < nControlCount; ++i )
  920. {
  921. ControlIndex_t nControlIndex = m_hCombinationOperator->FindControlIndex( controlNames[i] );
  922. m_hCombinationOperator->SetEyelidControl( nControlIndex, !bIsEyelid );
  923. }
  924. RefreshCombinationOperator();
  925. NotifyDataChanged();
  926. }
  927. //-----------------------------------------------------------------------------
  928. // Rename a control
  929. //-----------------------------------------------------------------------------
  930. void CDmeCombinationControlsPanel::OnRenameControl()
  931. {
  932. int nSelectedItemCount = m_pControlList->GetSelectedItemsCount();
  933. if ( nSelectedItemCount != 1 )
  934. return;
  935. vgui::InputDialog *pInput = new vgui::InputDialog( this, "Rename Control", "Enter new name of control" );
  936. pInput->SetMultiline( false );
  937. pInput->DoModal( new KeyValues( "OnRenameControl" ) );
  938. }
  939. //-----------------------------------------------------------------------------
  940. // Called when the file open dialog for browsing source files selects something
  941. //-----------------------------------------------------------------------------
  942. void CDmeCombinationControlsPanel::OnFileSelected( KeyValues *kv )
  943. {
  944. if ( ImportCombinationData( this, m_hCombinationOperator, kv ) )
  945. {
  946. RefreshCombinationOperator();
  947. NotifyDataChanged();
  948. }
  949. }
  950. //-----------------------------------------------------------------------------
  951. // Import combination controls + domination rules
  952. //-----------------------------------------------------------------------------
  953. void CDmeCombinationControlsPanel::OnImportCombination()
  954. {
  955. char pStartingDir[MAX_PATH];
  956. GetModContentSubdirectory( "models", pStartingDir, sizeof(pStartingDir) );
  957. vgui::FileOpenDialog *pDialog = new vgui::FileOpenDialog( this, "Select File to Import", true, new KeyValues( "ImportControls" ) );
  958. pDialog->SetStartDirectoryContext( "combination_system_import", pStartingDir );
  959. pDialog->AddFilter( "*.dmx", "Exported model file (*.dmx)", true );
  960. pDialog->SetDeleteSelfOnClose( true );
  961. pDialog->AddActionSignalTarget( this );
  962. pDialog->DoModal( false );
  963. }
  964. //-----------------------------------------------------------------------------
  965. //
  966. //
  967. // CDmeInputControlListPanel
  968. //
  969. // Declaration above because of scoping issues
  970. //
  971. //
  972. //-----------------------------------------------------------------------------
  973. //-----------------------------------------------------------------------------
  974. // Constructor, destructor
  975. //-----------------------------------------------------------------------------
  976. CDmeInputControlListPanel::CDmeInputControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel ) :
  977. BaseClass( pParent, pName ), m_pComboPanel( pComboPanel )
  978. {
  979. }
  980. //-----------------------------------------------------------------------------
  981. // Called when a list panel's selection changes
  982. //-----------------------------------------------------------------------------
  983. void CDmeInputControlListPanel::OnCreateDragData( KeyValues *msg )
  984. {
  985. const char *const pControlName = m_pComboPanel->GetSelectedControlName();
  986. if ( pControlName )
  987. {
  988. msg->SetString( "inputControl", pControlName );
  989. msg->SetInt( "selfDroppable", 1 );
  990. }
  991. }
  992. //-----------------------------------------------------------------------------
  993. // Called when a list panel's selection changes
  994. //-----------------------------------------------------------------------------
  995. bool CDmeInputControlListPanel::IsDroppable( CUtlVector< KeyValues * >& msgList )
  996. {
  997. if ( msgList.Count() > 0 )
  998. {
  999. KeyValues *pData( msgList[ 0 ] );
  1000. if ( pData->GetPtr( "panel", NULL ) == this && m_pComboPanel )
  1001. {
  1002. if ( pData->GetString( "inputControl" ) && pData->GetInt( "selfDroppable" ) )
  1003. {
  1004. return true;
  1005. }
  1006. }
  1007. }
  1008. return false;
  1009. }
  1010. //-----------------------------------------------------------------------------
  1011. // Called when a list panel's selection changes
  1012. //-----------------------------------------------------------------------------
  1013. void CDmeInputControlListPanel::OnPanelDropped( CUtlVector< KeyValues * >& msgList )
  1014. {
  1015. if ( msgList.Count() > 0 )
  1016. {
  1017. KeyValues *pData( msgList[ 0 ] );
  1018. if ( pData->GetPtr( "panel", NULL ) == this && m_pComboPanel )
  1019. {
  1020. const char *const pDragControl( pData->GetString( "inputControl" ) );
  1021. if ( pDragControl )
  1022. {
  1023. int x;
  1024. int y;
  1025. vgui::input()->GetCursorPos( x, y );
  1026. int row;
  1027. int column;
  1028. GetCellAtPos( x, y, row, column );
  1029. KeyValues *pKeyValues = GetItem( GetItemIDFromRow( row ) );
  1030. if ( pKeyValues )
  1031. {
  1032. const char *pDropControl = pKeyValues->GetString( "name" );
  1033. if ( pDropControl )
  1034. {
  1035. m_pComboPanel->MoveControlInFrontOf( pDragControl, pDropControl );
  1036. }
  1037. }
  1038. }
  1039. }
  1040. }
  1041. }
  1042. void CDmeInputControlListPanel::OnKeyCodeTyped( vgui::KeyCode code )
  1043. {
  1044. // Not sure how to handle 'edit' mode... the relevant stuff is private
  1045. if ( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) )
  1046. {
  1047. if ( code == KEY_UP )
  1048. {
  1049. const int nItemId = m_pComboPanel->GetSelectedInputControlItemId();
  1050. m_pComboPanel->OnMoveUpInputControl();
  1051. vgui::ListPanel::OnKeyCodeTyped( code );
  1052. m_pComboPanel->SelectedInputControlByItemId( nItemId );
  1053. return;
  1054. }
  1055. else if ( code == KEY_DOWN )
  1056. {
  1057. const int nItemId = m_pComboPanel->GetSelectedInputControlItemId();
  1058. m_pComboPanel->OnMoveDownInputControl();
  1059. vgui::ListPanel::OnKeyCodeTyped( code );
  1060. m_pComboPanel->SelectedInputControlByItemId( nItemId );
  1061. return;
  1062. }
  1063. }
  1064. vgui::ListPanel::OnKeyCodeTyped( code );
  1065. }
  1066. //-----------------------------------------------------------------------------
  1067. //
  1068. //
  1069. // CDmeRawControlListPanel
  1070. //
  1071. // Declaration above because of scoping issues
  1072. //
  1073. //
  1074. //-----------------------------------------------------------------------------
  1075. //-----------------------------------------------------------------------------
  1076. // Constructor, destructor
  1077. //-----------------------------------------------------------------------------
  1078. CDmeRawControlListPanel::CDmeRawControlListPanel( vgui::Panel *pParent, const char *pName, CDmeCombinationControlsPanel *pComboPanel ) :
  1079. BaseClass( pParent, pName ), m_pComboPanel( pComboPanel )
  1080. {
  1081. m_pWrinkleEdit = new vgui::TextEntry( this, "WrinkleEdit" );
  1082. m_pWrinkleEdit->SetVisible( false );
  1083. m_pWrinkleEdit->AddActionSignalTarget( this );
  1084. m_pWrinkleEdit->SetAllowNumericInputOnly( true );
  1085. }
  1086. void CDmeRawControlListPanel::OnKeyCodeTyped( vgui::KeyCode code )
  1087. {
  1088. // Not sure how to handle 'edit' mode... the relevant stuff is private
  1089. if ( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) )
  1090. {
  1091. if ( code == KEY_UP )
  1092. {
  1093. m_pComboPanel->OnMoveUp();
  1094. }
  1095. else if ( code == KEY_DOWN )
  1096. {
  1097. m_pComboPanel->OnMoveDown();
  1098. }
  1099. }
  1100. vgui::ListPanel::OnKeyCodeTyped( code );
  1101. }
  1102. void CDmeRawControlListPanel::OnMouseDoublePressed( vgui::MouseCode code )
  1103. {
  1104. if ( code != MOUSE_LEFT )
  1105. {
  1106. BaseClass::OnMouseDoublePressed( code );
  1107. return;
  1108. }
  1109. int nNumSelected = GetSelectedItemsCount();
  1110. if ( IsInEditMode() || nNumSelected != 1 )
  1111. return;
  1112. m_pWrinkleEdit->SetVisible( true );
  1113. m_pWrinkleEdit->SendNewLine( true );
  1114. // Always edit column 3, which contains the wrinkle amount
  1115. int nEditingItem = GetSelectedItem( 0 );
  1116. KeyValues *pKeyValues = GetItem( nEditingItem );
  1117. float flWrinkleValue = pKeyValues->GetFloat( "wrinkle" );
  1118. m_bIsWrinkle = !Q_stricmp( pKeyValues->GetString( "wrinkletype" ), "Wrinkle" );
  1119. char buf[64];
  1120. Q_snprintf( buf, sizeof(buf), "%f", flWrinkleValue );
  1121. m_pWrinkleEdit->SetText( buf );
  1122. EnterEditMode( nEditingItem, 3, m_pWrinkleEdit );
  1123. }
  1124. void CDmeRawControlListPanel::OnNewWrinkleText()
  1125. {
  1126. LeaveEditMode();
  1127. char szEditText[MAX_PATH];
  1128. m_pWrinkleEdit->GetText( szEditText, MAX_PATH );
  1129. m_pWrinkleEdit->SetVisible( false );
  1130. float flWrinkleScale = atof( szEditText );
  1131. if ( m_bIsWrinkle )
  1132. {
  1133. flWrinkleScale = -flWrinkleScale;
  1134. }
  1135. m_pComboPanel->SetRawControlWrinkleValue( flWrinkleScale );
  1136. }
  1137. //-----------------------------------------------------------------------------
  1138. //
  1139. // Purpose: Multiselect for raw controls
  1140. //
  1141. //-----------------------------------------------------------------------------
  1142. class CRawControlPickerFrame : public vgui::Frame
  1143. {
  1144. DECLARE_CLASS_SIMPLE( CRawControlPickerFrame, vgui::Frame );
  1145. public:
  1146. CRawControlPickerFrame( vgui::Panel *pParent, const char *pTitle );
  1147. ~CRawControlPickerFrame();
  1148. // Sets the current scene + animation list
  1149. void DoModal( CDmeCombinationOperator *pCombinationOperator, CDmeCombinationDominationRule *pRule, bool bSuppressed, KeyValues *pContextKeyValues );
  1150. // Inherited from Frame
  1151. virtual void OnCommand( const char *pCommand );
  1152. private:
  1153. // Refreshes the list of raw controls
  1154. void RefreshRawControlNames( CDmeCombinationOperator *pCombinationOperator, CDmeCombinationDominationRule *pRule, bool bSuppressed );
  1155. void CleanUpMessage();
  1156. vgui::ListPanel *m_pRawControlList;
  1157. vgui::Button *m_pOpenButton;
  1158. vgui::Button *m_pCancelButton;
  1159. KeyValues *m_pContextKeyValues;
  1160. };
  1161. CRawControlPickerFrame::CRawControlPickerFrame( vgui::Panel *pParent, const char *pTitle ) :
  1162. BaseClass( pParent, "RawControlPickerFrame" )
  1163. {
  1164. SetDeleteSelfOnClose( true );
  1165. m_pContextKeyValues = NULL;
  1166. m_pRawControlList = new vgui::ListPanel( this, "RawControlList" );
  1167. m_pRawControlList->AddColumnHeader( 0, "name", "Raw Control Name", 52, 0 );
  1168. m_pRawControlList->SetSelectIndividualCells( false );
  1169. m_pRawControlList->SetEmptyListText( "No raw controls" );
  1170. m_pRawControlList->AddActionSignalTarget( this );
  1171. m_pRawControlList->SetSortFunc( 0, ControlNameSortFunc );
  1172. m_pRawControlList->SetSortColumn( 0 );
  1173. m_pOpenButton = new vgui::Button( this, "OkButton", "#MessageBox_OK", this, "Ok" );
  1174. m_pCancelButton = new vgui::Button( this, "CancelButton", "#MessageBox_Cancel", this, "Cancel" );
  1175. SetBlockDragChaining( true );
  1176. LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditor_rawcontrolpickerframe.res" );
  1177. SetTitle( pTitle, false );
  1178. }
  1179. CRawControlPickerFrame::~CRawControlPickerFrame()
  1180. {
  1181. CleanUpMessage();
  1182. }
  1183. //-----------------------------------------------------------------------------
  1184. // Refreshes the list of raw controls
  1185. //-----------------------------------------------------------------------------
  1186. void CRawControlPickerFrame::RefreshRawControlNames( CDmeCombinationOperator *pCombinationOperator, CDmeCombinationDominationRule *pRule, bool bChooseSuppressed )
  1187. {
  1188. m_pRawControlList->RemoveAll();
  1189. if ( !pCombinationOperator )
  1190. return;
  1191. int nCount = pCombinationOperator->GetRawControlCount( );
  1192. for ( int i = 0; i < nCount; ++i )
  1193. {
  1194. const char *pRawControl = pCombinationOperator->GetRawControlName( i );
  1195. // Hide controls that are in the other part of the rule
  1196. bool bIsDominator = pRule->HasDominatorControl( pRawControl );
  1197. bool bIsSuppressed = pRule->HasSuppressedControl( pRawControl );
  1198. Assert( !bIsDominator || !bIsSuppressed );
  1199. if ( ( bChooseSuppressed && bIsDominator ) || ( !bChooseSuppressed && bIsSuppressed ) )
  1200. continue;
  1201. KeyValues *kv = new KeyValues( "node", "name", pCombinationOperator->GetRawControlName( i ) );
  1202. int nItemID = m_pRawControlList->AddItem( kv, 0, false, false );
  1203. if ( ( bChooseSuppressed && bIsSuppressed ) || ( !bChooseSuppressed && bIsDominator ) )
  1204. {
  1205. m_pRawControlList->AddSelectedItem( nItemID );
  1206. }
  1207. }
  1208. m_pRawControlList->SortList();
  1209. }
  1210. //-----------------------------------------------------------------------------
  1211. // Deletes the message
  1212. //-----------------------------------------------------------------------------
  1213. void CRawControlPickerFrame::CleanUpMessage()
  1214. {
  1215. if ( m_pContextKeyValues )
  1216. {
  1217. m_pContextKeyValues->deleteThis();
  1218. m_pContextKeyValues = NULL;
  1219. }
  1220. }
  1221. //-----------------------------------------------------------------------------
  1222. // Sets the current scene + animation list
  1223. //-----------------------------------------------------------------------------
  1224. void CRawControlPickerFrame::DoModal( CDmeCombinationOperator *pCombinationOperator,
  1225. CDmeCombinationDominationRule *pRule, bool bSuppressed, KeyValues *pContextKeyValues )
  1226. {
  1227. CleanUpMessage();
  1228. RefreshRawControlNames( pCombinationOperator, pRule, bSuppressed );
  1229. m_pContextKeyValues = pContextKeyValues;
  1230. BaseClass::DoModal();
  1231. }
  1232. //-----------------------------------------------------------------------------
  1233. // On command
  1234. //-----------------------------------------------------------------------------
  1235. void CRawControlPickerFrame::OnCommand( const char *pCommand )
  1236. {
  1237. if ( !Q_stricmp( pCommand, "Ok" ) )
  1238. {
  1239. KeyValues *pActionKeys = new KeyValues( "RawControlPicked" );
  1240. KeyValues *pControlList = pActionKeys->FindKey( "rawControls", true );
  1241. int nSelectedItemCount = m_pRawControlList->GetSelectedItemsCount();
  1242. for ( int i = 0; i < nSelectedItemCount; ++i )
  1243. {
  1244. int nItemID = m_pRawControlList->GetSelectedItem( i );
  1245. KeyValues *pKeyValues = m_pRawControlList->GetItem( nItemID );
  1246. const char *pControlName = pKeyValues->GetString( "name" );
  1247. pControlList->SetString( pControlName, pControlName );
  1248. }
  1249. if ( m_pContextKeyValues )
  1250. {
  1251. pActionKeys->AddSubKey( m_pContextKeyValues );
  1252. // This prevents them from being deleted later
  1253. m_pContextKeyValues = NULL;
  1254. }
  1255. PostActionSignal( pActionKeys );
  1256. CloseModal();
  1257. return;
  1258. }
  1259. if ( !Q_stricmp( pCommand, "Cancel" ) )
  1260. {
  1261. CloseModal();
  1262. return;
  1263. }
  1264. BaseClass::OnCommand( pCommand );
  1265. }
  1266. //-----------------------------------------------------------------------------
  1267. // Domination rules panel
  1268. //-----------------------------------------------------------------------------
  1269. class CDmeCombinationDominationRulesPanel : public vgui::EditablePanel
  1270. {
  1271. DECLARE_CLASS_SIMPLE( CDmeCombinationDominationRulesPanel, vgui::EditablePanel );
  1272. public:
  1273. // constructor, destructor
  1274. CDmeCombinationDominationRulesPanel( vgui::Panel *pParent, const char *pName );
  1275. virtual ~CDmeCombinationDominationRulesPanel();
  1276. void SetCombinationOperator( CDmeCombinationOperator *pOp );
  1277. void RefreshCombinationOperator();
  1278. void NotifyDataChanged();
  1279. private:
  1280. MESSAGE_FUNC_PARAMS( OnOpenContextMenu, "OpenContextMenu", kv );
  1281. MESSAGE_FUNC_PARAMS( OnRawControlPicked, "RawControlPicked", kv );
  1282. MESSAGE_FUNC( OnAddDominationRule, "AddDominationRule" );
  1283. MESSAGE_FUNC( OnRemoveDominationRule, "RemoveDominationRule" );
  1284. MESSAGE_FUNC( OnDuplicateSuppressed, "DuplicateSuppressed" );
  1285. MESSAGE_FUNC( OnDuplicateDominators, "DuplicateDominators" );
  1286. MESSAGE_FUNC( OnSelectDominators, "SelectDominators" );
  1287. MESSAGE_FUNC( OnSelectSuppressed, "SelectSuppressed" );
  1288. MESSAGE_FUNC( OnMoveUp, "MoveUp" );
  1289. MESSAGE_FUNC( OnMoveDown, "MoveDown" );
  1290. MESSAGE_FUNC( OnImportDominationRules, "ImportDominationRules" );
  1291. MESSAGE_FUNC_PARAMS( OnFileSelected, "FileSelected", kv );
  1292. // Cleans up the context menu
  1293. void CleanupContextMenu();
  1294. // Selects a particular domination rule
  1295. void SelectRule( CDmeCombinationDominationRule* pRule );
  1296. // Returns the currently selected rule
  1297. CDmeCombinationDominationRule* GetSelectedRule( );
  1298. CDmeHandle< CDmeCombinationOperator > m_hCombinationOperator;
  1299. vgui::ListPanel *m_pDominationRulesList;
  1300. vgui::DHANDLE< vgui::Menu > m_hContextMenu;
  1301. };
  1302. static int __cdecl DominatorNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
  1303. {
  1304. int i1 = item1.kv->GetInt("index");
  1305. int i2 = item2.kv->GetInt("index");
  1306. return i1 - i2;
  1307. }
  1308. //-----------------------------------------------------------------------------
  1309. // constructor, destructor
  1310. //-----------------------------------------------------------------------------
  1311. CDmeCombinationDominationRulesPanel::CDmeCombinationDominationRulesPanel( vgui::Panel *pParent, const char *pName ) :
  1312. BaseClass( pParent, pName )
  1313. {
  1314. m_pDominationRulesList = new vgui::ListPanel( this, "DominationRulesList" );
  1315. m_pDominationRulesList->AddColumnHeader( 0, "suppressed", "Suppress", 100, 0 );
  1316. m_pDominationRulesList->AddColumnHeader( 1, "dominator", "Dominate", 100, 0 );
  1317. m_pDominationRulesList->AddActionSignalTarget( this );
  1318. m_pDominationRulesList->SetSortFunc( 0, DominatorNameSortFunc );
  1319. m_pDominationRulesList->SetSortFunc( 1, DominatorNameSortFunc );
  1320. m_pDominationRulesList->SetSortColumn( 0 );
  1321. m_pDominationRulesList->SetEmptyListText("No domination rules.");
  1322. m_pDominationRulesList->SetMultiselectEnabled( false );
  1323. }
  1324. CDmeCombinationDominationRulesPanel::~CDmeCombinationDominationRulesPanel()
  1325. {
  1326. CleanupContextMenu();
  1327. SaveUserConfig();
  1328. }
  1329. //-----------------------------------------------------------------------------
  1330. // Cleans up the context menu
  1331. //-----------------------------------------------------------------------------
  1332. void CDmeCombinationDominationRulesPanel::CleanupContextMenu()
  1333. {
  1334. if ( m_hContextMenu.Get() )
  1335. {
  1336. m_hContextMenu->MarkForDeletion();
  1337. m_hContextMenu = NULL;
  1338. }
  1339. }
  1340. //-----------------------------------------------------------------------------
  1341. // Sets the combination operator
  1342. //-----------------------------------------------------------------------------
  1343. void CDmeCombinationDominationRulesPanel::SetCombinationOperator( CDmeCombinationOperator *pOp )
  1344. {
  1345. if ( pOp != m_hCombinationOperator.Get() )
  1346. {
  1347. m_hCombinationOperator = pOp;
  1348. RefreshCombinationOperator();
  1349. }
  1350. }
  1351. //-----------------------------------------------------------------------------
  1352. // Purpose: Basic sort function, for use in qsort
  1353. //-----------------------------------------------------------------------------
  1354. static int __cdecl ControlNameSortFunc(const void *elem1, const void *elem2)
  1355. {
  1356. const char *pItem1 = *((const char **) elem1);
  1357. const char *pItem2 = *((const char **) elem2);
  1358. return Q_stricmp( pItem1, pItem2 );
  1359. }
  1360. //-----------------------------------------------------------------------------
  1361. // Builds the list of animations
  1362. //-----------------------------------------------------------------------------
  1363. void CDmeCombinationDominationRulesPanel::RefreshCombinationOperator()
  1364. {
  1365. m_pDominationRulesList->RemoveAll();
  1366. if ( !m_hCombinationOperator.Get() )
  1367. return;
  1368. char pTemp[1024];
  1369. int nCount = m_hCombinationOperator->DominationRuleCount();
  1370. for ( int i = 0; i < nCount; ++i )
  1371. {
  1372. CDmeCombinationDominationRule *pRule = m_hCombinationOperator->GetDominationRule( i );
  1373. KeyValues *pItemKeys = new KeyValues( "node" );
  1374. int nLen = 0;
  1375. int nControlCount = pRule->DominatorCount();
  1376. pTemp[0] = 0;
  1377. const char **ppStrings = (const char**)_alloca( nControlCount * sizeof(const char*) );
  1378. for ( int j = 0; j < nControlCount; ++j )
  1379. {
  1380. ppStrings[j] = pRule->GetDominator(j);
  1381. }
  1382. qsort( ppStrings, (size_t)nControlCount, (size_t)sizeof(char*), ControlNameSortFunc );
  1383. for ( int j = 0; j < nControlCount; ++j )
  1384. {
  1385. nLen += Q_snprintf( &pTemp[nLen], sizeof(pTemp) - nLen, "%s ", ppStrings[j] );
  1386. }
  1387. pItemKeys->SetString( "dominator", pTemp );
  1388. nLen = 0;
  1389. nControlCount = pRule->SuppressedCount();
  1390. pTemp[0] = 0;
  1391. ppStrings = (const char**)_alloca( nControlCount * sizeof(const char*) );
  1392. for ( int j = 0; j < nControlCount; ++j )
  1393. {
  1394. ppStrings[j] = pRule->GetSuppressed(j);
  1395. }
  1396. qsort( ppStrings, (size_t)nControlCount, (size_t)sizeof(char*), ControlNameSortFunc );
  1397. for ( int j = 0; j < nControlCount; ++j )
  1398. {
  1399. nLen += Q_snprintf( &pTemp[nLen], sizeof(pTemp) - nLen, "%s ", ppStrings[j] );
  1400. }
  1401. pItemKeys->SetString( "suppressed", pTemp );
  1402. pItemKeys->SetInt( "index", i );
  1403. SetElementKeyValue( pItemKeys, "rule", pRule );
  1404. m_pDominationRulesList->AddItem( pItemKeys, 0, false, false );
  1405. }
  1406. m_pDominationRulesList->SortList();
  1407. }
  1408. void CDmeCombinationDominationRulesPanel::NotifyDataChanged()
  1409. {
  1410. PostActionSignal( new KeyValues( "DmeElementChanged", "DmeCombinationDominationRulesPanel", 2 ) );
  1411. }
  1412. //-----------------------------------------------------------------------------
  1413. // Returns the currently selected domination rule
  1414. //-----------------------------------------------------------------------------
  1415. CDmeCombinationDominationRule* CDmeCombinationDominationRulesPanel::GetSelectedRule( )
  1416. {
  1417. if ( !m_hCombinationOperator.Get() )
  1418. return NULL;
  1419. int nSelectedItemCount = m_pDominationRulesList->GetSelectedItemsCount();
  1420. if ( nSelectedItemCount != 1 )
  1421. return NULL;
  1422. int nItemID = m_pDominationRulesList->GetSelectedItem( 0 );
  1423. KeyValues *pKeyValues = m_pDominationRulesList->GetItem( nItemID );
  1424. return GetElementKeyValue<CDmeCombinationDominationRule>( pKeyValues, "rule" );
  1425. }
  1426. //-----------------------------------------------------------------------------
  1427. // Reorder rules
  1428. //-----------------------------------------------------------------------------
  1429. void CDmeCombinationDominationRulesPanel::OnMoveUp( )
  1430. {
  1431. CDmeCombinationDominationRule* pRule = GetSelectedRule( );
  1432. if ( !pRule )
  1433. return;
  1434. m_hCombinationOperator->MoveDominationRuleUp( pRule );
  1435. RefreshCombinationOperator();
  1436. NotifyDataChanged();
  1437. }
  1438. void CDmeCombinationDominationRulesPanel::OnMoveDown( )
  1439. {
  1440. CDmeCombinationDominationRule* pRule = GetSelectedRule( );
  1441. if ( !pRule )
  1442. return;
  1443. m_hCombinationOperator->MoveDominationRuleDown( pRule );
  1444. RefreshCombinationOperator();
  1445. NotifyDataChanged();
  1446. }
  1447. //-----------------------------------------------------------------------------
  1448. // Called when the file open dialog for browsing source files selects something
  1449. //-----------------------------------------------------------------------------
  1450. void CDmeCombinationDominationRulesPanel::OnFileSelected( KeyValues *kv )
  1451. {
  1452. if ( ImportCombinationData( this, m_hCombinationOperator, kv ) )
  1453. {
  1454. RefreshCombinationOperator();
  1455. NotifyDataChanged();
  1456. }
  1457. }
  1458. //-----------------------------------------------------------------------------
  1459. // Import domination rules
  1460. //-----------------------------------------------------------------------------
  1461. void CDmeCombinationDominationRulesPanel::OnImportDominationRules()
  1462. {
  1463. char pStartingDir[MAX_PATH];
  1464. GetModContentSubdirectory( "models", pStartingDir, sizeof(pStartingDir) );
  1465. vgui::FileOpenDialog *pDialog = new vgui::FileOpenDialog( this, "Select File to Import", true, new KeyValues( "ImportDominationRules" ) );
  1466. pDialog->SetStartDirectoryContext( "combination_system_import", pStartingDir );
  1467. pDialog->AddFilter( "*.dmx", "Exported model file (*.dmx)", true );
  1468. pDialog->SetDeleteSelfOnClose( true );
  1469. pDialog->AddActionSignalTarget( this );
  1470. pDialog->DoModal( false );
  1471. }
  1472. //-----------------------------------------------------------------------------
  1473. // Called to open a context-sensitive menu for a particular menu item
  1474. //-----------------------------------------------------------------------------
  1475. void CDmeCombinationDominationRulesPanel::OnOpenContextMenu( KeyValues *kv )
  1476. {
  1477. CleanupContextMenu();
  1478. if ( !m_hCombinationOperator.Get() )
  1479. return;
  1480. Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL );
  1481. if ( pPanel != m_pDominationRulesList )
  1482. return;
  1483. int nSelectedItemCount = m_pDominationRulesList->GetSelectedItemsCount();
  1484. m_hContextMenu = new vgui::Menu( this, "ActionMenu" );
  1485. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_AddDominationRule", new KeyValues( "AddDominationRule" ), this );
  1486. if ( nSelectedItemCount > 0 )
  1487. {
  1488. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_RemoveDominationRule", new KeyValues( "RemoveDominationRule" ), this );
  1489. }
  1490. if ( nSelectedItemCount == 1 )
  1491. {
  1492. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_DuplicateSuppressed", new KeyValues( "DuplicateSuppressed" ), this );
  1493. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_DuplicateDominators", new KeyValues( "DuplicateDominators" ), this );
  1494. m_hContextMenu->AddSeparator();
  1495. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_SelectSuppressed", new KeyValues( "SelectSuppressed" ), this );
  1496. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_SelectDominators", new KeyValues( "SelectDominators" ), this );
  1497. m_hContextMenu->AddSeparator();
  1498. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveUp", new KeyValues( "MoveUp" ), this );
  1499. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_MoveDown", new KeyValues( "MoveDown" ), this );
  1500. }
  1501. m_hContextMenu->AddSeparator();
  1502. m_hContextMenu->AddMenuItem( "#DmeCombinationSystemEditor_ImportDomination", new KeyValues( "ImportDominationRules" ), this );
  1503. vgui::Menu::PlaceContextMenu( this, m_hContextMenu.Get() );
  1504. }
  1505. //-----------------------------------------------------------------------------
  1506. // Selects a particular domination rule
  1507. //-----------------------------------------------------------------------------
  1508. void CDmeCombinationDominationRulesPanel::SelectRule( CDmeCombinationDominationRule* pRule )
  1509. {
  1510. for ( int nItemID = m_pDominationRulesList->FirstItem(); nItemID != m_pDominationRulesList->InvalidItemID(); nItemID = m_pDominationRulesList->NextItem( nItemID ) )
  1511. {
  1512. KeyValues *pKeyValues = m_pDominationRulesList->GetItem( nItemID );
  1513. if ( pRule == GetElementKeyValue<CDmeCombinationDominationRule>( pKeyValues, "rule" ) )
  1514. {
  1515. m_pDominationRulesList->SetSingleSelectedItem( nItemID );
  1516. break;
  1517. }
  1518. }
  1519. }
  1520. //-----------------------------------------------------------------------------
  1521. // Called by the context menu to add dominator rules
  1522. //-----------------------------------------------------------------------------
  1523. void CDmeCombinationDominationRulesPanel::OnAddDominationRule( )
  1524. {
  1525. CDmeCombinationDominationRule* pRule = m_hCombinationOperator->AddDominationRule();
  1526. RefreshCombinationOperator();
  1527. SelectRule( pRule );
  1528. OnSelectSuppressed();
  1529. NotifyDataChanged();
  1530. }
  1531. //-----------------------------------------------------------------------------
  1532. // Duplicate suppressed
  1533. //-----------------------------------------------------------------------------
  1534. void CDmeCombinationDominationRulesPanel::OnDuplicateSuppressed()
  1535. {
  1536. CDmeCombinationDominationRule *pSrcRule = GetSelectedRule();
  1537. if ( !pSrcRule )
  1538. return;
  1539. CDmeCombinationDominationRule* pRule = m_hCombinationOperator->AddDominationRule();
  1540. RefreshCombinationOperator();
  1541. SelectRule( pRule );
  1542. for ( int i = 0; i < pSrcRule->SuppressedCount(); ++i )
  1543. {
  1544. pRule->AddSuppressed( pSrcRule->GetSuppressed( i ) );
  1545. }
  1546. OnSelectDominators();
  1547. NotifyDataChanged();
  1548. }
  1549. void CDmeCombinationDominationRulesPanel::OnDuplicateDominators()
  1550. {
  1551. CDmeCombinationDominationRule *pSrcRule = GetSelectedRule();
  1552. if ( !pSrcRule )
  1553. return;
  1554. CDmeCombinationDominationRule* pRule = m_hCombinationOperator->AddDominationRule();
  1555. RefreshCombinationOperator();
  1556. SelectRule( pRule );
  1557. for ( int i = 0; i < pSrcRule->DominatorCount(); ++i )
  1558. {
  1559. pRule->AddDominator( pSrcRule->GetDominator( i ) );
  1560. }
  1561. OnSelectSuppressed();
  1562. NotifyDataChanged();
  1563. }
  1564. //-----------------------------------------------------------------------------
  1565. // Called by the context menu to remove dominator rules
  1566. //-----------------------------------------------------------------------------
  1567. void CDmeCombinationDominationRulesPanel::OnRemoveDominationRule( )
  1568. {
  1569. int nSelectedItemCount = m_pDominationRulesList->GetSelectedItemsCount();
  1570. for ( int i = 0; i < nSelectedItemCount; ++i )
  1571. {
  1572. int nItemID = m_pDominationRulesList->GetSelectedItem( i );
  1573. KeyValues *pKeyValues = m_pDominationRulesList->GetItem( nItemID );
  1574. CDmeCombinationDominationRule *pRule = GetElementKeyValue<CDmeCombinationDominationRule>( pKeyValues, "rule" );
  1575. if ( pRule )
  1576. {
  1577. m_hCombinationOperator->RemoveDominationRule( pRule );
  1578. }
  1579. }
  1580. RefreshCombinationOperator();
  1581. NotifyDataChanged();
  1582. }
  1583. //-----------------------------------------------------------------------------
  1584. // Called by the pickers made in OnSelectDominators + OnSelectSuppressed
  1585. //-----------------------------------------------------------------------------
  1586. void CDmeCombinationDominationRulesPanel::OnRawControlPicked( KeyValues *pKeyValues )
  1587. {
  1588. KeyValues *pControlList = pKeyValues->FindKey( "rawControls" );
  1589. if ( !pControlList )
  1590. return;
  1591. KeyValues *pContextKeys = pKeyValues->FindKey( "OnSelectDominators" );
  1592. if ( pContextKeys )
  1593. {
  1594. CDmeCombinationDominationRule *pRule = GetElementKeyValue<CDmeCombinationDominationRule>( pContextKeys, "rule" );
  1595. if ( !pRule )
  1596. return;
  1597. pRule->RemoveAllDominators();
  1598. for ( KeyValues *pKey = pControlList->GetFirstValue(); pKey; pKey = pKey->GetNextValue() )
  1599. {
  1600. pRule->AddDominator( pKey->GetName() );
  1601. }
  1602. RefreshCombinationOperator();
  1603. NotifyDataChanged();
  1604. return;
  1605. }
  1606. pContextKeys = pKeyValues->FindKey( "OnSelectSuppressed" );
  1607. if ( pContextKeys )
  1608. {
  1609. CDmeCombinationDominationRule *pRule = GetElementKeyValue<CDmeCombinationDominationRule>( pContextKeys, "rule" );
  1610. if ( !pRule )
  1611. return;
  1612. pRule->RemoveAllSuppressed();
  1613. for ( KeyValues *pKey = pControlList->GetFirstValue(); pKey; pKey = pKey->GetNextValue() )
  1614. {
  1615. pRule->AddSuppressed( pKey->GetName() );
  1616. }
  1617. RefreshCombinationOperator();
  1618. NotifyDataChanged();
  1619. return;
  1620. }
  1621. }
  1622. //-----------------------------------------------------------------------------
  1623. // Called by the context menu to change dominator rules
  1624. //-----------------------------------------------------------------------------
  1625. void CDmeCombinationDominationRulesPanel::OnSelectDominators( )
  1626. {
  1627. CDmeCombinationDominationRule *pRule = GetSelectedRule();
  1628. if ( !pRule )
  1629. return;
  1630. KeyValues *pContextKeyValues = new KeyValues( "OnSelectDominators" );
  1631. SetElementKeyValue( pContextKeyValues, "rule", pRule );
  1632. CRawControlPickerFrame *pPicker = new CRawControlPickerFrame( this, "Select Dominator(s)" );
  1633. pPicker->DoModal( m_hCombinationOperator, pRule, false, pContextKeyValues );
  1634. }
  1635. void CDmeCombinationDominationRulesPanel::OnSelectSuppressed( )
  1636. {
  1637. CDmeCombinationDominationRule *pRule = GetSelectedRule();
  1638. if ( !pRule )
  1639. return;
  1640. KeyValues *pContextKeyValues = new KeyValues( "OnSelectSuppressed" );
  1641. SetElementKeyValue( pContextKeyValues, "rule", pRule );
  1642. CRawControlPickerFrame *pPicker = new CRawControlPickerFrame( this, "Select Suppressed" );
  1643. pPicker->DoModal( m_hCombinationOperator, pRule, true, pContextKeyValues );
  1644. }
  1645. //-----------------------------------------------------------------------------
  1646. //
  1647. // Combination system editor panel
  1648. //
  1649. //-----------------------------------------------------------------------------
  1650. //-----------------------------------------------------------------------------
  1651. // Constructor, destructor
  1652. //-----------------------------------------------------------------------------
  1653. CDmeCombinationSystemEditorPanel::CDmeCombinationSystemEditorPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
  1654. {
  1655. m_pEditorSheet = new vgui::PropertySheet( this, "EditorSheet" );
  1656. m_pEditorSheet->AddActionSignalTarget( this );
  1657. m_pControlsPage = new vgui::PropertyPage( m_pEditorSheet, "ControlsPage" );
  1658. m_pDominationRulesPage = new vgui::PropertyPage( m_pEditorSheet, "DominationRulesPage" );
  1659. m_pPropertiesPage = new vgui::PropertyPage( m_pEditorSheet, "PropertiesPage" );
  1660. m_pControlsPanel = new CDmeCombinationControlsPanel( (vgui::Panel*)NULL, "CombinationControls" );
  1661. m_pControlsPanel->AddActionSignalTarget( this );
  1662. m_pDominationRulesPanel = new CDmeCombinationDominationRulesPanel( (vgui::Panel*)NULL, "DominationRules" );
  1663. m_pDominationRulesPanel->AddActionSignalTarget( this );
  1664. m_pPropertiesPanel = new CDmeElementPanel( (vgui::Panel*)NULL, "PropertiesPanel" );
  1665. m_pPropertiesPanel->AddActionSignalTarget( this );
  1666. m_pControlsPanel->LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorpanel_controlspage.res" );
  1667. m_pDominationRulesPanel->LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorpanel_dominationpage.res" );
  1668. // Load layout settings; has to happen before pinning occurs in code
  1669. LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorpanel.res" );
  1670. // NOTE: Page adding happens *after* LoadControlSettingsAndUserConfig
  1671. // because the layout of the sheet is correct at this point.
  1672. m_pEditorSheet->AddPage( m_pControlsPanel, "Controls" );
  1673. m_pEditorSheet->AddPage( m_pDominationRulesPanel, "Domination" );
  1674. m_pEditorSheet->AddPage( m_pPropertiesPanel, "Properties" );
  1675. }
  1676. CDmeCombinationSystemEditorPanel::~CDmeCombinationSystemEditorPanel()
  1677. {
  1678. }
  1679. //-----------------------------------------------------------------------------
  1680. // Set the scene
  1681. //-----------------------------------------------------------------------------
  1682. void CDmeCombinationSystemEditorPanel::SetDmeElement( CDmeCombinationOperator *pComboOp )
  1683. {
  1684. m_pControlsPanel->SetCombinationOperator( pComboOp );
  1685. m_pDominationRulesPanel->SetCombinationOperator( pComboOp );
  1686. m_pPropertiesPanel->SetDmeElement( pComboOp );
  1687. }
  1688. CDmeCombinationOperator *CDmeCombinationSystemEditorPanel::GetDmeElement()
  1689. {
  1690. return m_pControlsPanel->GetCombinationOperator( );
  1691. }
  1692. //-----------------------------------------------------------------------------
  1693. // Called when the page changes
  1694. //-----------------------------------------------------------------------------
  1695. void CDmeCombinationSystemEditorPanel::OnPageChanged( )
  1696. {
  1697. if ( m_pEditorSheet->GetActivePage() == m_pControlsPage )
  1698. {
  1699. return;
  1700. }
  1701. if ( m_pEditorSheet->GetActivePage() == m_pDominationRulesPage )
  1702. {
  1703. return;
  1704. }
  1705. }
  1706. //-----------------------------------------------------------------------------
  1707. // Called when the property editor has made a change
  1708. //-----------------------------------------------------------------------------
  1709. void CDmeCombinationSystemEditorPanel::OnDmeElementChanged( KeyValues *kv )
  1710. {
  1711. m_pControlsPanel->RefreshCombinationOperator();
  1712. m_pDominationRulesPanel->RefreshCombinationOperator();
  1713. m_pPropertiesPanel->Refresh();
  1714. PostActionSignal( new KeyValues( "DmeElementChanged" ) );
  1715. }
  1716. //-----------------------------------------------------------------------------
  1717. //
  1718. // Purpose: Combination system editor frame
  1719. //
  1720. //-----------------------------------------------------------------------------
  1721. CDmeCombinationSystemEditorFrame::CDmeCombinationSystemEditorFrame( vgui::Panel *pParent, const char *pTitle ) :
  1722. BaseClass( pParent, "DmeCombinationSystemEditorFrame" )
  1723. {
  1724. SetDeleteSelfOnClose( true );
  1725. m_pEditor = new CDmeCombinationSystemEditorPanel( this, "DmeCombinationSystemEditorPanel" );
  1726. m_pEditor->AddActionSignalTarget( this );
  1727. m_pOpenButton = new vgui::Button( this, "OpenButton", "#FileOpenDialog_Open", this, "Open" );
  1728. m_pCancelButton = new vgui::Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" );
  1729. SetBlockDragChaining( true );
  1730. LoadControlSettingsAndUserConfig( "resource/dmecombinationsystemeditorframe.res" );
  1731. SetTitle( pTitle, false );
  1732. }
  1733. CDmeCombinationSystemEditorFrame::~CDmeCombinationSystemEditorFrame()
  1734. {
  1735. }
  1736. //-----------------------------------------------------------------------------
  1737. // Sets the current scene + animation list
  1738. //-----------------------------------------------------------------------------
  1739. void CDmeCombinationSystemEditorFrame::SetCombinationOperator( CDmeCombinationOperator *pComboSystem )
  1740. {
  1741. m_pEditor->SetDmeElement( pComboSystem );
  1742. }
  1743. //-----------------------------------------------------------------------------
  1744. // On command
  1745. //-----------------------------------------------------------------------------
  1746. void CDmeCombinationSystemEditorFrame::OnCommand( const char *pCommand )
  1747. {
  1748. if ( !Q_stricmp( pCommand, "Open" ) )
  1749. {
  1750. return;
  1751. }
  1752. if ( !Q_stricmp( pCommand, "Cancel" ) )
  1753. {
  1754. return;
  1755. }
  1756. BaseClass::OnCommand( pCommand );
  1757. }
  1758. //-----------------------------------------------------------------------------
  1759. // On command
  1760. //-----------------------------------------------------------------------------
  1761. void CDmeCombinationSystemEditorFrame::OnDmeElementChanged()
  1762. {
  1763. PostActionSignal( new KeyValues( "CombinationOperatorChanged" ) );
  1764. }