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.

1453 lines
40 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose: Core Movie Maker UI API
  4. //
  5. //=============================================================================
  6. #include "pettool.h"
  7. #include "vgui_controls/Menu.h"
  8. #include "tier1/KeyValues.h"
  9. #include "vgui/IInput.h"
  10. #include "vgui/KeyCode.h"
  11. #include "vgui_controls/FileOpenDialog.h"
  12. #include "filesystem.h"
  13. #include "vgui/ilocalize.h"
  14. #include "dme_controls/elementpropertiestree.h"
  15. #include "tier0/icommandline.h"
  16. #include "materialsystem/imaterialsystem.h"
  17. #include "vguimatsurface/imatsystemsurface.h"
  18. #include "petdoc.h"
  19. #include "particlesystemdefinitionbrowser.h"
  20. #include "particlesystempropertiescontainer.h"
  21. #include "dme_controls/AttributeStringChoicePanel.h"
  22. #include "dme_controls/ParticleSystemPanel.h"
  23. #include "dme_controls/sheeteditorpanel.h"
  24. #include "datamodel/dmelementfactoryhelper.h"
  25. #include "matsys_controls/picker.h"
  26. #include "tier2/fileutils.h"
  27. #include "tier3/tier3.h"
  28. #include "tier3/mdlutils.h"
  29. #include "particles/particles.h"
  30. #include "dmserializers/idmserializers.h"
  31. #include "dme_controls/dmepanel.h"
  32. #include "vgui/ivgui.h"
  33. #include "engine/IVDebugOverlay.h"
  34. using namespace vgui;
  35. //-----------------------------------------------------------------------------
  36. // Interface to allow the particle system to call back into the game code
  37. //-----------------------------------------------------------------------------
  38. class CPetParticleSystemQuery : public CBaseAppSystem< IParticleSystemQuery >
  39. {
  40. public:
  41. CPetParticleSystemQuery() : m_pQuery( NULL ) {}
  42. virtual void LevelShutdown( ) { }
  43. virtual bool IsEditor( ) { return true; }
  44. // Inherited from IParticleSystemQuery
  45. virtual void GetLightingAtPoint( const Vector& vecOrigin, Color &cTint )
  46. {
  47. cTint.SetColor( 255, 255, 255, 255 );
  48. }
  49. virtual void TraceLine( const Vector& vecAbsStart,
  50. const Vector& vecAbsEnd, unsigned int mask,
  51. const IHandleEntity *ignore,
  52. int collisionGroup, CBaseTrace *ptr )
  53. {
  54. ptr->startpos = vecAbsStart;
  55. ptr->endpos = vecAbsEnd;
  56. ptr->fraction = 1.0f;
  57. ptr->allsolid = ptr->startsolid = false;
  58. }
  59. virtual bool IsPointInSolid( const Vector& vecPos, const int nContentsMask )
  60. {
  61. return false;
  62. }
  63. virtual bool MovePointInsideControllingObject( CParticleCollection *pParticles, void *pObject, Vector *pPnt )
  64. {
  65. return true;
  66. }
  67. virtual void GetRandomPointsOnControllingObjectHitBox( CParticleCollection *pParticles,
  68. int nControlPointNumber,
  69. int nNumPtsOut,
  70. float flBBoxScale,
  71. int nNumTrysToGetAPointInsideTheModel,
  72. Vector *pPntsOut,
  73. Vector vecDirectionalBias,
  74. Vector *pHitBoxRelativeCoordOut,
  75. int *pHitBoxIndexOut,
  76. int nDesiredHitbox,
  77. const char *pszHitboxSetName )
  78. {
  79. for ( int i=0; i < nNumPtsOut; i++ )
  80. {
  81. pPntsOut[i] = pParticles->GetControlPointAtCurrentTime(nControlPointNumber); // fallback if anything goes wrong
  82. if ( pHitBoxIndexOut )
  83. pHitBoxIndexOut[i] = 0;
  84. if ( pHitBoxRelativeCoordOut )
  85. pHitBoxRelativeCoordOut[i].Init();
  86. }
  87. }
  88. virtual void GetClosestControllingObjectHitBox( CParticleCollection *pParticles,
  89. int nControlPointNumber,
  90. int nNumPtsIn,
  91. float flBBoxScale,
  92. Vector *pPntsIn,
  93. Vector *pHitBoxRelativeCoordOut,
  94. int *pHitBoxIndexOut,
  95. int nDesiredHitbox,
  96. const char *pszHitboxSetName )
  97. {
  98. for ( int i=0; i < nNumPtsIn; i++ )
  99. {
  100. if ( pHitBoxIndexOut )
  101. pHitBoxIndexOut[i] = 0;
  102. if ( pHitBoxRelativeCoordOut )
  103. pHitBoxRelativeCoordOut[i].Init();
  104. }
  105. }
  106. virtual void TraceAgainstRayTraceEnv(
  107. int envnumber,
  108. const FourRays &rays, fltx4 TMin, fltx4 TMax,
  109. RayTracingResult *rslt_out, int32 skip_id ) const
  110. {
  111. rslt_out->HitDistance = Four_Ones;
  112. rslt_out->surface_normal.DuplicateVector( vec3_origin );
  113. }
  114. virtual int GetRayTraceEnvironmentFromName( const char *pszRtEnvName )
  115. {
  116. if ( !m_pQuery )
  117. return 0;
  118. return m_pQuery->GetRayTraceEnvironmentFromName( pszRtEnvName );
  119. }
  120. virtual int GetCollisionGroupFromName( const char *pszCollisionGroupName )
  121. {
  122. if ( !m_pQuery )
  123. return 0;
  124. return m_pQuery->GetCollisionGroupFromName( pszCollisionGroupName );
  125. }
  126. virtual int GetControllingObjectHitBoxInfo( CParticleCollection *pParticles,
  127. int nControlPointNumber,
  128. int nBufSize, // # of output slots available
  129. ModelHitBoxInfo_t *pHitBoxOutputBuffer,
  130. const char *pszHitboxSetName )
  131. {
  132. return 0;
  133. }
  134. virtual void GetControllingObjectOBBox( CParticleCollection *pParticles,
  135. int nControlPointNumber,
  136. Vector vecMin, Vector vecMax )
  137. {
  138. vecMin = vecMax = vec3_origin;
  139. }
  140. virtual Vector GetLocalPlayerPos()
  141. {
  142. return vec3_origin;
  143. }
  144. virtual Vector GetCurrentViewOrigin()
  145. {
  146. //FIXME : This should get the petool's window location.
  147. return vec3_origin;
  148. }
  149. //Not Yet Implemented
  150. virtual int GetActivityCount() { return 0; }
  151. virtual const char *GetActivityNameFromIndex( int nActivityIndex ) { return 0; }
  152. virtual int GetActivityNumber( void *pModel, const char *m_pszActivityName );
  153. virtual float GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale )
  154. {
  155. return 1.0f;
  156. }
  157. void SetChainQuery( IParticleSystemQuery *pQuery ) { m_pQuery = pQuery; }
  158. virtual void PreSimulate( ) { }
  159. virtual void PostSimulate( ) { }
  160. void DebugDrawLine( const Vector &origin, const Vector &target, int r, int g, int b, bool noDepthTest, float duration )
  161. {
  162. debugoverlay->AddLineOverlay( origin, target, r, g, b, noDepthTest, duration );
  163. }
  164. virtual void *GetModel( char const *pMdlName );
  165. virtual void DrawModel( void *pModel, const matrix3x4_t &DrawMatrix, CParticleCollection *pParticles, int nParticleNumber, int nBodyPart, int nSubModel,
  166. int nSkin, int nAnimationSequence = 0, float flAnimationRate = 30.0f, float r = 1.0f, float g = 1.0f, float b = 1.0f, float a = 1.0f );
  167. virtual void UpdateProjectedTexture( const int nParticleID, IMaterial *pMaterial, Vector &vOrigin, float flRadius, float flRotation, float r, float g, float b, float a, void *&pUserVar ) { }
  168. private:
  169. IParticleSystemQuery *m_pQuery;
  170. };
  171. static CPetParticleSystemQuery s_PetParticleSystemQuery;
  172. IParticleSystemQuery *g_pPetParticleSystemQuery = &s_PetParticleSystemQuery;
  173. static void SetBodygroup( studiohdr_t *pstudiohdr, int &body, int iGroup, int iValue )
  174. {
  175. if ( !pstudiohdr )
  176. {
  177. return;
  178. }
  179. if (iGroup >= pstudiohdr->numbodyparts)
  180. {
  181. return;
  182. }
  183. mstudiobodyparts_t *pbodypart = pstudiohdr->pBodypart( iGroup );
  184. if ( iValue >= pbodypart->nummodels )
  185. {
  186. return;
  187. }
  188. int iCurrent = ( body / pbodypart->base ) % pbodypart->nummodels;
  189. body = ( body - ( iCurrent * pbodypart->base ) + ( iValue * pbodypart->base ) );
  190. }
  191. void CPetParticleSystemQuery::DrawModel( void *pModel, const matrix3x4_t &DrawMatrix, CParticleCollection *pParticles, int nParticleNumber, int nBodyPart, int nSubModel,
  192. int nSkin, int nAnimationSequence, float flAnimationRate, float r, float g, float b, float a )
  193. {
  194. MDLHandle_t hMdl = ( MDLHandle_t ) pModel;
  195. CMDL myModel;
  196. myModel.SetMDL( hMdl );
  197. CMatRenderContextPtr pRenderContext( materials );
  198. // flashlights can't work in the model panel under queued mode (the state isn't ready yet, so causes a crash)
  199. pRenderContext->SetFlashlightMode( false );
  200. CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( hMdl ), g_pMDLCache );
  201. CMatRenderData< matrix3x4_t > rdBoneToWorld( pRenderContext, studioHdr.numbones() );
  202. myModel.m_Color = Color( FastFToC( r ), FastFToC( g ), FastFToC( b ), FastFToC( a ) );
  203. SetBodygroup( myModel.GetStudioHdr(), myModel.m_nBody, nBodyPart, nSubModel );
  204. myModel.m_nSkin = nSkin;
  205. myModel.m_nSequence = nAnimationSequence;
  206. myModel.m_flPlaybackRate = flAnimationRate;
  207. myModel.m_flTime = pParticles->m_flCurTime;
  208. myModel.SetUpBones( DrawMatrix, studioHdr.numbones(), rdBoneToWorld.Base() );
  209. myModel.Draw( DrawMatrix, rdBoneToWorld.Base(), STUDIORENDER_DRAW_NO_SHADOWS );
  210. //debugging
  211. //Vector vecFwd, vecRight, vecUp, vecOrigin;
  212. //MatrixVectors( DrawMatrix, &vecFwd, &vecRight, &vecUp );
  213. //vecOrigin = Vector ( DrawMatrix[0][3], DrawMatrix[1][3], DrawMatrix[2][3] );
  214. //debugoverlay->AddLineOverlay( vecOrigin, vecOrigin + 36 * vecFwd, 255, 0, 0, true, 0.1 );
  215. //debugoverlay->AddLineOverlay( vecOrigin, vecOrigin + 36 * vecUp, 0, 0, 255, true, 0.1 );
  216. //debugoverlay->AddLineOverlay( vecOrigin, vecOrigin + 36 * vecRight, 0, 255, 0, true, 0.1 );
  217. }
  218. void *CPetParticleSystemQuery::GetModel( char const *pMdlName )
  219. {
  220. CUtlString ModelName = "models/";
  221. ModelName += pMdlName;
  222. MDLHandle_t mdlHandle = g_pMDLCache->FindMDL( ModelName );
  223. return ( void * ) mdlHandle;
  224. }
  225. int CPetParticleSystemQuery::GetActivityNumber( void *pModel, const char *m_pszActivityName )
  226. {
  227. /*MDLHandle_t hMdl = ( MDLHandle_t ) pModel;
  228. CStudioHdr *pStudioHdr = new CStudioHdr( g_pMDLCache->GetStudioHdr( hMdl ), g_pMDLCache );
  229. if ( pStudioHdr->IsValid() )
  230. {
  231. int nActivityNum = LookupActivity( pStudioHdr, m_pszActivityName );
  232. int nAnimationNum = pStudioHdr->SelectWeightedSequence( nActivityNum, -1 );
  233. return nAnimationNum;
  234. }*/
  235. return -1;
  236. }
  237. //-----------------------------------------------------------------------------
  238. // Methods needed by scenedatabase. They have to live here instead of toolutils
  239. // because this is a DLL but toolutils is only a static library
  240. //-----------------------------------------------------------------------------
  241. USING_DMEPANEL_FACTORY( CParticleSystemPreviewPanel, DmeParticleSystemDefinition );
  242. USING_DMEPANEL_FACTORY( CParticleSystemDmePanel, DmeParticleSystemDefinition );
  243. const char *GetVGuiControlsModuleName()
  244. {
  245. return "PetTool";
  246. }
  247. //-----------------------------------------------------------------------------
  248. // Connect, disconnect
  249. //-----------------------------------------------------------------------------
  250. bool ConnectTools( CreateInterfaceFn factory )
  251. {
  252. // Attach to the dmserializers instance of the particle system
  253. return (materials != NULL) && (g_pMatSystemSurface != NULL) && (g_pMDLCache != NULL) && (studiorender != NULL) && (g_pMaterialSystemHardwareConfig != NULL);
  254. }
  255. void DisconnectTools( )
  256. {
  257. }
  258. //-----------------------------------------------------------------------------
  259. // Singleton
  260. //-----------------------------------------------------------------------------
  261. CPetTool *g_pPetTool = NULL;
  262. void CreateTools()
  263. {
  264. g_pPetTool = new CPetTool();
  265. }
  266. //-----------------------------------------------------------------------------
  267. // Constructor
  268. //-----------------------------------------------------------------------------
  269. CPetTool::CPetTool()
  270. {
  271. m_pMenuBar = NULL;
  272. m_pDoc = NULL;
  273. }
  274. //-----------------------------------------------------------------------------
  275. // Init, shutdown
  276. //-----------------------------------------------------------------------------
  277. bool CPetTool::Init( )
  278. {
  279. m_hCurrentParticleSystem = NULL;
  280. m_pDoc = NULL;
  281. m_RecentFiles.LoadFromRegistry( GetRegistryName() );
  282. // NOTE: This has to happen before BaseClass::Init
  283. g_pVGuiLocalize->AddFile( "resource/toolpet_%language%.txt" );
  284. if ( !BaseClass::Init( ) )
  285. return false;
  286. CreateInterfaceFn factory;
  287. enginetools->GetClientFactory( factory );
  288. IParticleSystemQuery *pQuery = (IParticleSystemQuery*)factory( PARTICLE_SYSTEM_QUERY_INTERFACE_VERSION, NULL );
  289. s_PetParticleSystemQuery.SetChainQuery( pQuery );
  290. g_pParticleSystemMgr->Init( g_pPetParticleSystemQuery, true );
  291. // tell particle mgr to add the default simulation + rendering ops
  292. g_pParticleSystemMgr->AddBuiltinSimulationOperators();
  293. g_pParticleSystemMgr->AddBuiltinRenderingOperators();
  294. // Create a directory for particles if it doesn't exist
  295. char pStartingDir[ MAX_PATH ];
  296. GetModSubdirectory( "particles", pStartingDir, sizeof(pStartingDir) );
  297. g_pFullFileSystem->CreateDirHierarchy( pStartingDir );
  298. return true;
  299. }
  300. void CPetTool::Shutdown()
  301. {
  302. m_RecentFiles.SaveToRegistry( GetRegistryName() );
  303. BaseClass::Shutdown();
  304. }
  305. //-----------------------------------------------------------------------------
  306. bool UTIL_IsDedicatedServer( void )
  307. {
  308. return false;
  309. }
  310. //-----------------------------------------------------------------------------
  311. // returns the document
  312. //-----------------------------------------------------------------------------
  313. CPetDoc *CPetTool::GetDocument()
  314. {
  315. return m_pDoc;
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Tool activation/deactivation
  319. //-----------------------------------------------------------------------------
  320. void CPetTool::OnToolActivate()
  321. {
  322. BaseClass::OnToolActivate();
  323. }
  324. void CPetTool::OnToolDeactivate()
  325. {
  326. BaseClass::OnToolDeactivate();
  327. }
  328. //-----------------------------------------------------------------------------
  329. // Used to hook DME VMF entities into the render lists
  330. //-----------------------------------------------------------------------------
  331. void CPetTool::Think( bool finalTick )
  332. {
  333. BaseClass::Think( finalTick );
  334. if ( IsActiveTool() )
  335. {
  336. // Force resolve calls to happen
  337. // FIXME: Shouldn't this not have to happen here?
  338. CUtlVector< IDmeOperator* > operators;
  339. g_pDmElementFramework->SetOperators( operators );
  340. g_pDmElementFramework->Operate( true );
  341. g_pDmElementFramework->BeginEdit();
  342. }
  343. }
  344. //-----------------------------------------------------------------------------
  345. // Derived classes can implement this to get a new scheme to be applied to this tool
  346. //-----------------------------------------------------------------------------
  347. vgui::HScheme CPetTool::GetToolScheme()
  348. {
  349. return vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", "BoxRocket" );
  350. }
  351. //-----------------------------------------------------------------------------
  352. //
  353. // The View menu
  354. //
  355. //-----------------------------------------------------------------------------
  356. class CPetViewMenuButton : public CToolMenuButton
  357. {
  358. DECLARE_CLASS_SIMPLE( CPetViewMenuButton, CToolMenuButton );
  359. public:
  360. CPetViewMenuButton( CPetTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget );
  361. virtual void OnShowMenu(vgui::Menu *menu);
  362. private:
  363. CPetTool *m_pTool;
  364. };
  365. CPetViewMenuButton::CPetViewMenuButton( CPetTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget )
  366. : BaseClass( parent, panelName, text, pActionSignalTarget )
  367. {
  368. m_pTool = parent;
  369. AddCheckableMenuItem( "properties", "#PetProperties", new KeyValues( "OnToggleProperties" ), pActionSignalTarget );
  370. AddCheckableMenuItem( "browser", "#PetParticleSystemBrowser", new KeyValues( "OnToggleParticleSystemBrowser" ), pActionSignalTarget );
  371. AddCheckableMenuItem( "particlepreview", "#PetParticlePreview", new KeyValues( "OnToggleParticlePreview" ), pActionSignalTarget );
  372. // AddCheckableMenuItem( "sheeteditor", "#PetSheetEditor", new KeyValues( "OnToggleSheetEditor" ), pActionSignalTarget );
  373. AddSeparator();
  374. AddMenuItem( "defaultlayout", "#PetViewDefault", new KeyValues( "OnDefaultLayout" ), pActionSignalTarget );
  375. SetMenu(m_pMenu);
  376. }
  377. void CPetViewMenuButton::OnShowMenu(vgui::Menu *menu)
  378. {
  379. BaseClass::OnShowMenu( menu );
  380. // Update the menu
  381. int id;
  382. CPetDoc *pDoc = m_pTool->GetDocument();
  383. if ( pDoc )
  384. {
  385. id = m_Items.Find( "properties" );
  386. m_pMenu->SetItemEnabled( id, true );
  387. Panel *p;
  388. p = m_pTool->GetProperties();
  389. Assert( p );
  390. m_pMenu->SetMenuItemChecked( id, ( p && p->GetParent() ) ? true : false );
  391. id = m_Items.Find( "browser" );
  392. m_pMenu->SetItemEnabled( id, true );
  393. p = m_pTool->GetParticleSystemDefinitionBrowser();
  394. Assert( p );
  395. m_pMenu->SetMenuItemChecked( id, ( p && p->GetParent() ) ? true : false );
  396. id = m_Items.Find( "particlepreview" );
  397. m_pMenu->SetItemEnabled( id, true );
  398. p = m_pTool->GetParticlePreview();
  399. Assert( p );
  400. m_pMenu->SetMenuItemChecked( id, ( p && p->GetParent() ) ? true : false );
  401. /*
  402. id = m_Items.Find( "sheeteditor" );
  403. m_pMenu->SetItemEnabled( id, true );
  404. p = m_pTool->GetSheetEditor();
  405. Assert( p );
  406. m_pMenu->SetMenuItemChecked( id, ( p && p->GetParent() ) ? true : false );
  407. */
  408. }
  409. else
  410. {
  411. id = m_Items.Find( "properties" );
  412. m_pMenu->SetItemEnabled( id, false );
  413. id = m_Items.Find( "browser" );
  414. m_pMenu->SetItemEnabled( id, false );
  415. id = m_Items.Find( "particlepreview" );
  416. m_pMenu->SetItemEnabled( id, false );
  417. /*
  418. id = m_Items.Find( "sheeteditor" );
  419. m_pMenu->SetItemEnabled( id, false );
  420. */
  421. }
  422. }
  423. //-----------------------------------------------------------------------------
  424. //
  425. // The Tool menu
  426. //
  427. //-----------------------------------------------------------------------------
  428. class CPetToolMenuButton : public CToolMenuButton
  429. {
  430. DECLARE_CLASS_SIMPLE( CPetToolMenuButton, CToolMenuButton );
  431. public:
  432. CPetToolMenuButton( CPetTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget );
  433. virtual void OnShowMenu(vgui::Menu *menu);
  434. private:
  435. CPetTool *m_pTool;
  436. };
  437. CPetToolMenuButton::CPetToolMenuButton( CPetTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget )
  438. : BaseClass( parent, panelName, text, pActionSignalTarget )
  439. {
  440. m_pTool = parent;
  441. SetMenu(m_pMenu);
  442. }
  443. void CPetToolMenuButton::OnShowMenu(vgui::Menu *menu)
  444. {
  445. BaseClass::OnShowMenu( menu );
  446. }
  447. //-----------------------------------------------------------------------------
  448. // Initializes the menu bar
  449. //-----------------------------------------------------------------------------
  450. vgui::MenuBar *CPetTool::CreateMenuBar( CBaseToolSystem *pParent )
  451. {
  452. m_pMenuBar = new CToolFileMenuBar( pParent, "Main Menu Bar" );
  453. // Sets info in the menu bar
  454. char title[ 64 ];
  455. ComputeMenuBarTitle( title, sizeof( title ) );
  456. m_pMenuBar->SetInfo( title );
  457. m_pMenuBar->SetToolName( GetToolName() );
  458. // Add menu buttons
  459. CToolMenuButton *pFileButton = CreateToolFileMenuButton( m_pMenuBar, "File", "&File", GetActionTarget(), this );
  460. CToolMenuButton *pEditButton = CreateToolEditMenuButton( this, "Edit", "&Edit", GetActionTarget() );
  461. CPetToolMenuButton *pToolButton = new CPetToolMenuButton( this, "Pet", "&Pet", GetActionTarget() );
  462. CPetViewMenuButton *pViewButton = new CPetViewMenuButton( this, "View", "&View", GetActionTarget() );
  463. CToolMenuButton *pSwitchButton = CreateToolSwitchMenuButton( m_pMenuBar, "Switcher", "&Tools", GetActionTarget() );
  464. pEditButton->AddMenuItem( "copySystem", "Copy Systems", new KeyValues( "OnCopySystems" ), GetActionTarget(), NULL );
  465. pEditButton->AddMenuItem( "copyFunctions", "Copy Functions", new KeyValues( "OnCopyFunctions" ), GetActionTarget() );
  466. pEditButton->AddMenuItem( "paste", "#BxEditPaste", new KeyValues( "OnPaste" ), GetActionTarget(), NULL, "edit_paste" );
  467. pEditButton->MoveMenuItem( pEditButton->FindMenuItem( "paste" ), pEditButton->FindMenuItem( "editkeybindings" ) );
  468. pEditButton->MoveMenuItem( pEditButton->FindMenuItem( "copySystem" ), pEditButton->FindMenuItem( "paste" ) );
  469. pEditButton->MoveMenuItem( pEditButton->FindMenuItem( "copyFunctions" ), pEditButton->FindMenuItem( "paste" ) );
  470. pEditButton->AddSeparatorAfterItem( "paste" );
  471. m_pMenuBar->AddButton( pFileButton );
  472. m_pMenuBar->AddButton( pEditButton );
  473. m_pMenuBar->AddButton( pToolButton );
  474. m_pMenuBar->AddButton( pViewButton );
  475. m_pMenuBar->AddButton( pSwitchButton );
  476. return m_pMenuBar;
  477. }
  478. //-----------------------------------------------------------------------------
  479. // Updates the menu bar based on the current file
  480. //-----------------------------------------------------------------------------
  481. void CPetTool::UpdateMenuBar( )
  482. {
  483. if ( !m_pDoc )
  484. {
  485. m_pMenuBar->SetFileName( "#PetNoFile" );
  486. return;
  487. }
  488. const char *pFile = m_pDoc->GetFileName();
  489. if ( !pFile[0] )
  490. {
  491. m_pMenuBar->SetFileName( "#PetNoFile" );
  492. return;
  493. }
  494. if ( m_pDoc->IsDirty() )
  495. {
  496. char sz[ 512 ];
  497. Q_snprintf( sz, sizeof( sz ), "* %s", pFile );
  498. m_pMenuBar->SetFileName( sz );
  499. }
  500. else
  501. {
  502. m_pMenuBar->SetFileName( pFile );
  503. }
  504. }
  505. //-----------------------------------------------------------------------------
  506. // Gets at tool windows
  507. //-----------------------------------------------------------------------------
  508. CParticleSystemPropertiesContainer *CPetTool::GetProperties()
  509. {
  510. return m_hProperties.Get();
  511. }
  512. CParticleSystemDefinitionBrowser *CPetTool::GetParticleSystemDefinitionBrowser()
  513. {
  514. return m_hParticleSystemDefinitionBrowser.Get();
  515. }
  516. CParticleSystemPreviewPanel *CPetTool::GetParticlePreview()
  517. {
  518. return m_hParticlePreview.Get();
  519. }
  520. /*
  521. CSheetEditorPanel *CPetTool::GetSheetEditor()
  522. {
  523. return m_hSheetEditorPanel.Get();
  524. }
  525. */
  526. //-----------------------------------------------------------------------------
  527. // paste
  528. //-----------------------------------------------------------------------------
  529. void CPetTool::OnCopySystems()
  530. {
  531. Panel *pDefBrowser = FindChildByName( "ParticleSystemDefinitionBrowser", true );
  532. if ( pDefBrowser )
  533. {
  534. vgui::ipanel()->SendMessage( pDefBrowser->GetVPanel(), new KeyValues( "OnCopy" ), GetVPanel() );
  535. }
  536. }
  537. void CPetTool::OnCopyFunctions()
  538. {
  539. Panel *pFuncBrowser = FindChildByName( "FunctionBrowser", true );
  540. if ( pFuncBrowser )
  541. {
  542. vgui::ipanel()->SendMessage( pFuncBrowser->GetVPanel(), new KeyValues( "OnCopy" ), GetVPanel() );
  543. }
  544. }
  545. void CPetTool::OnPaste()
  546. {
  547. GetParticleSystemDefinitionBrowser()->PasteFromClipboard();
  548. }
  549. void CPetTool::OnRequestPaste()
  550. {
  551. OnPaste();
  552. }
  553. //-----------------------------------------------------------------------------
  554. // Sets/gets the current particle system
  555. //-----------------------------------------------------------------------------
  556. void CPetTool::SetCurrentParticleSystem( CDmeParticleSystemDefinition *pParticleSystem, bool bForceBrowserSelection )
  557. {
  558. if ( !m_pDoc )
  559. return;
  560. if ( pParticleSystem && m_hCurrentParticleSystem.Get() == pParticleSystem )
  561. return;
  562. m_hCurrentParticleSystem = pParticleSystem;
  563. if ( bForceBrowserSelection && m_hParticleSystemDefinitionBrowser.Get() )
  564. {
  565. m_hParticleSystemDefinitionBrowser->UpdateParticleSystemList( false );
  566. m_hParticleSystemDefinitionBrowser->SelectParticleSystem( pParticleSystem );
  567. }
  568. if ( m_hParticlePreview.Get() )
  569. {
  570. m_hParticlePreview->SetParticleSystem( pParticleSystem, bForceBrowserSelection );
  571. }
  572. if ( m_hProperties.Get() )
  573. {
  574. m_hProperties->SetParticleSystem( m_hCurrentParticleSystem );
  575. }
  576. /*
  577. if ( m_hSheetEditorPanel.Get() )
  578. {
  579. m_hSheetEditorPanel->SetParticleSystem( m_hCurrentParticleSystem );
  580. }
  581. */
  582. }
  583. CDmeParticleSystemDefinition* CPetTool::GetCurrentParticleSystem( void )
  584. {
  585. return m_hCurrentParticleSystem;
  586. }
  587. //-----------------------------------------------------------------------------
  588. // Destroys all tool windows
  589. //-----------------------------------------------------------------------------
  590. void CPetTool::DestroyToolContainers()
  591. {
  592. int c = ToolWindow::GetToolWindowCount();
  593. for ( int i = c - 1; i >= 0 ; --i )
  594. {
  595. ToolWindow *kill = ToolWindow::GetToolWindow( i );
  596. delete kill;
  597. }
  598. }
  599. //-----------------------------------------------------------------------------
  600. // Sets up the default layout
  601. //-----------------------------------------------------------------------------
  602. void CPetTool::OnDefaultLayout()
  603. {
  604. int y = m_pMenuBar->GetTall();
  605. int usew, useh;
  606. GetSize( usew, useh );
  607. DestroyToolContainers();
  608. Assert( ToolWindow::GetToolWindowCount() == 0 );
  609. CParticleSystemPropertiesContainer *pProperties = GetProperties();
  610. CParticleSystemDefinitionBrowser *pParticleSystemBrowser = GetParticleSystemDefinitionBrowser();
  611. CParticleSystemPreviewPanel *pPreviewer = GetParticlePreview();
  612. //CSheetEditorPanel *pSheetEditor = GetSheetEditor();
  613. // Need three containers
  614. ToolWindow *pPropertyWindow = m_ToolWindowFactory.InstanceToolWindow( GetClientArea(), false, pProperties, "#PetProperties", false );
  615. ToolWindow *pBrowserWindow = m_ToolWindowFactory.InstanceToolWindow( GetClientArea(), false, pParticleSystemBrowser, "#PetParticleSystemBrowser", false );
  616. ToolWindow *pPreviewWindow = m_ToolWindowFactory.InstanceToolWindow( GetClientArea(), false, pPreviewer, "#PetPreviewer", false );
  617. //pPropertyWindow->AddPage( pSheetEditor, "#PetSheetEditor", false );
  618. int halfScreen = usew / 2;
  619. int bottom = useh - y;
  620. int sy = (bottom - y) / 2;
  621. SetMiniViewportBounds( halfScreen, y, halfScreen, sy - y );
  622. pPreviewWindow->SetBounds( halfScreen, sy, halfScreen, bottom - sy );
  623. pBrowserWindow->SetBounds( 0, y, halfScreen, sy - y );
  624. pPropertyWindow->SetBounds( 0, sy, halfScreen, bottom - sy );
  625. }
  626. void CPetTool::OnToggleProperties()
  627. {
  628. if ( m_hProperties.Get() )
  629. {
  630. ToggleToolWindow( m_hProperties.Get(), "#PetProperties" );
  631. }
  632. }
  633. void CPetTool::OnToggleParticleSystemBrowser()
  634. {
  635. if ( m_hParticleSystemDefinitionBrowser.Get() )
  636. {
  637. ToggleToolWindow( m_hParticleSystemDefinitionBrowser.Get(), "#PetParticleSystemBrowser" );
  638. }
  639. }
  640. void CPetTool::OnToggleParticlePreview()
  641. {
  642. if ( m_hParticlePreview.Get() )
  643. {
  644. ToggleToolWindow( m_hParticlePreview.Get(), "#PetPreviewer" );
  645. }
  646. }
  647. /*
  648. void CPetTool::OnToggleSheetEditor()
  649. {
  650. if ( m_hSheetEditorPanel.Get() )
  651. {
  652. ToggleToolWindow( m_hSheetEditorPanel.Get(), "#PetSheetEditor" );
  653. }
  654. }
  655. */
  656. //-----------------------------------------------------------------------------
  657. // Creates
  658. //-----------------------------------------------------------------------------
  659. void CPetTool::CreateTools( CPetDoc *doc )
  660. {
  661. if ( !m_hProperties.Get() )
  662. {
  663. m_hProperties = new CParticleSystemPropertiesContainer( m_pDoc, this );
  664. m_hProperties->AddActionSignalTarget(this);
  665. }
  666. if ( !m_hParticleSystemDefinitionBrowser.Get() )
  667. {
  668. m_hParticleSystemDefinitionBrowser = new CParticleSystemDefinitionBrowser( m_pDoc, this, "ParticleSystemDefinitionBrowser" );
  669. }
  670. if ( !m_hParticlePreview.Get() )
  671. {
  672. m_hParticlePreview = new CParticleSystemPreviewPanel( NULL, "Particle System Preview" );
  673. }
  674. /*
  675. if ( !m_hSheetEditorPanel.Get() )
  676. {
  677. m_hSheetEditorPanel = new CSheetEditorPanel( NULL, "Sheet Editor" );
  678. }
  679. */
  680. RegisterToolWindow( m_hProperties );
  681. RegisterToolWindow( m_hParticleSystemDefinitionBrowser );
  682. RegisterToolWindow( m_hParticlePreview );
  683. // RegisterToolWindow( m_hSheetEditorPanel );
  684. }
  685. //-----------------------------------------------------------------------------
  686. // Initializes the tools
  687. //-----------------------------------------------------------------------------
  688. void CPetTool::InitTools()
  689. {
  690. // FIXME: There are no tool windows here; how should this work?
  691. // These panels are saved
  692. windowposmgr->RegisterPanel( "properties", m_hProperties, false );
  693. windowposmgr->RegisterPanel( "particlesystemdefinitionbrowser", m_hParticleSystemDefinitionBrowser, false );
  694. windowposmgr->RegisterPanel( "previewpanel", m_hParticlePreview, false );
  695. // windowposmgr->RegisterPanel( "sheeteditor", m_hSheetEditorPanel, false );
  696. if ( !windowposmgr->LoadPositions( "cfg/pet.txt", this, &m_ToolWindowFactory, "Pet" ) )
  697. {
  698. OnDefaultLayout();
  699. }
  700. }
  701. void CPetTool::DestroyTools()
  702. {
  703. if ( m_hParticlePreview.Get() )
  704. {
  705. m_hParticlePreview->ClearParticleSystemLock();
  706. }
  707. SetCurrentParticleSystem( NULL );
  708. int c = ToolWindow::GetToolWindowCount();
  709. for ( int i = c - 1; i >= 0 ; --i )
  710. {
  711. ToolWindow *kill = ToolWindow::GetToolWindow( i );
  712. delete kill;
  713. }
  714. UnregisterAllToolWindows();
  715. if ( m_hProperties.Get() )
  716. {
  717. windowposmgr->UnregisterPanel( m_hProperties.Get() );
  718. delete m_hProperties.Get();
  719. m_hProperties = NULL;
  720. }
  721. if ( m_hParticleSystemDefinitionBrowser.Get() )
  722. {
  723. windowposmgr->UnregisterPanel( m_hParticleSystemDefinitionBrowser.Get() );
  724. delete m_hParticleSystemDefinitionBrowser.Get();
  725. m_hParticleSystemDefinitionBrowser = NULL;
  726. }
  727. if ( m_hParticlePreview.Get() )
  728. {
  729. windowposmgr->UnregisterPanel( m_hParticlePreview.Get() );
  730. delete m_hParticlePreview.Get();
  731. m_hParticlePreview = NULL;
  732. }
  733. /*
  734. if ( m_hSheetEditorPanel.Get() )
  735. {
  736. windowposmgr->UnregisterPanel( m_hSheetEditorPanel.Get() );
  737. delete m_hSheetEditorPanel.Get();
  738. m_hSheetEditorPanel = NULL;
  739. }
  740. */
  741. }
  742. void CPetTool::ShowToolWindow( Panel *tool, char const *toolName, bool visible )
  743. {
  744. Assert( tool );
  745. if ( tool->GetParent() == NULL && visible )
  746. {
  747. m_ToolWindowFactory.InstanceToolWindow( this, false, tool, toolName, false );
  748. }
  749. else if ( !visible )
  750. {
  751. ToolWindow *tw = dynamic_cast< ToolWindow * >( tool->GetParent()->GetParent() );
  752. Assert( tw );
  753. tw->RemovePage( tool );
  754. }
  755. }
  756. void CPetTool::ToggleToolWindow( Panel *tool, char const *toolName )
  757. {
  758. Assert( tool );
  759. if ( tool->GetParent() == NULL )
  760. {
  761. ShowToolWindow( tool, toolName, true );
  762. }
  763. else
  764. {
  765. ShowToolWindow( tool, toolName, false );
  766. }
  767. }
  768. //-----------------------------------------------------------------------------
  769. // Creates the action menu
  770. //-----------------------------------------------------------------------------
  771. vgui::Menu *CPetTool::CreateActionMenu( vgui::Panel *pParent )
  772. {
  773. vgui::Menu *pActionMenu = new Menu( pParent, "ActionMenu" );
  774. pActionMenu->AddMenuItem( "#ToolHide", new KeyValues( "Command", "command", "HideActionMenu" ), GetActionTarget() );
  775. return pActionMenu;
  776. }
  777. //-----------------------------------------------------------------------------
  778. // Inherited from IFileMenuCallbacks
  779. //-----------------------------------------------------------------------------
  780. int CPetTool::GetFileMenuItemsEnabled( )
  781. {
  782. int nFlags = FILE_ALL;
  783. if ( m_RecentFiles.IsEmpty() )
  784. {
  785. nFlags &= ~FILE_RECENT;
  786. }
  787. return nFlags;
  788. }
  789. void CPetTool::AddRecentFilesToMenu( vgui::Menu *pMenu )
  790. {
  791. m_RecentFiles.AddToMenu( pMenu, GetActionTarget(), "OnRecent" );
  792. }
  793. bool CPetTool::GetPerforceFileName( char *pFileName, int nMaxLen )
  794. {
  795. if ( !m_pDoc )
  796. return false;
  797. Q_strncpy( pFileName, m_pDoc->GetFileName(), nMaxLen );
  798. return pFileName[0] != 0;
  799. }
  800. //-----------------------------------------------------------------------------
  801. // Purpose:
  802. // Input : -
  803. //-----------------------------------------------------------------------------
  804. void CPetTool::OnExit()
  805. {
  806. windowposmgr->SavePositions( "cfg/pet.txt", "Pet" );
  807. enginetools->Command( "quit\n" );
  808. }
  809. //-----------------------------------------------------------------------------
  810. // Handle commands from the action menu and other menus
  811. //-----------------------------------------------------------------------------
  812. void CPetTool::OnCommand( const char *cmd )
  813. {
  814. if ( !V_stricmp( cmd, "HideActionMenu" ) )
  815. {
  816. if ( GetActionMenu() )
  817. {
  818. GetActionMenu()->SetVisible( false );
  819. }
  820. }
  821. else if ( const char *pSuffix = StringAfterPrefix( cmd, "OnRecent" ) )
  822. {
  823. int idx = Q_atoi( pSuffix );
  824. OpenFileFromHistory( idx );
  825. }
  826. else if ( const char *pSuffix = StringAfterPrefix( cmd, "OnTool" ) )
  827. {
  828. int idx = Q_atoi( pSuffix );
  829. enginetools->SwitchToTool( idx );
  830. }
  831. else if ( !V_stricmp( cmd, "OnUndo" ) )
  832. {
  833. OnUndo();
  834. }
  835. else if ( !V_stricmp( cmd, "OnRedo" ) )
  836. {
  837. OnRedo();
  838. }
  839. else if ( !V_stricmp( cmd, "OnDescribeUndo" ) )
  840. {
  841. OnDescribeUndo();
  842. }
  843. else
  844. {
  845. BaseClass::OnCommand( cmd );
  846. }
  847. }
  848. //-----------------------------------------------------------------------------
  849. // Command handlers
  850. //-----------------------------------------------------------------------------
  851. void CPetTool::PerformNew()
  852. {
  853. OnCloseNoSave();
  854. NewDocument();
  855. }
  856. void CPetTool::OnNew()
  857. {
  858. if ( m_pDoc && m_pDoc->IsDirty() )
  859. {
  860. SaveFile( m_pDoc->GetFileName(), PET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY,
  861. new KeyValues( "OnNew" ) );
  862. return;
  863. }
  864. PerformNew();
  865. }
  866. //-----------------------------------------------------------------------------
  867. // Called when the File->Open menu is selected
  868. //-----------------------------------------------------------------------------
  869. void CPetTool::OnOpen( )
  870. {
  871. int nFlags = 0;
  872. const char *pSaveFileName = NULL;
  873. if ( m_pDoc && m_pDoc->IsDirty() )
  874. {
  875. nFlags = FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY;
  876. pSaveFileName = m_pDoc->GetFileName();
  877. }
  878. OpenFile( PET_FILE_FORMAT, pSaveFileName, PET_FILE_FORMAT, nFlags );
  879. }
  880. bool CPetTool::OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  881. {
  882. OnCloseNoSave();
  883. if ( !LoadDocument( pFileName ) )
  884. return false;
  885. m_RecentFiles.Add( pFileName, pFileFormat );
  886. m_RecentFiles.SaveToRegistry( GetRegistryName() );
  887. UpdateMenuBar();
  888. return true;
  889. }
  890. void CPetTool::Save()
  891. {
  892. if ( m_pDoc )
  893. {
  894. SaveFile( m_pDoc->GetFileName(), PET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS );
  895. }
  896. }
  897. void CPetTool::OnSaveAs()
  898. {
  899. if ( m_pDoc )
  900. {
  901. SaveFile( NULL, PET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS );
  902. }
  903. }
  904. void CPetTool::OnRestartLevel()
  905. {
  906. enginetools->Command( "restart" );
  907. enginetools->Execute();
  908. }
  909. void CPetTool::SaveAndTest()
  910. {
  911. if ( m_pDoc && m_pDoc->IsDirty() )
  912. {
  913. SaveFile( m_pDoc->GetFileName(), PET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS,
  914. new KeyValues( "RestartLevel" ) );
  915. }
  916. else
  917. {
  918. OnRestartLevel();
  919. }
  920. }
  921. bool CPetTool::OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  922. {
  923. if ( !m_pDoc )
  924. return true;
  925. m_pDoc->SetFileName( pFileName );
  926. m_pDoc->SaveToFile( );
  927. m_RecentFiles.Add( pFileName, pFileFormat );
  928. m_RecentFiles.SaveToRegistry( GetRegistryName() );
  929. UpdateMenuBar();
  930. return true;
  931. }
  932. void CPetTool::OnClose()
  933. {
  934. if ( m_pDoc && m_pDoc->IsDirty() )
  935. {
  936. SaveFile( m_pDoc->GetFileName(), PET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY,
  937. new KeyValues( "OnClose" ) );
  938. return;
  939. }
  940. OnCloseNoSave();
  941. }
  942. void CPetTool::OnCloseNoSave()
  943. {
  944. DestroyTools();
  945. if ( m_pDoc )
  946. {
  947. CAppNotifyScopeGuard sg( "CPetTool::OnCloseNoSave", NOTIFY_CHANGE_OTHER );
  948. delete m_pDoc;
  949. m_pDoc = NULL;
  950. if ( m_hProperties )
  951. {
  952. m_hProperties->SetParticleSystem( NULL );
  953. }
  954. }
  955. UpdateMenuBar( );
  956. }
  957. void CPetTool::OnMarkNotDirty()
  958. {
  959. if ( m_pDoc )
  960. {
  961. m_pDoc->SetDirty( false );
  962. }
  963. }
  964. //-----------------------------------------------------------------------------
  965. // Open a specific file
  966. //-----------------------------------------------------------------------------
  967. void CPetTool::OpenSpecificFile( const char *pFileName )
  968. {
  969. int nFlags = 0;
  970. const char *pSaveFileName = NULL;
  971. if ( m_pDoc )
  972. {
  973. // File is already open
  974. if ( !Q_stricmp( m_pDoc->GetFileName(), pFileName ) )
  975. return;
  976. if ( m_pDoc->IsDirty() )
  977. {
  978. nFlags = FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY;
  979. pSaveFileName = m_pDoc->GetFileName();
  980. }
  981. else
  982. {
  983. OnCloseNoSave();
  984. }
  985. }
  986. OpenFile( pFileName, PET_FILE_FORMAT, pSaveFileName, PET_FILE_FORMAT, nFlags );
  987. }
  988. //-----------------------------------------------------------------------------
  989. // Show the save document query dialog
  990. //-----------------------------------------------------------------------------
  991. void CPetTool::OpenFileFromHistory( int slot )
  992. {
  993. const char *pFileName = m_RecentFiles.GetFile( slot );
  994. if ( !pFileName )
  995. return;
  996. OpenSpecificFile( pFileName );
  997. }
  998. //-----------------------------------------------------------------------------
  999. // Derived classes can implement this to get notified when files are saved/loaded
  1000. //-----------------------------------------------------------------------------
  1001. void CPetTool::OnFileOperationCompleted( const char *pFileType, bool bWroteFile, vgui::FileOpenStateMachine::CompletionState_t state, KeyValues *pContextKeyValues )
  1002. {
  1003. if ( bWroteFile )
  1004. {
  1005. OnMarkNotDirty();
  1006. }
  1007. if ( !pContextKeyValues )
  1008. return;
  1009. if ( state != FileOpenStateMachine::SUCCESSFUL )
  1010. return;
  1011. if ( !Q_stricmp( pContextKeyValues->GetName(), "OnNew" ) )
  1012. {
  1013. PerformNew();
  1014. return;
  1015. }
  1016. if ( !Q_stricmp( pContextKeyValues->GetName(), "OnClose" ) )
  1017. {
  1018. OnCloseNoSave();
  1019. return;
  1020. }
  1021. if ( !Q_stricmp( pContextKeyValues->GetName(), "OnQuit" ) )
  1022. {
  1023. OnCloseNoSave();
  1024. vgui::ivgui()->PostMessage( GetVPanel(), new KeyValues( "OnExit" ), 0 );
  1025. return;
  1026. }
  1027. if ( !Q_stricmp( pContextKeyValues->GetName(), "OnUnload" ) )
  1028. {
  1029. enginetools->Command( "toolunload pet -nosave\n" );
  1030. return;
  1031. }
  1032. if ( !Q_stricmp( pContextKeyValues->GetName(), "RestartLevel" ) )
  1033. {
  1034. OnRestartLevel();
  1035. return;
  1036. }
  1037. }
  1038. //-----------------------------------------------------------------------------
  1039. // Show the File browser dialog
  1040. //-----------------------------------------------------------------------------
  1041. void CPetTool::SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues )
  1042. {
  1043. char pStartingDir[ MAX_PATH ];
  1044. GetModSubdirectory( "particles", pStartingDir, sizeof(pStartingDir) );
  1045. // Open a bsp file to create a new commentary file
  1046. pDialog->SetTitle( "Choose Particle Configuration File", true );
  1047. pDialog->SetStartDirectoryContext( "pet_session", pStartingDir );
  1048. pDialog->AddFilter( "*.pcf", "Particle Configuration File (*.pcf)", true );
  1049. }
  1050. //-----------------------------------------------------------------------------
  1051. // Can we quit?
  1052. //-----------------------------------------------------------------------------
  1053. bool CPetTool::CanQuit( const char *pExitMsg )
  1054. {
  1055. if ( m_pDoc && m_pDoc->IsDirty() )
  1056. {
  1057. // Show Save changes Yes/No/Cancel and re-quit if hit yes/no
  1058. SaveFile( m_pDoc->GetFileName(), PET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY, new KeyValues( pExitMsg ) );
  1059. return false;
  1060. }
  1061. return true;
  1062. }
  1063. //-----------------------------------------------------------------------------
  1064. // Various command handlers related to the Edit menu
  1065. //-----------------------------------------------------------------------------
  1066. void CPetTool::OnUndo()
  1067. {
  1068. CDisableUndoScopeGuard guard;
  1069. g_pDataModel->Undo();
  1070. }
  1071. void CPetTool::OnRedo()
  1072. {
  1073. CDisableUndoScopeGuard guard;
  1074. g_pDataModel->Redo();
  1075. }
  1076. void CPetTool::OnDescribeUndo()
  1077. {
  1078. CUtlVector< UndoInfo_t > list;
  1079. g_pDataModel->GetUndoInfo( list );
  1080. Msg( "%i operations in stack\n", list.Count() );
  1081. for ( int i = list.Count() - 1; i >= 0; --i )
  1082. {
  1083. UndoInfo_t& entry = list[ i ];
  1084. if ( entry.terminator )
  1085. {
  1086. Msg( "[ '%s' ] - %i operations\n", entry.undo, entry.numoperations );
  1087. }
  1088. Msg( " +%s\n", entry.desc );
  1089. }
  1090. }
  1091. //-----------------------------------------------------------------------------
  1092. // Background
  1093. //-----------------------------------------------------------------------------
  1094. const char *CPetTool::GetLogoTextureName()
  1095. {
  1096. return NULL;
  1097. }
  1098. //-----------------------------------------------------------------------------
  1099. // Inherited from IPetDocCallback
  1100. //-----------------------------------------------------------------------------
  1101. void CPetTool::OnDocChanged( const char *pReason, int nNotifySource, int nNotifyFlags )
  1102. {
  1103. if ( nNotifyFlags & NOTIFY_CHANGE_MASK )
  1104. {
  1105. // force a resolve so the local particle manager stays in sync
  1106. g_pDmElementFramework->Operate( true );
  1107. g_pDmElementFramework->BeginEdit();
  1108. }
  1109. CDmeParticleSystemDefinition *pParticleSystem = GetCurrentParticleSystem();
  1110. if ( m_pDoc && GetParticlePreview() && pParticleSystem )
  1111. {
  1112. m_pDoc->UpdateParticleDefinition( pParticleSystem );
  1113. }
  1114. if ( nNotifyFlags & NOTIFY_CHANGE_TOPOLOGICAL )
  1115. {
  1116. if ( GetParticleSystemDefinitionBrowser() )
  1117. {
  1118. // only retain selection if we didn't create/delete a system
  1119. bool bRetainSelection = !(nNotifyFlags & NOTIFY_FLAG_PARTICLESYS_ADDED_OR_REMOVED);
  1120. GetParticleSystemDefinitionBrowser()->UpdateParticleSystemList( bRetainSelection );
  1121. }
  1122. }
  1123. bool bRefreshProperties = ( nNotifySource != NOTIFY_SOURCE_PROPERTIES_TREE ) &&
  1124. ( ( nNotifyFlags & ( NOTIFY_CHANGE_TOPOLOGICAL | NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE ) ) != 0 );
  1125. bool bRefreshPropertyValues = ( nNotifySource != NOTIFY_SOURCE_PROPERTIES_TREE ) &&
  1126. ( nNotifyFlags & NOTIFY_CHANGE_ATTRIBUTE_VALUE ) != 0;
  1127. if ( bRefreshProperties || bRefreshPropertyValues )
  1128. {
  1129. if ( m_hProperties.Get() )
  1130. {
  1131. m_hProperties->Refresh( !bRefreshProperties );
  1132. }
  1133. }
  1134. UpdateMenuBar();
  1135. }
  1136. //-----------------------------------------------------------------------------
  1137. // Creates a new document
  1138. //-----------------------------------------------------------------------------
  1139. void CPetTool::NewDocument( )
  1140. {
  1141. Assert( !m_pDoc );
  1142. DestroyTools();
  1143. m_pDoc = new CPetDoc( this );
  1144. m_pDoc->CreateNew( );
  1145. ShowMiniViewport( true );
  1146. CreateTools( m_pDoc );
  1147. UpdateMenuBar( );
  1148. InitTools();
  1149. }
  1150. //-----------------------------------------------------------------------------
  1151. // Loads up a new document
  1152. //-----------------------------------------------------------------------------
  1153. bool CPetTool::LoadDocument( const char *pDocName )
  1154. {
  1155. Assert( !m_pDoc );
  1156. DestroyTools();
  1157. m_pDoc = new CPetDoc( this );
  1158. if ( !m_pDoc->LoadFromFile( pDocName ) )
  1159. {
  1160. delete m_pDoc;
  1161. m_pDoc = NULL;
  1162. Warning( "Fatal error loading '%s'\n", pDocName );
  1163. return false;
  1164. }
  1165. ShowMiniViewport( true );
  1166. CreateTools( m_pDoc );
  1167. UpdateMenuBar( );
  1168. InitTools();
  1169. // Let the other tools know we've loaded + therefore modified particle systems
  1170. CUtlBuffer buf;
  1171. g_pDataModel->Serialize( buf, "binary", PET_FILE_FORMAT, m_pDoc->GetRootObject()->GetHandle() );
  1172. KeyValues *pMessage = new KeyValues( "ParticleSystemUpdated" );
  1173. pMessage->SetPtr( "definitionBits", buf.Base() );
  1174. pMessage->SetInt( "definitionSize", buf.TellMaxPut() );
  1175. PostMessageToAllTools( pMessage );
  1176. pMessage->deleteThis();
  1177. return true;
  1178. }
  1179. void CPetTool::PreOperatorsPaste()
  1180. {
  1181. if ( m_hProperties.Get() )
  1182. {
  1183. m_hProperties->DeleteSelectedFunctions( );
  1184. }
  1185. }