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.

2139 lines
73 KiB

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