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.

513 lines
16 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Singleton dialog that generates and presents the entity report.
  4. //
  5. //===========================================================================//
  6. #include "particlesystemdefinitionbrowser.h"
  7. #include "tier1/keyvalues.h"
  8. #include "tier1/utlbuffer.h"
  9. #include "iregistry.h"
  10. #include "vgui/ivgui.h"
  11. #include "vgui_controls/listpanel.h"
  12. #include "vgui_controls/inputdialog.h"
  13. #include "vgui_controls/messagebox.h"
  14. #include "petdoc.h"
  15. #include "pettool.h"
  16. #include "datamodel/dmelement.h"
  17. #include "vgui/keycode.h"
  18. #include "dme_controls/dmecontrols_utils.h"
  19. #include "dme_controls/particlesystempanel.h"
  20. #include "matsys_controls/particlepicker.h"
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include <tier0/memdbgon.h>
  23. using namespace vgui;
  24. //-----------------------------------------------------------------------------
  25. // Sort by particle system definition name
  26. //-----------------------------------------------------------------------------
  27. static int __cdecl ParticleSystemNameSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
  28. {
  29. const char *string1 = item1.kv->GetString("name");
  30. const char *string2 = item2.kv->GetString("name");
  31. return Q_stricmp( string1, string2 );
  32. }
  33. //-----------------------------------------------------------------------------
  34. // Constructor
  35. //-----------------------------------------------------------------------------
  36. CParticleSystemDefinitionBrowser::CParticleSystemDefinitionBrowser( CPetDoc *pDoc, vgui::Panel* pParent, const char *pName )
  37. : BaseClass( pParent, pName ), m_pDoc( pDoc )
  38. {
  39. SetKeyBoardInputEnabled( true );
  40. SetPaintBackgroundEnabled( true );
  41. m_pSystemGrid = new CParticleSnapshotGrid( this, "SnapshotGrid" );
  42. m_pSystemGrid->AddActionSignalTarget(this);
  43. CBoxSizer *pBaseSizer = new CBoxSizer( ESLD_HORIZONTAL );
  44. {
  45. CBoxSizer *pDefinitionSizer = new CBoxSizer( ESLD_VERTICAL );
  46. pDefinitionSizer->AddPanel( new Label( this, "ParticleSystemsLabel", "Particle System Definitions:" ), SizerAddArgs_t() );
  47. pDefinitionSizer->AddPanel( m_pSystemGrid, SizerAddArgs_t().Expand( 1.0f ) );
  48. {
  49. CBoxSizer *pBottomRowSizer = new CBoxSizer( ESLD_HORIZONTAL );
  50. pBottomRowSizer->AddPanel( new Button( this, "SaveButton", "Save", this, "save" ), SizerAddArgs_t() );
  51. pBottomRowSizer->AddPanel( new Button( this, "SaveAndTestButton", "Save and Test", this, "SaveAndTest" ), SizerAddArgs_t() );
  52. pDefinitionSizer->AddSizer( pBottomRowSizer, SizerAddArgs_t() );
  53. }
  54. pBaseSizer->AddSizer( pDefinitionSizer, SizerAddArgs_t().Expand( 1.0f ) );
  55. }
  56. {
  57. CBoxSizer *pButtonColSizer = new CBoxSizer( ESLD_VERTICAL );
  58. m_pCreateButton = new Button( this, "CreateButton", "Create", this, "Create" );
  59. pButtonColSizer->AddPanel( m_pCreateButton, SizerAddArgs_t() );
  60. m_pDeleteButton = new Button( this, "DeleteButton", "Delete", this, "Delete" );
  61. m_pDeleteButton->SetEnabled(false);
  62. pButtonColSizer->AddPanel( m_pDeleteButton, SizerAddArgs_t() );
  63. m_pCopyButton = new Button( this, "CopyButton", "Duplicate", this, "Copy" );
  64. m_pCopyButton->SetEnabled(false);
  65. pButtonColSizer->AddPanel( m_pCopyButton, SizerAddArgs_t() );
  66. pBaseSizer->AddSizer( pButtonColSizer, SizerAddArgs_t() );
  67. }
  68. SetSizer( pBaseSizer );
  69. UpdateParticleSystemList();
  70. }
  71. CParticleSystemDefinitionBrowser::~CParticleSystemDefinitionBrowser()
  72. {
  73. SaveUserConfig();
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Gets the ith selected particle system
  77. //-----------------------------------------------------------------------------
  78. CDmeParticleSystemDefinition* CParticleSystemDefinitionBrowser::GetSelectedParticleSystem( int i )
  79. {
  80. if ( i < 0 || i >= m_pSystemGrid->GetSelectedSystemCount() )
  81. return NULL;
  82. int iSel = m_pSystemGrid->GetSelectedSystemId(i);
  83. return m_pDoc->GetParticleSystem(iSel);
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Purpose: Deletes the marked objects.
  87. //-----------------------------------------------------------------------------
  88. void CParticleSystemDefinitionBrowser::DeleteParticleSystems()
  89. {
  90. {
  91. // This is undoable
  92. CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG|NOTIFY_FLAG_PARTICLESYS_ADDED_OR_REMOVED, "Delete Particle Systems", "Delete Particle Systems" );
  93. //
  94. // Build a list of objects to delete.
  95. //
  96. CUtlVector< CDmeParticleSystemDefinition* > itemsToDelete;
  97. int nCount = m_pSystemGrid->GetSelectedSystemCount();
  98. for (int i = 0; i < nCount; i++)
  99. {
  100. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  101. if ( pParticleSystem )
  102. {
  103. itemsToDelete.AddToTail( pParticleSystem );
  104. }
  105. }
  106. m_pSystemGrid->DeselectAll();
  107. nCount = itemsToDelete.Count();
  108. for ( int i = 0; i < nCount; ++i )
  109. {
  110. m_pDoc->DeleteParticleSystemDefinition( itemsToDelete[i] );
  111. }
  112. g_pPetTool->SetCurrentParticleSystem( NULL, true );
  113. }
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose:
  117. //-----------------------------------------------------------------------------
  118. void CParticleSystemDefinitionBrowser::OnKeyCodeTyped( vgui::KeyCode code )
  119. {
  120. if ( code == KEY_DELETE )
  121. {
  122. DeleteParticleSystems();
  123. }
  124. else
  125. {
  126. BaseClass::OnKeyCodeTyped( code );
  127. }
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Called when the selection changes
  131. //-----------------------------------------------------------------------------
  132. void CParticleSystemDefinitionBrowser::UpdateParticleSystemSelection()
  133. {
  134. if ( m_pSystemGrid->GetSelectedSystemCount() == 1 )
  135. {
  136. g_pPetTool->SetCurrentParticleSystem( m_pDoc->GetParticleSystem( m_pSystemGrid->GetSelectedSystemId(0) ), false );
  137. }
  138. else
  139. {
  140. g_pPetTool->SetCurrentParticleSystem( NULL, false );
  141. }
  142. }
  143. void CParticleSystemDefinitionBrowser::OnParticleSystemSelectionChanged( )
  144. {
  145. UpdateParticleSystemSelection();
  146. bool bAnySelected = ( m_pSystemGrid->GetSelectedSystemCount() > 0 );
  147. m_pDeleteButton->SetEnabled( bAnySelected );
  148. m_pCopyButton->SetEnabled( bAnySelected );
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Select a particular node
  152. //-----------------------------------------------------------------------------
  153. void CParticleSystemDefinitionBrowser::SelectParticleSystem( CDmeParticleSystemDefinition *pFind )
  154. {
  155. for ( int i = 0; i < m_pDoc->GetParticleSystemCount(); ++i )
  156. {
  157. if ( m_pDoc->GetParticleSystem(i) == pFind )
  158. {
  159. m_pSystemGrid->SelectId( i, false, false );
  160. break;
  161. }
  162. }
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Called when buttons are clicked
  166. //-----------------------------------------------------------------------------
  167. void CParticleSystemDefinitionBrowser::OnInputCompleted( KeyValues *pKeyValues )
  168. {
  169. const char *pText = pKeyValues->GetString( "text", NULL );
  170. if ( m_pDoc->IsParticleSystemDefined( pText ) )
  171. {
  172. char pBuf[1024];
  173. Q_snprintf( pBuf, sizeof(pBuf), "Particle System \"%s\" already exists!\n", pText );
  174. vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Duplicate Particle System Name!\n", pBuf, g_pPetTool->GetRootPanel() );
  175. pMessageBox->DoModal( );
  176. return;
  177. }
  178. if ( pKeyValues->FindKey( "create" ) )
  179. {
  180. CDmeParticleSystemDefinition *pParticleSystem = m_pDoc->AddNewParticleSystemDefinition( pText );
  181. g_pPetTool->SetCurrentParticleSystem( pParticleSystem );
  182. }
  183. else if ( pKeyValues->FindKey( "copy_one" ) || pKeyValues->FindKey( "copy_many" ) )
  184. {
  185. int nCount = m_pSystemGrid->GetSelectedSystemCount();
  186. if ( nCount == 1 )
  187. {
  188. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( 0 );
  189. CDmeParticleSystemDefinition * pNew = NULL;
  190. {
  191. CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG|NOTIFY_FLAG_PARTICLESYS_ADDED_OR_REMOVED, "Duplicate One Particle System", "Duplicate One Particle System" );
  192. pNew = CastElement<CDmeParticleSystemDefinition>( pParticleSystem->Copy( ) );
  193. pNew->SetName( pText );
  194. m_pDoc->AddNewParticleSystemDefinition( pNew, guard );
  195. }
  196. g_pPetTool->SetCurrentParticleSystem( pNew );
  197. }
  198. else if ( nCount > 1 )
  199. {
  200. CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG|NOTIFY_FLAG_PARTICLESYS_ADDED_OR_REMOVED, "Duplicate Multiple Particle Systems", "Duplicate Multiple Particle Systems" );
  201. CUtlVector<CDmeParticleSystemDefinition*> pNewSystems;
  202. for ( int i = 0; i < nCount; ++i )
  203. {
  204. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  205. CDmeParticleSystemDefinition *pNew = NULL;
  206. CUtlString newName = pParticleSystem->GetName();
  207. newName += pText;
  208. pNew = CastElement<CDmeParticleSystemDefinition>( pParticleSystem->Copy( ) );
  209. pNew->SetName( newName.Get() );
  210. pNewSystems.AddToTail(pNew);
  211. }
  212. Assert( pNewSystems.Count() == nCount );
  213. for ( int i = 0; i < nCount; ++i )
  214. {
  215. m_pDoc->AddNewParticleSystemDefinition( pNewSystems[i], guard );
  216. }
  217. g_pPetTool->SetCurrentParticleSystem( NULL );
  218. }
  219. }
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Copy to clipboard
  223. //-----------------------------------------------------------------------------
  224. void CParticleSystemDefinitionBrowser::OnCopy( )
  225. {
  226. int nCount = m_pSystemGrid->GetSelectedSystemCount();
  227. CUtlVector< KeyValues * > list;
  228. CUtlRBTree< CDmeParticleSystemDefinition* > defs( 0, 0, DefLessFunc( CDmeParticleSystemDefinition* ) );
  229. for ( int i = 0; i < nCount; ++i )
  230. {
  231. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  232. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  233. if ( g_pDataModel->Serialize( buf, "keyvalues2", "pcf", pParticleSystem->GetHandle() ) )
  234. {
  235. KeyValues *pData = new KeyValues( "Clipboard" );
  236. pData->SetString( PARTICLE_CLIPBOARD_DEFINITION_STR, (char*)buf.Base() );
  237. list.AddToTail( pData );
  238. }
  239. }
  240. if ( list.Count() )
  241. {
  242. g_pDataModel->SetClipboardData( list );
  243. }
  244. }
  245. //-----------------------------------------------------------------------------
  246. // Paste from clipboard
  247. //-----------------------------------------------------------------------------
  248. void CParticleSystemDefinitionBrowser::ReplaceDef_r( CUndoScopeGuard& guard, CDmeParticleSystemDefinition *pDef )
  249. {
  250. if ( !pDef )
  251. return;
  252. m_pDoc->ReplaceParticleSystemDefinition( pDef );
  253. int nChildCount = pDef->GetParticleFunctionCount( FUNCTION_CHILDREN );
  254. for ( int i = 0; i < nChildCount; ++i )
  255. {
  256. CDmeParticleChild *pChildFunction = static_cast< CDmeParticleChild* >( pDef->GetParticleFunction( FUNCTION_CHILDREN, i ) );
  257. CDmeParticleSystemDefinition* pChild = pChildFunction->m_Child;
  258. ReplaceDef_r( guard, pChild );
  259. }
  260. }
  261. void CParticleSystemDefinitionBrowser::PasteOperator( CUndoScopeGuard& guard, CDmeParticleFunction *pFunc )
  262. {
  263. int nCount = m_pSystemGrid->GetSelectedSystemCount();
  264. for ( int i = 0; i < nCount; ++i )
  265. {
  266. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  267. pParticleSystem->AddCopyOfOperator( pFunc );
  268. }
  269. }
  270. void CParticleSystemDefinitionBrowser::PasteDefinitionBody( CUndoScopeGuard& guard, CDmeParticleSystemDefinition *pDef )
  271. {
  272. int nCount = m_pSystemGrid->GetSelectedSystemCount();
  273. for ( int i = 0; i < nCount; ++i )
  274. {
  275. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  276. pParticleSystem->OverrideAttributesFromOtherDefinition( pDef );
  277. }
  278. }
  279. void CParticleSystemDefinitionBrowser::PasteFromClipboard( )
  280. {
  281. // This is undoable
  282. CAppUndoScopeGuard guard( NOTIFY_SETDIRTYFLAG, "Paste From Clipboard", "Paste From Clipboard" );
  283. bool bRefreshAll = false;
  284. CUtlVector< KeyValues * > list;
  285. g_pDataModel->GetClipboardData( list );
  286. int nItems = list.Count();
  287. for ( int i = 0; i < nItems; ++i )
  288. {
  289. CDmeParticleSystemDefinition *pDef = ReadParticleClassFromKV<CDmeParticleSystemDefinition>( list[i], PARTICLE_CLIPBOARD_DEFINITION_STR );
  290. if ( pDef )
  291. {
  292. ReplaceDef_r( guard, pDef );
  293. bRefreshAll = true;
  294. continue;
  295. }
  296. CDmeParticleFunction *pFunc = ReadParticleClassFromKV<CDmeParticleFunction>( list[i], PARTICLE_CLIPBOARD_FUNCTIONS_STR );
  297. if ( pFunc )
  298. {
  299. PasteOperator( guard, pFunc );
  300. bRefreshAll = true;
  301. continue;
  302. }
  303. pDef = ReadParticleClassFromKV<CDmeParticleSystemDefinition>( list[i], PARTICLE_CLIPBOARD_DEF_BODY_STR );
  304. if ( pDef )
  305. {
  306. PasteDefinitionBody( guard, pDef );
  307. bRefreshAll = true;
  308. continue;
  309. }
  310. }
  311. guard.Release();
  312. if ( bRefreshAll )
  313. {
  314. m_pDoc->UpdateAllParticleSystems();
  315. }
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Called when buttons are clicked
  319. //-----------------------------------------------------------------------------
  320. void CParticleSystemDefinitionBrowser::OnCommand( const char *pCommand )
  321. {
  322. if ( !Q_stricmp( pCommand, "create" ) )
  323. {
  324. vgui::InputDialog *pInputDialog = new vgui::InputDialog( g_pPetTool->GetRootPanel(), "Enter Particle System Name", "Name:", "" );
  325. pInputDialog->SetSmallCaption( true );
  326. pInputDialog->SetMultiline( false );
  327. pInputDialog->AddActionSignalTarget( this );
  328. pInputDialog->DoModal( new KeyValues("create") );
  329. return;
  330. }
  331. if ( !Q_stricmp( pCommand, "copy" ) )
  332. {
  333. if ( m_pSystemGrid->GetSelectedSystemCount() == 1 )
  334. {
  335. CUtlString newName = m_pSystemGrid->GetSystemName(m_pSystemGrid->GetSelectedSystemId(0));
  336. newName += "_copy";
  337. vgui::InputDialog *pInputDialog = new vgui::InputDialog( g_pPetTool->GetRootPanel(), "Enter Duplicate System Name", "Name:", newName.Get() );
  338. pInputDialog->SetSmallCaption( true );
  339. pInputDialog->SetMultiline( false );
  340. pInputDialog->AddActionSignalTarget( this );
  341. pInputDialog->DoModal( new KeyValues("copy_one") );
  342. }
  343. else if ( m_pSystemGrid->GetSelectedSystemCount() > 1 )
  344. {
  345. vgui::InputDialog *pInputDialog = new vgui::InputDialog( g_pPetTool->GetRootPanel(), "Enter Suffix for New Systems", "Suffix:", "_copy" );
  346. pInputDialog->SetSmallCaption( true );
  347. pInputDialog->SetMultiline( false );
  348. pInputDialog->AddActionSignalTarget( this );
  349. pInputDialog->DoModal( new KeyValues("copy_many") );
  350. }
  351. return;
  352. }
  353. if ( !Q_stricmp( pCommand, "delete" ) )
  354. {
  355. DeleteParticleSystems();
  356. return;
  357. }
  358. if ( !Q_stricmp( pCommand, "Save" ) )
  359. {
  360. g_pPetTool->Save();
  361. return;
  362. }
  363. if ( !Q_stricmp( pCommand, "SaveAndTest" ) )
  364. {
  365. g_pPetTool->SaveAndTest();
  366. return;
  367. }
  368. BaseClass::OnCommand( pCommand );
  369. }
  370. //-----------------------------------------------------------------------------
  371. // Purpose:
  372. //-----------------------------------------------------------------------------
  373. void CParticleSystemDefinitionBrowser::UpdateParticleSystemList( bool bRetainSelection )
  374. {
  375. /////////////////////////
  376. // build a list of previously selected systems
  377. CUtlVector< CUtlString > selectedItems;
  378. if ( bRetainSelection )
  379. {
  380. int nCount = m_pSystemGrid->GetSelectedSystemCount();
  381. for ( int i = 0; i < nCount; ++i )
  382. {
  383. CDmeParticleSystemDefinition *pParticleSystem = GetSelectedParticleSystem( i );
  384. if ( pParticleSystem )
  385. {
  386. selectedItems.AddToTail( pParticleSystem->GetName() );
  387. }
  388. }
  389. }
  390. /////////////////////////
  391. // now go nuts
  392. const CDmrParticleSystemList particleSystemList = m_pDoc->GetParticleSystemDefinitionList();
  393. if ( !particleSystemList.IsValid() )
  394. {
  395. m_pSystemGrid->SetParticleList( CUtlVector<const char *>() );
  396. return;
  397. }
  398. CUtlVector<const char *> systemNames;
  399. CUtlVector<int> selectionIndicies;
  400. /////////////////////////
  401. // populate the new list
  402. for ( int i = 0; i < particleSystemList.Count(); ++i )
  403. {
  404. CDmeParticleSystemDefinition *pParticleSystem = particleSystemList[i];
  405. if ( !pParticleSystem )
  406. continue;
  407. systemNames.AddToTail( pParticleSystem->GetName() );
  408. // see if the system was previously selected
  409. for ( int s = 0; s < selectedItems.Count(); ++s )
  410. {
  411. if( !V_strcmp(pParticleSystem->GetName(), selectedItems[s]) )
  412. {
  413. selectionIndicies.AddToTail(i);
  414. }
  415. }
  416. }
  417. m_pSystemGrid->SetParticleList( systemNames );
  418. /////////////////////////
  419. // reselect any identified systems
  420. if ( bRetainSelection )
  421. {
  422. for ( int i = 0; i < selectionIndicies.Count(); ++i )
  423. {
  424. m_pSystemGrid->SelectId( selectionIndicies[i], true, false );
  425. }
  426. }
  427. }