Browse Source

Merge pull request #1631 from Areloch/ParticleEditorUpdatePR

Update of Particle Editor to standardize it up and utilize inspectors rather than adhoc guis
Brian Roberts 2 weeks ago
parent
commit
975fc924cc
31 changed files with 5081 additions and 6085 deletions
  1. 1 1
      Engine/source/T3D/assets/ImageAsset.h
  2. 311 0
      Engine/source/T3D/fx/particle.cpp
  3. 1 0
      Engine/source/T3D/fx/particle.h
  4. 10 59
      Engine/source/T3D/fx/particleEmitter.cpp
  5. 1 1
      Engine/source/T3D/fx/particleEmitter.h
  6. 40 0
      Engine/source/T3D/fx/particleInspectors.h
  7. 5 0
      Engine/source/gui/containers/guiStackCtrl.cpp
  8. 2 0
      Engine/source/gui/containers/guiStackCtrl.h
  9. 34 0
      Engine/source/gui/editor/inspector/group.cpp
  10. 1 0
      Engine/source/gui/editor/inspector/group.h
  11. 119 0
      Templates/BaseGame/game/tools/gui/contextedDropdownList.gui
  12. 127 0
      Templates/BaseGame/game/tools/gui/contextedDropdownList.tscript
  13. 0 7
      Templates/BaseGame/game/tools/particleEditor/PE_Window.asset.taml
  14. 0 3880
      Templates/BaseGame/game/tools/particleEditor/ParticleEditor.ed.gui
  15. 86 0
      Templates/BaseGame/game/tools/particleEditor/guis/PETabTemplate.gui
  16. 83 0
      Templates/BaseGame/game/tools/particleEditor/guis/ParticleEditor.ed.gui
  17. 197 0
      Templates/BaseGame/game/tools/particleEditor/guis/createNewPrompt.ed.gui
  18. 33 0
      Templates/BaseGame/game/tools/particleEditor/guis/createNewPrompt.ed.tscript
  19. 141 166
      Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript
  20. 60 23
      Templates/BaseGame/game/tools/particleEditor/main.tscript
  21. 0 606
      Templates/BaseGame/game/tools/particleEditor/particleEditorUndo.ed.tscript
  22. 0 680
      Templates/BaseGame/game/tools/particleEditor/particleEmitterEditor.ed.tscript
  23. 0 662
      Templates/BaseGame/game/tools/particleEditor/particleParticleEditor.ed.tscript
  24. 398 0
      Templates/BaseGame/game/tools/particleEditor/scripts/afxChoreoEditor.ed.tscript
  25. 398 0
      Templates/BaseGame/game/tools/particleEditor/scripts/afxZodiacEditor.ed.tscript
  26. 490 0
      Templates/BaseGame/game/tools/particleEditor/scripts/explosionEditor.ed.tscript
  27. 1070 0
      Templates/BaseGame/game/tools/particleEditor/scripts/particleEditorUndo.ed.tscript
  28. 605 0
      Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript
  29. 396 0
      Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript
  30. 469 0
      Templates/BaseGame/game/tools/particleEditor/scripts/particleRibbonEditor.ed.tscript
  31. 3 0
      Templates/BaseGame/game/tools/worldEditor/main.tscript

+ 1 - 1
Engine/source/T3D/assets/ImageAsset.h

@@ -351,7 +351,7 @@ public:
 
 #define INITPERSISTFIELD_IMAGEASSET(name, consoleClass, docs)                                                                                                                 \
    addProtectedField(assetText(name, Asset), TypeImageAssetPtr, Offset(m##name##Asset, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.)); \
-   addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, file docs.));
+   addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, file docs.), AbstractClassRep::FIELD_HideInInspectors);
 
 
 #define DECLARE_IMAGEASSET_ARRAY(className, name, profile, max)                                                                                                               \

+ 311 - 0
Engine/source/T3D/fx/particle.cpp

@@ -32,6 +32,7 @@
 #include "math/mRandom.h"
 #include "math/mathIO.h"
 #include "console/engineAPI.h"
+#include "particleInspectors.h"
 
 IMPLEMENT_CO_DATABLOCK_V1( ParticleData );
 
@@ -814,3 +815,313 @@ void ParticleData::onPerformSubstitutions()
 }
 
 DEF_ASSET_BINDS_REFACTOR(ParticleData, Texture);
+
+ConsoleType(stringList, TypeParticleList, Vector<StringTableEntry>, "")
+
+ConsoleGetType(TypeParticleList)
+{
+   Vector<StringTableEntry>* vec = (Vector<StringTableEntry> *)dptr;
+   S32 buffSize = (vec->size() * 15) + 16;
+   char* returnBuffer = Con::getReturnBuffer(buffSize);
+   S32 maxReturn = buffSize;
+   returnBuffer[0] = '\0';
+   S32 returnLeng = 0;
+   for (Vector<const char*>::iterator itr = vec->begin(); itr != vec->end(); itr++)
+   {
+      // concatenate the next value onto the return string
+      dSprintf(returnBuffer + returnLeng, maxReturn - returnLeng, "%s ", *itr);
+      // update the length of the return string (so far)
+      returnLeng = dStrlen(returnBuffer);
+   }
+   // trim off that last extra space
+   if (returnLeng > 0 && returnBuffer[returnLeng - 1] == ' ')
+      returnBuffer[returnLeng - 1] = '\0';
+   return returnBuffer;
+}
+
+ConsoleSetType(TypeParticleList)
+{
+   Vector<StringTableEntry>* vec = (Vector<StringTableEntry> *)dptr;
+   // we assume the vector should be cleared first (not just appending)
+   vec->clear();
+   S32 numUnits = 0;
+   if (argc == 1)
+   {
+      const char* values = argv[0];
+      numUnits = StringUnit::getUnitCount(values, " ");
+
+      if (numUnits > 1)
+         bool dafgdf = true;
+
+      for (U32 i = 0; i < numUnits; i++)
+      {
+         const char* value = StringUnit::getUnit(values, i, " ");
+
+         vec->push_back(StringTable->insert(value));
+      }
+   }
+   else if (argc > 1)
+   {
+      for (S32 i = 0; i < argc; i++)
+         vec->push_back(StringTable->insert(argv[i]));
+   }
+   else
+      Con::printf("TypeParticleList must be set as { a, b, c, ... } or \"a b c ...\"");
+
+   if (numUnits > 1)
+   {
+      for (U32 x = 0; x < numUnits; x++)
+      {
+         Vector<const char*> testVec = *vec;
+         String test = testVec[x];
+         Con::printf("TypeParticleList vec results: %s", testVec[x]);
+      }
+   }
+   bool test = false;
+}
+
+#ifdef TORQUE_TOOLS
+//-----------------------------------------------------------------------------
+// GuiInspectorTypeExpandableIdList 
+//-----------------------------------------------------------------------------
+/**/IMPLEMENT_CONOBJECT(GuiInspectorTypeParticleDataList);
+
+ConsoleDocClass(GuiInspectorTypeParticleDataList,
+   "@brief Inspector field type for ParticleData lists\n\n"
+   "Editor use only.\n\n"
+   "@internal"
+);
+
+GuiControl* GuiInspectorTypeParticleDataList::constructEditControl()
+{
+   mStack = new GuiStackControl();
+
+   if (mStack == NULL)
+      return mStack;
+
+   mStack->registerObject();
+   mStack->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiDefaultProfile");
+   mStack->setPadding(3);
+
+   mNewParticleBtn = new GuiIconButtonCtrl();
+   mNewParticleBtn->registerObject();
+   mNewParticleBtn->_setBitmap(StringTable->insert("ToolsModule:iconAdd_image"));
+   mNewParticleBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiDefaultProfile");
+   mNewParticleBtn->setHorizSizing(horizResizeRight);
+   mNewParticleBtn->mMakeIconSquare = true;
+   mNewParticleBtn->mFitBitmapToButton = true;
+   mNewParticleBtn->setExtent(20, 20);
+
+   char szBuffer[512];
+   dSprintf(szBuffer, sizeof(szBuffer), "ParticleEditor.addParticleSlot(%s, %s);",
+      mNewParticleBtn->getIdString(), mInspector->getInspectObject()->getIdString());
+   mNewParticleBtn->setField("Command", szBuffer);
+
+   GuiContainer* newBtnCtnr = new GuiContainer();
+   newBtnCtnr->registerObject();
+   newBtnCtnr->addObject(mNewParticleBtn);
+   newBtnCtnr->setHorizSizing(horizResizeWidth);
+
+   mStack->addObject(newBtnCtnr);
+
+   //Particle 0
+   mParticleSlot0Ctrl = _buildParticleEntryField(0);
+   
+   mStack->addObject(mParticleSlot0Ctrl);
+
+   //Now the non-default entries if we already have some
+   Parent::updateValue();
+   const char* data = getData();
+
+   if (data != nullptr && !String::isEmpty(data))
+   {
+      U32 particlesCount = StringUnit::getUnitCount(data, " ");
+      for (U32 i=1; i < particlesCount; i++)
+      {
+         GuiControl* particleSlotCtrl = _buildParticleEntryField(i);
+         mStack->addObject(particleSlotCtrl);
+      }
+   }
+
+   _registerEditControl(mStack);
+
+   //constructEditControlChildren(retCtrl, getWidth());
+
+   //retCtrl->addObject(mScriptValue);
+
+   /*char szBuffer[512];
+   dSprintf(szBuffer, 512, "setClipboard(%d.getText());", mScriptValue->getId());
+   mCopyButton->setField("Command", szBuffer);
+   addObject(mCopyButton);*/
+
+   mUseHeightOverride = true;
+   mHeightOverride = (mStack->getCount() * 23) + 6;
+
+   return mStack;
+}
+
+GuiControl* GuiInspectorTypeParticleDataList::_buildParticleEntryField(const S32& index)
+{
+   Point2I editPos = mStack->getPosition();
+   Point2I editExtent = mStack->getExtent();
+
+   //Particle 0
+   GuiControl* particleSlotCtrl = new GuiControl();
+   particleSlotCtrl->registerObject();
+   particleSlotCtrl->setExtent(editExtent.x, 18);
+   particleSlotCtrl->setHorizSizing(horizResizeWidth);
+
+   GuiButtonCtrl* listBtn = new GuiButtonCtrl();
+   listBtn->registerObject();
+   listBtn->setHorizSizing(horizResizeLeft);
+   listBtn->setInternalName("particleDropdown");
+   listBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiButtonProfile");
+   listBtn->setExtent(editExtent.x - 40, 18);
+
+   char szBuffer[512];
+   dSprintf(szBuffer, sizeof(szBuffer), "ParticleEditor.changeParticleSlot(%s, %s, %d);",
+      listBtn->getIdString(), mInspector->getInspectObject()->getIdString(), index);
+   listBtn->setField("Command", szBuffer);
+
+   if (mField && index != -1)
+   {
+      Parent::updateValue();
+      const char* data = getData();
+
+      if (data != nullptr && !String::isEmpty(data))
+      {
+         const char* particleSlotData = StringUnit::getUnit(data, index, " ");
+         listBtn->setText(particleSlotData);
+      }
+   }
+
+   particleSlotCtrl->addObject(listBtn);
+
+   GuiButtonCtrl* editSlotBtn = new GuiIconButtonCtrl();
+   editSlotBtn->registerObject();
+   editSlotBtn->setText(StringTable->insert("..."));
+   editSlotBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiButtonProfile");
+   editSlotBtn->setHorizSizing(horizResizeRight);
+   editSlotBtn->setInternalName("editBtn");
+   editSlotBtn->setPosition(editExtent.x - 40, 0);
+   editSlotBtn->setExtent(20, 20);
+
+   char cmdBuffer[512];
+   dSprintf(cmdBuffer, sizeof(cmdBuffer), "ParticleEditor.editParticleSlot(%s, %s, %d);",
+      this->getIdString(), mInspector->getInspectObject()->getIdString(), index);
+   editSlotBtn->setField("Command", cmdBuffer);
+
+   particleSlotCtrl->addObject(editSlotBtn);
+
+   if (index != 0)
+   {
+      GuiIconButtonCtrl* deleteSlotBtn = new GuiIconButtonCtrl();
+      deleteSlotBtn->registerObject();
+      deleteSlotBtn->_setBitmap(StringTable->insert("ToolsModule:iconCancel_image"));
+      deleteSlotBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiDefaultProfile");
+      deleteSlotBtn->setHorizSizing(horizResizeRight);
+      deleteSlotBtn->setInternalName("deleteBtn");
+      deleteSlotBtn->mMakeIconSquare = true;
+      deleteSlotBtn->mFitBitmapToButton = true;
+      deleteSlotBtn->setPosition(editExtent.x - 20, 0);
+      deleteSlotBtn->setExtent(20, 20);
+
+      char cmdBuffer[512];
+      dSprintf(cmdBuffer, sizeof(cmdBuffer), "ParticleEditor.clearParticleSlot(%s, %s, %d);",
+         this->getIdString(), mInspector->getInspectObject()->getIdString(), index);
+      deleteSlotBtn->setField("Command", cmdBuffer);
+
+      particleSlotCtrl->addObject(deleteSlotBtn);
+   }
+
+   return particleSlotCtrl;
+}
+
+void GuiInspectorTypeParticleDataList::_populateMenu(GuiPopUpMenuCtrlEx* menu)
+{
+   // Check whether we should show profiles from the editor category.
+
+   const bool showEditorProfiles = Con::getBoolVariable("$pref::GuiEditor::showEditorProfiles", false);
+
+   // Add the control profiles to the menu.
+
+   SimGroup* grp = Sim::getGuiDataGroup();
+   SimSetIterator iter(grp);
+   for (; *iter; ++iter)
+   {
+      GuiControlProfile* profile = dynamic_cast<GuiControlProfile*>(*iter);
+      if (!profile)
+         continue;
+
+      if (!showEditorProfiles && profile->mCategory.compare("Editor", 0, String::NoCase) == 0)
+         continue;
+
+      menu->addEntry(profile->getName(), profile->getId());
+   }
+
+   menu->sort();
+}
+
+bool GuiInspectorTypeParticleDataList::updateRects()
+{
+   S32 rowSize = 18;
+   S32 dividerPos, dividerMargin;
+   mInspector->getDivider(dividerPos, dividerMargin);
+   Point2I fieldExtent = getExtent();
+   Point2I fieldPos = getPosition();
+
+   mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
+
+   mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin, fieldExtent.y);
+   S32 cellWidth = mCeil((dividerPos - dividerMargin - 29));
+
+   mNewParticleBtn->resize(Point2I(mEditCtrlRect.extent.x - 20, 0), Point2I(20, 20));
+
+   //Particle Slot 0 is mandatory
+   auto c = mStack->getCount();
+   for (U32 i=0; i < mStack->getCount(); i++)
+   {
+      GuiControl* slot = static_cast<GuiControl*>(mStack->getObject(i));
+
+      slot->resize(Point2I(0, 0), Point2I(mEditCtrlRect.extent.x, rowSize));
+
+      GuiControl* dropdown = dynamic_cast<GuiControl*>(slot->findObjectByInternalName(StringTable->insert("particleDropdown")));
+      if (dropdown)
+      {
+         dropdown->setPosition(0, 0);
+         dropdown->setExtent(mEditCtrlRect.extent.x - 40, 20);
+      }
+
+      GuiControl* editBtn = dynamic_cast<GuiControl*>(slot->findObjectByInternalName(StringTable->insert("editBtn")));
+      if (editBtn)
+      {
+         editBtn->setPosition(mEditCtrlRect.extent.x - 40, 0);
+         editBtn->setExtent(20, 20);
+      }
+
+      GuiControl* deleteBtn = dynamic_cast<GuiControl*>(slot->findObjectByInternalName(StringTable->insert("deleteBtn")));
+      if (deleteBtn)
+      {
+         deleteBtn->setPosition(mEditCtrlRect.extent.x - 20, 0);
+         deleteBtn->setExtent(20, 20);
+      }
+   }
+
+   mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
+
+   mHeightOverride = (mStack->getCount() * 23) + 6;
+
+   //mCopyButton->resize(Point2I(mProfile->mTextOffset.x, rowSize + 3), Point2I(45, 15));
+   //mPasteButton->resize(Point2I(mProfile->mTextOffset.x, rowSize + rowSize + 6), Point2I(45, 15));
+
+   return true;
+}
+
+
+void GuiInspectorTypeParticleDataList::consoleInit()
+{
+   Parent::consoleInit();
+
+   ConsoleBaseType::getType(TypeParticleList)->setInspectorFieldType("GuiInspectorTypeParticleDataList");
+}
+#endif

+ 1 - 0
Engine/source/T3D/fx/particle.h

@@ -24,6 +24,7 @@
 // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
 // Copyright (C) 2015 Faust Logic, Inc.
 //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
+#pragma once
 
 #ifndef _PARTICLE_H_
 #define _PARTICLE_H_

+ 10 - 59
Engine/source/T3D/fx/particleEmitter.cpp

@@ -42,6 +42,7 @@
 #include "T3D/gameBase/gameProcess.h"
 #include "lighting/lightInfo.h"
 #include "console/engineAPI.h"
+#include "particleInspectors.h"
 
 #if defined(AFX_CAP_PARTICLE_POOLS) 
 #include "afx/util/afxParticlePool.h"
@@ -145,7 +146,6 @@ ParticleEmitterData::ParticleEmitterData()
    ribbonParticles = false;
    useEmitterSizes  = false;
    useEmitterColors = false;
-   particleString   = NULL;
    partListInitSize = 0;
 
    // These members added for support of user defined blend factors
@@ -265,7 +265,7 @@ void ParticleEmitterData::initPersistFields()
       addField( "ribbonParticles", TYPEID< bool >(), Offset(ribbonParticles, ParticleEmitterData),
          "If true, particles are rendered as a continous ribbon." );
 
-      addField( "particles", TYPEID< StringTableEntry >(), Offset(particleString, ParticleEmitterData),
+      addField( "particles", TypeParticleList, Offset(particleString, ParticleEmitterData),
          "@brief List of space or TAB delimited ParticleData datablock names.\n\n"
          "A random one of these datablocks is selected each time a particle is "
          "emitted." );
@@ -605,21 +605,11 @@ bool ParticleEmitterData::onAdd()
       softnessDistance = 0.0f;
    }
 
-   if (particleString == NULL && dataBlockIds.size() == 0) 
+   if (particleString.empty() && dataBlockIds.size() == 0) 
    {
       Con::warnf(ConsoleLogEntry::General, "ParticleEmitterData(%s) no particleString, invalid datablock", getName());
       return false;
    }
-   if (particleString && particleString[0] == '\0') 
-   {
-      Con::warnf(ConsoleLogEntry::General, "ParticleEmitterData(%s) no particleString, invalid datablock", getName());
-      return false;
-   }
-   if (particleString && dStrlen(particleString) > 255) 
-   {
-      Con::errorf(ConsoleLogEntry::General, "ParticleEmitterData(%s) particle string too long [> 255 chars]", getName());
-      return false;
-   }
 
    if( lifetimeMS < 0 )
    {
@@ -635,40 +625,18 @@ bool ParticleEmitterData::onAdd()
 
    // load the particle datablocks...
    //
-   if( particleString != NULL )
+   if( !particleString.empty() )
    {
-      //   particleString is once again a list of particle datablocks so it
-      //   must be parsed to extract the particle references.
-
-      // First we parse particleString into a list of particle name tokens 
-      Vector<char*> dataBlocks(__FILE__, __LINE__);
-      dsize_t tokLen = dStrlen(particleString) + 1;
-      char* tokCopy = new char[tokLen];
-      dStrcpy(tokCopy, particleString, tokLen);
-
-      char* currTok = dStrtok(tokCopy, " \t");
-      while (currTok != NULL) 
-      {
-         dataBlocks.push_back(currTok);
-         currTok = dStrtok(NULL, " \t");
-      }
-      if (dataBlocks.size() == 0) 
-      {
-         Con::warnf(ConsoleLogEntry::General, "ParticleEmitterData(%s) invalid particles string.  No datablocks found", getName());
-         delete [] tokCopy;
-         return false;
-      }    
-
       // Now we convert the particle name tokens into particle datablocks and IDs 
       particleDataBlocks.clear();
       dataBlockIds.clear();
 
-      for (U32 i = 0; i < dataBlocks.size(); i++) 
+      for (U32 i = 0; i < particleString.size(); i++) 
       {
          ParticleData* pData = NULL;
-         if (Sim::findObject(dataBlocks[i], pData) == false) 
+         if (Sim::findObject(particleString[i], pData) == false)
          {
-            Con::warnf(ConsoleLogEntry::General, "ParticleEmitterData(%s) unable to find particle datablock: %s", getName(), dataBlocks[i]);
+            Con::warnf(ConsoleLogEntry::General, "ParticleEmitterData(%s) unable to find particle datablock: %s", getName(), particleString[i]);
          }
          else 
          {
@@ -677,9 +645,6 @@ bool ParticleEmitterData::onAdd()
          }
       }
 
-      // cleanup
-      delete [] tokCopy;
-
       // check that we actually found some particle datablocks
       if (particleDataBlocks.size() == 0) 
       {
@@ -2570,26 +2535,12 @@ bool ParticleEmitterData::reload()
    dataBlockIds.clear();
    particleDataBlocks.clear();
 
-   // Parse out particle string.
-   
-   U32 numUnits = 0;
-   if( particleString )
-      numUnits = StringUnit::getUnitCount( particleString, " \t" );
-   if( !particleString || !particleString[ 0 ] || !numUnits )
+   for( U32 i = 0; i < particleString.size(); ++ i )
    {
-      Con::errorf( "ParticleEmitterData(%s) has an empty particles string.", getName() );
-      mReloadSignal.trigger();
-      return false;
-   }
-
-   for( U32 i = 0; i < numUnits; ++ i )
-   {
-      const char* dbName = StringUnit::getUnit( particleString, i, " \t" );
-
       ParticleData* data = NULL;
-      if( !Sim::findObject( dbName, data ) )
+      if( !Sim::findObject(particleString[i], data))
       {
-         Con::errorf( ConsoleLogEntry::General, "ParticleEmitterData(%s) unable to find particle datablock: %s", getName(), dbName );
+         Con::errorf( ConsoleLogEntry::General, "ParticleEmitterData(%s) unable to find particle datablock: %s", getName(), particleString[i]);
          continue;
       }
 

+ 1 - 1
Engine/source/T3D/fx/particleEmitter.h

@@ -109,7 +109,7 @@ class ParticleEmitterData : public GameBaseData
    bool  alignParticles;                     ///< Particles always face along a particular axis
    Point3F alignDirection;                   ///< The direction aligned particles should face
 
-   StringTableEntry      particleString;     ///< Used to load particle data directly from a string
+   Vector<StringTableEntry>      particleString;     ///< Used to load particle data directly from a string
 
    Vector<ParticleData*> particleDataBlocks; ///< Particle Datablocks 
    Vector<U32>           dataBlockIds;       ///< Datablock IDs (parellel array to particleDataBlocks)

+ 40 - 0
Engine/source/T3D/fx/particleInspectors.h

@@ -0,0 +1,40 @@
+#pragma once
+#ifdef TORQUE_TOOLS
+#include "gui/buttons/guiIconButtonCtrl.h"
+#endif
+
+#include "gui/containers/guiStackCtrl.h"
+#include "gui/controls/guiPopUpCtrlEx.h"
+#include "gui/editor/inspector/field.h"
+
+//-----------------------------------------------------------------------------
+// TypeParticleList
+//-----------------------------------------------------------------------------
+DefineConsoleType(TypeParticleList, Vector<const char*>)
+
+
+#ifdef TORQUE_TOOLS
+//-----------------------------------------------------------------------------
+// GuiInspectorTypeGuiProfile Class
+//-----------------------------------------------------------------------------
+class GuiInspectorTypeParticleDataList : public GuiInspectorField
+{
+private:
+   typedef GuiInspectorField Parent;
+
+   GuiStackControl* mStack;
+   GuiIconButtonCtrl* mNewParticleBtn;
+   GuiControl* mParticleSlot0Ctrl;
+   Vector<GuiControl*> mParticleSlotList;
+
+public:
+   DECLARE_CONOBJECT(GuiInspectorTypeParticleDataList);
+   static void consoleInit();
+
+   GuiControl* constructEditControl() override;
+   bool updateRects() override;
+
+   void _populateMenu(GuiPopUpMenuCtrlEx* menu);
+   GuiControl* _buildParticleEntryField(const S32& index);
+};
+#endif

+ 5 - 0
Engine/source/gui/containers/guiStackCtrl.cpp

@@ -387,3 +387,8 @@ void GuiStackControl::childResized(GuiControl *child)
 {
    updatePanes();
 }
+
+void GuiStackControl::setPadding(const U32& padding)
+{
+   mPadding = padding;
+}

+ 2 - 0
Engine/source/gui/containers/guiStackCtrl.h

@@ -94,6 +94,8 @@ public:
 
    bool reOrder(SimObject* obj, SimObject* target = 0) override;
 
+   void setPadding(const U32& padding);
+
    static void initPersistFields();
    
    DECLARE_CONOBJECT(GuiStackControl);

+ 34 - 0
Engine/source/gui/editor/inspector/group.cpp

@@ -781,6 +781,30 @@ void GuiInspectorGroup::hideInspectorField(StringTableEntry fieldName, bool setH
       field->flag.clear(AbstractClassRep::FIELD_HideInInspectors);
 }
 
+void GuiInspectorGroup::replaceInspectorField(StringTableEntry fieldName, GuiInspectorField* replacementField)
+{
+   for (U32 i = 0; i < mStack->size(); i++)
+   {
+      GuiInspectorField* field = dynamic_cast<GuiInspectorField*>(mStack->getObject(i));
+
+      if (field == nullptr)
+         continue;
+
+      if (field->getFieldName() == fieldName || field->getSpecialEditVariableName() == fieldName)
+      {
+         //ensure we match up to the internals
+         replacementField->mField = field->mField;
+
+         mStack->addObject(replacementField);
+         mStack->reOrder(replacementField, field);
+
+         mStack->removeObject(field);
+
+         return;
+      }
+   }
+}
+
 DefineEngineMethod(GuiInspectorGroup, createInspectorField, GuiInspectorField*, (), , "createInspectorField()")
 {
    return object->createInspectorField();
@@ -828,6 +852,16 @@ DefineEngineMethod(GuiInspectorGroup, hideField, void, (const char* fieldName, b
    object->hideInspectorField(StringTable->insert(fieldName), setHidden);
 }
 
+DefineEngineMethod(GuiInspectorGroup, replaceField, void, (const char* fieldName, GuiInspectorField* field), (nullAsType<GuiInspectorField*>()),
+   "Removes a Inspector field to this group of a given name.\n"
+   "@param fieldName The name of the field to be removed.")
+{
+   if (dStrEqual(fieldName, ""))
+      return;
+
+   object->replaceInspectorField(StringTable->insert(fieldName), field);
+}
+
 DefineEngineMethod(GuiInspectorGroup, setForcedArrayIndex, void, (S32 arrayIndex), (-1),
    "Sets the ForcedArrayIndex for the group. Used to force presentation of arrayed fields to only show a specific field index."
    "@param arrayIndex The specific field index for arrayed fields to show. Use -1 or blank arg to go back to normal behavior.")

+ 1 - 0
Engine/source/gui/editor/inspector/group.h

@@ -87,6 +87,7 @@ public:
    void addInspectorField(GuiInspectorField* field);
    void removeInspectorField(StringTableEntry name);
    void hideInspectorField(StringTableEntry fieldName, bool setHidden);
+   void replaceInspectorField(StringTableEntry fieldName, GuiInspectorField* replacementField);
 
    void setForcedArrayIndex(const S32& arrayIndex = -1)
    {

+ 119 - 0
Templates/BaseGame/game/tools/gui/contextedDropdownList.gui

@@ -0,0 +1,119 @@
+//--- OBJECT WRITE BEGIN ---
+$guiContent = new GuiControl(ContextedDropdownListGui) {
+   extent = "1280 720";
+   profile = "GuiDefaultProfile";
+   tooltipProfile = "GuiToolTipProfile";
+   isContainer = "1";
+   canSaveDynamicFields = "0";
+   horizSizing = "width";
+   vertSizing = "height";
+   
+   new GuiMouseEventCtrl(ContextedDropdownListDecoy) {
+      extent = "1280 720";
+      minExtent = "8 8";
+      horizSizing = "width";
+      vertSizing = "height";
+      profile = "ToolsGuiDefaultProfile";
+      tooltipProfile = "GuiToolTipProfile";
+   };
+   
+   new GuiContainer(ContextedDropdownList) {
+      position = "472 151";
+      extent = "300 450";
+      profile = "ToolsGuiDefaultNonModalProfile";
+      tooltipProfile = "GuiToolTipProfile";
+      canSaveDynamicFields = "0";
+      minExtent = "300 350";
+
+      new GuiContainer() {
+         position = "25 25";
+         extent = "250 400";
+         profile = "IconDropdownProfile";
+         tooltipProfile = "GuiToolTipProfile";
+         internalName = "window";
+         horizSizing = "width";
+         vertSizing = "height";
+
+         new GuiTextCtrl() {
+            position = "0 3";
+            extent = "250 16";
+            horizSizing = "width";
+            profile = "ToolsGuiTextCenterProfile";
+            tooltipProfile = "GuiToolTipProfile";
+            internalName = "titleText";
+         };
+         new GuiContainer() {
+            position = "0 22";
+            extent = "250 20";
+            horizSizing = "width";
+            profile = "GuiDefaultProfile";
+            tooltipProfile = "GuiToolTipProfile";
+
+            new GuiTextEditCtrl() {
+               position = "3 0";
+               extent = "223 20";
+               horizSizing = "width";
+               profile = "ToolsGuiTextEditProfile";
+               tooltipProfile = "GuiToolTipProfile";
+               internalName = "textFilter";
+               validate = "ContextedDropdownListGui.updateFilterText();";
+            };
+            new GuiIconButtonCtrl() {
+               BitmapAsset = "ToolsModule:cross_image";
+               BitmapFile = "tools/gui/images/stencilIcons/cross.png";
+               sizeIconToButton = "1";
+               position = "227 0";
+               extent = "20 20";
+               horizSizing = "left";
+               profile = "ToolsGuiIconButtonSmallProfile";
+               tooltipProfile = "GuiToolTipProfile";
+               command = "ContextedDropdownListGui.clearFilterText();";
+            };
+         };
+         new GuiScrollCtrl() {
+            hScrollBar = "dynamic";
+            vScrollBar = "dynamic";
+            position = "7 44";
+            extent = "236 326";
+            horizSizing = "width";
+            vertSizing = "height";
+            profile = "ToolsGuiScrollProfile";
+            tooltipProfile = "GuiToolTipProfile";
+            internalName = "scroll";
+
+            new GuiTreeViewCtrl() {
+               itemHeight = "21";
+               position = "1 1";
+               extent = "220 2";
+               profile = "ToolsGuiTreeViewProfile";
+               tooltipProfile = "GuiToolTipProfile";
+               internalName = "tree";
+               showObjectIds = "0";
+               showClassNames = "0";
+               showTypeHints = "0";
+               showRoot = "0";
+            };
+         };
+         new GuiButtonCtrl() {
+            Text = "Select";
+            position = "6 376";
+            extent = "118 20";
+            vertSizing = "top";
+            profile = "ToolsGuiButtonProfile";
+            tooltipProfile = "GuiToolTipProfile";
+            Command = "ContextedDropdownListGui.select();";
+         };
+         new GuiButtonCtrl() {
+            Text = "Cancel";
+            position = "126 376";
+            extent = "117 20";
+            horizSizing = "left";
+            vertSizing = "top";
+            profile = "ToolsGuiButtonProfile";
+            tooltipProfile = "GuiToolTipProfile";
+            Command = "ContextedDropdownListGui.toggle();";
+         };
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 127 - 0
Templates/BaseGame/game/tools/gui/contextedDropdownList.tscript

@@ -0,0 +1,127 @@
+if(!isObject( ContextedDropdownListActionMap ) )
+{
+   new ActionMap(ContextedDropdownListActionMap){};
+   
+   BaseUIActionMap.bindCmd( keyboard, Escape, "", "ContextedDropdownListGui.toggle();");
+}
+
+
+function ContextedDropdownListGui::onWake(%this)
+{
+   %this.clearFilterText();
+}
+
+function ContextedDropdownListGui::show(%this, %listObject, %titleText, %selectCallback, %callerObject)
+{
+     %this-->tree.open(%listObject, false);
+     %this-->tree.expandItem(1, true);
+     
+     //Epxand any sub-categories as appropriate
+     foreach(%child in %listObject)
+     {
+         %childId = %this-->tree.findItemByObjectId(%child);
+         %this-->tree.expandItem(%childId, true);
+     }
+     %this.callback = %selectCallback;
+     %this-->titleText.setText(%titleText);
+     
+     Canvas.pushDialog(ContextedDropdownListGui);
+     
+     if(isObject(%callerObject))
+     {
+         %canvasExt = Canvas.getExtent();
+         %contextListExt = ContextedDropdownList.extent;
+         %callerGlobalPos = %callerObject.getGlobalPosition();
+         %decoyPad = ContextedDropdownList-->window.position;
+
+         %width = %callerObject.extent.x + %decoyPad;
+         if(%width < ContextedDropdownList.minExtent.x)
+            %width = ContextedDropdownList.minExtent.x;
+            
+         %callerGlobalPos.x -= ContextedDropdownList-->window.position.x;
+         %callerGlobalPos.y -= ContextedDropdownList-->window.position.y - %callerObject.extent.y;
+
+         //bump us to fit to the screen if needbe
+         %xOvershoot = %callerGlobalPos.x + %contextListExt.x;
+         if(%xOvershoot > %canvasExt.x)
+            %callerGlobalPos.x -= %xOvershoot - %canvasExt.x;
+
+         //If we would go off the bottom of the screen, flip is to be above the callera object's position
+         %yOvershoot = %callerGlobalPos.y + %contextListExt.y;
+         if(%yOvershoot > %canvasExt.y)
+         {
+            %callerGlobalPos.y = %callerGlobalPos.y - %callerObject.extent.y - ContextedDropdownList.extent.y - %decoyPad.y;
+         }
+            
+          ContextedDropdownList.resize(%callerGlobalPos.x, %callerGlobalPos.y, %width, ContextedDropdownList.extent.y);
+     }
+     
+     %this-->scroll.scrollToTop();
+     %this-->Tree.clearSelection();
+}
+
+function ContextedDropdownListGui::seekText(%this, %text)
+{
+   %itemId = %this-->Tree.findItemByName(%text);
+   %this-->Tree.scrollVisible(%itemId);
+   %this-->Tree.clearSelection();
+   %this-->Tree.addSelection(%itemId);
+}
+
+function ContextedDropdownListGui::seekItemObject(%this, %obj)
+{
+   %itemId = %this-->Tree.findItemByObjectId(%obj.getId());
+   %this-->Tree.scrollVisible(%itemId);
+   %this-->Tree.clearSelection();
+   %this-->Tree.addSelection(%itemId);
+}
+
+function ContextedDropdownListGui::toggle(%this)
+{
+   if ( ContextedDropdownListGui.isAwake()  )
+   {
+      Canvas.popDialog(ContextedDropdownListGui);
+   }
+   else
+   {
+      Canvas.pushDialog(ContextedDropdownListGui);
+   }
+}
+
+function ContextedDropdownListDecoy::onMouseUp()
+{
+   ContextedDropdownListGui.toggle();
+}
+
+function ContextedDropdownListDecoy::onRightMouseUp()
+{
+   ContextedDropdownListGui.toggle();
+}
+
+function ContextedDropdownListGui::updateFilterText(%this)
+{
+   %filterText = %this-->textFilter.getText(); 
+   %this-->tree.setFilterText(%filterText); 
+}
+
+function ContextedDropdownListGui::clearFilterText(%this)
+{
+   %this-->textFilter.setText("");
+   %this-->tree.setFilterText("");
+}
+
+function ContextedDropdownListGui::select(%this)
+{
+   %obj = %this-->tree.getSelectedObject(0);
+   
+   %command = %this.callback @ "(" @ %obj @ ");";
+   echo("SELECT COMMAND: " @ %command);
+   eval(%command);
+   
+   ContextedDropdownListGui.toggle();
+}
+
+function ContextedDropdownListInputHandler::onInputEvent(%this)
+{
+   ContextedDropdownListGui.toggle();
+}

+ 0 - 7
Templates/BaseGame/game/tools/particleEditor/PE_Window.asset.taml

@@ -1,7 +0,0 @@
-<GUIAsset
-    canSave="true"
-    canSaveDynamicFields="true"
-    AssetName="PE_Window"
-    scriptFile="@assetFile=ParticleEditor.ed.gui"
-    GUIFile="@assetFile=ParticleEditor.ed.gui"
-    VersionId="1" />

+ 0 - 3880
Templates/BaseGame/game/tools/particleEditor/ParticleEditor.ed.gui

@@ -1,3880 +0,0 @@
-//-----------------------------------------------------------------------------
-// Torque
-// Copyright GarageGames, LLC 2011
-//-----------------------------------------------------------------------------
-
-$PE_guielement_pos_single_container = "0 0";
-$PE_guielement_ext_single_container = "184 20";
-$PE_guielement_pos_name = "1 0";
-$PE_guielement_ext_name = "70 18";
-$PE_guielement_pos_slider = "74 2";
-$PE_guielement_ext_slider = "58 12";
-$PE_guielement_pos_value = "138 0";
-$PE_guielement_ext_value = "36 18";
-$PE_guielement_pos_textedit = "74 0";
-$PE_guielement_ext_textedit = "100 18";
-$PE_guielement_ext_checkbox_name = "156 18";
-$PE_guielement_pos_checkbox = "161 0";
-$PE_guielement_ext_checkbox = "15 18";
-$PE_guielement_pos_colorpicker = "158 0";
-$PE_guielement_ext_colorpicker = "18 18";
-
-//--- OBJECT WRITE BEGIN ---
-$guiContent = new GuiWindowCollapseCtrl(PE_Window) {
-   canCollapse = "0";
-   canSaveDynamicFields = "0";
-   Enabled = "1";
-   isContainer = "1";
-   Profile = "ToolsGuiWindowProfile";
-   Position = firstWord($pref::Video::mode) - 360
-      SPC getWord(EditorGuiToolbar.extent, 1) + 6;
-   Extent = "360" SPC getWord($pref::Video::mode, 1) - getWord(EditorGuiToolbar.extent, 1) - 65;
-   MinExtent = "300 140";
-   HorizSizing = "windowRelative";
-   VertSizing = "windowRelative";
-   canSave = "1";
-   Visible = "1";
-   hovertime = "1000";
-   Margin = "0 0 0 0";
-   Padding = "0 0 0 0";
-   AnchorTop = "1";
-   AnchorBottom = "0";
-   AnchorLeft = "1";
-   AnchorRight = "0";
-   resizeWidth = "1";
-   resizeHeight = "1";
-   canMove = "0";
-   canClose = "0";
-   canMinimize = "0";
-   canMaximize = "0";
-   minSize = "50 50";
-   closeCommand = "";
-   EdgeSnap = "0";
-   text = ":: Particle Editor";
-      
-   new GuiTabBookCtrl(PE_TabBook) {
-      canSaveDynamicFields = "0";
-      isContainer = "1";
-      internalName = "EditorTabBook";
-      Profile = "ToolsGuiTabBookProfile";
-      HorizSizing = "width";
-      VertSizing = "height";
-      position = "6 27";
-      Extent = "197 289";
-      MinExtent = "8 2";
-      canSave = "1";
-      Visible = "1";
-      hovertime = "1000";
-      Margin = "3 2 3 3";
-      Docking = "client";
-      Padding = "0 0 0 0";
-      AnchorTop = "1";
-      AnchorBottom = "0";
-      AnchorLeft = "1";
-      AnchorRight = "0";
-      TabPosition = "Top";
-      TabMargin = "0";
-      MinTabWidth = "64";
-      
-      new GuiTabPageCtrl(PE_EmitterEditor) {
-         canSaveDynamicFields = "0";
-         Enabled = "1";
-         isContainer = "1";
-         Profile = "ToolsGuiEditorTabPage";
-         HorizSizing = "width";
-         VertSizing = "height";
-         position = "0 19";
-         Extent = "197 271";
-         MinExtent = "8 2";
-         canSave = "1";
-         Visible = "1";
-         hovertime = "1000";
-         Margin = "0 0 0 0";
-         Padding = "0 0 0 0";
-         AnchorTop = "1";
-         AnchorBottom = "0";
-         AnchorLeft = "1";
-         AnchorRight = "0";
-         text = "Emitter";
-         maxLength = "1024";
-         
-         new GuiScrollCtrl() {
-            canSaveDynamicFields = "0";
-            Enabled = "1";
-            isContainer = "1";
-            Profile = "ToolsGuiScrollProfile";
-            HorizSizing = "width";
-            VertSizing = "height";
-            Position = "0 0";
-            Extent = "197 271";
-            MinExtent = "8 8";
-            canSave = "1";
-            Visible = "1";
-            hovertime = "1000";
-            willFirstRespond = "1";
-            hScrollBar = "alwaysOff";
-            vScrollBar = "dynamic";
-            lockHorizScroll = false;
-            lockVertScroll = "false";
-            constantThumbHeight = "0";
-            childMargin = "0 0";
-            
-            new GuiStackControl() {
-               StackingType = "Vertical";
-               HorizStacking = "Left to Right";
-               VertStacking = "Top to Bottom";
-               Padding = "0";
-               canSaveDynamicFields = "0";
-               Enabled = "1";
-               isContainer = "1";
-               Profile = "ToolsGuiDefaultProfile";
-               HorizSizing = "width";
-               VertSizing = "bottom";
-               Position = "1 3";
-               Extent = "197 16";
-               MinExtent = "16 16";
-               canSave = "1";
-               isDecoy = "0";
-               Visible = "1";
-               tooltipprofile = "ToolsGuiToolTipProfile";
-               hovertime = "1000";
-               
-               new GuiControl(PEE_EmitterSelector_Control){ // PEE_EmitterSelector
-                  class = "QuickEditDropDownTextEditCtrl";
-                  isContainer = "1";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = $PE_guielement_pos_single_container ;
-                  Extent = "197 26" ;
-                        
-                  new GuiPopUpMenuCtrl(PEE_EmitterSelector) {
-                     internalName = "PopUpMenu";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiPopUpMenuProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     position = "4 4";
-                     Extent = "123 18";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     Command = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor::onNewEmitter();";
-                     hovertime = "1000";
-                     Margin = "0 0 0 0";
-                     Padding = "0 0 0 0";
-                     AnchorTop = "1";
-                     AnchorBottom = "0";
-                     AnchorLeft = "1";
-                     AnchorRight = "0";
-                     maxLength = "255";
-                     maxPopupHeight = "200";
-                     sbUsesNAColor = "0";
-                     reverseTextList = "0";
-                     bitmapBounds = "16 16";
-                  };
-                  new GuiTextEditCtrl() {
-                     internalName = "TextEdit";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "GuiDropdownTextEditProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     position = "4 4";
-                     Extent = "107 18";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     hovertime = "1000";
-                     Margin = "0 0 0 0";
-                     Padding = "0 0 0 0";
-                     AnchorTop = "1";
-                     AnchorBottom = "0";
-                     AnchorLeft = "1";
-                     AnchorRight = "0";
-                     text = "None";
-                     maxLength = "1024";
-                     AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);";
-                  }; 
-                  new GuiBitmapButtonCtrl() {
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "left";
-                     VertSizing = "bottom";
-                     position = "131 5";
-                     Extent = "17 17";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     Command = "PE_EmitterEditor.showNewDialog();";
-                     hovertime = "1000";
-                     groupNum = "-1";
-                     buttonType = "PushButton";
-                     useMouseEvents = "0";
-                     bitmapAsset = "ToolsModule:new_n_image";
-                     tooltip = "Create New Emitter";
-                  };
-                  new GuiBitmapButtonCtrl() {
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "left";
-                     VertSizing = "bottom";
-                     position = "147 5";
-                     Extent = "17 17";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     Command = "";
-                     hovertime = "1000";
-                     groupNum = "-1";
-                     buttonType = "PushButton";
-                     useMouseEvents = "0";
-                     bitmapAsset = "ToolsModule:save_icon_n_image";
-                     command = "PE_EmitterEditor.saveEmitter( " @ PE_EmitterEditor.currEmitter @ " ); PE_ParticleEditor.saveParticle( PE_ParticleEditor.currParticle );";
-                     tooltip = "Save Current Emitter";
-                  };
-                  new GuiBitmapButtonCtrl() {
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "left";
-                     VertSizing = "bottom";
-                     position = "164 5";
-                     Extent = "17 17";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     Command = "PE_EmitterEditor.showDeleteDialog();";
-                     hovertime = "1000";
-                     groupNum = "-1";
-                     buttonType = "PushButton";
-                     useMouseEvents = "0";
-                     bitmapAsset = "ToolsModule:delete_n_image";
-                     tooltip = "Delete Current Emitter";
-                  };
-               };
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Basic";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(){ // Emitter PEE_lifetimeMS
-                        isContainer = "1";
-                        class = "AggregateControl";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "Life";
-                           maxLength = "255";
-                        };
-                        new GuiSliderCtrl(PEE_lifetimeMS) {
-                           internalName = "PEE_lifetimeMS_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 1000";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_lifetimeMS_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue() );";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                        };
-                     };
-                     
-                     new GuiControl(){ // Emitter PEE_lifetimeVarianceMS
-                        isContainer = "1";
-                        class = "AggregateControl";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "Life Random";
-                           maxLength = "255";
-                        };
-                        new GuiSliderCtrl(PEE_lifetimeVarianceMS) {
-                           internalName = "PEE_lifetimeVarianceMS_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 1000";
-                           ticks = "0";
-                           value = "";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_lifetimeVarianceMS_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue() );";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Emitter Infinite Loop
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Infinite Loop";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEE_infiniteLoop";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           Command = "PE_EmitterEditor.updateLifeFieldsInfiniteLoop();";
-                           text = "";
-                        };
-                     };
-                        
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Emitter Amount
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Amount";
-                        };
-                        new GuiSliderCtrl(PEE_ejectionPeriodMS) {
-                           internalName = "PEE_ejectionPeriodMS_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "1 1000";
-                           ticks = "0";
-                           value = "1";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_ejectionPeriodMS_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue() );";
-                        };
-                     };
-                     new GuiControl(){ // Emitter Amount Random
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Amount Random";
-                        };
-                        new GuiSliderCtrl(PEE_periodVarianceMS) {
-                           internalName = "PEE_periodVarianceMS_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 999";
-                           ticks = "0";
-                           value = "1";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_periodVarianceMS_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue() );";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Particle glow
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Glow";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEE_glow";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           Command = "PE_EmitterEditor.updateEmitter( \"glow\", $ThisControl.getValue());";
-                           text = "";
-                        };
-                     };
-                  };// end stack
-               }; // end "basic" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Motion";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(){ // Emitter speed
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Speed";
-                        };
-                        new GuiSliderCtrl(PEE_ejectionVelocity) {
-                           internalName = "PEE_ejectionVelocity_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 100";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_ejectionVelocity_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue() );";
-                        };
-                     };
-                     new GuiControl(){ // Emitter speed random
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Speed Random";
-                        };
-                        new GuiSliderCtrl(PEE_velocityVariance) {
-                           internalName = "PEE_velocityVariance_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 100";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_velocityVariance_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue() );";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Emitter Orient to Movment Direction
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Orient to Movment Direction";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEE_orientParticles";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           text = "";
-                           command = "PE_EmitterEditor.updateEmitter( \"orientParticles\", $ThisControl.getValue());";
-                        };
-                     };
-                     new GuiControl(){ // Emitter Align to a Direction
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Align to a Direction";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEE_alignParticles";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           text = "";
-                           command = "PE_EmitterEditor.updateEmitter( \"alignParticles\", $ThisControl.getValue());";
-                        };
-                     };
-                     new GuiControl(){ // Emitter Align Direction
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Align Direction";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_alignDirection";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_textedit;
-                           Extent = $PE_guielement_ext_textedit;
-                           text = "0  0  0";
-                           altCommand = "PE_EmitterEditor.updateEmitter( \"alignDirection\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Emitter ribbon
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Render as a Ribbon";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEE_ribbonParticles";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           text = "";
-                           command = "PE_EmitterEditor.updateEmitter( \"ribbonParticles\", $ThisControl.getValue());";
-                        };                     
-                     };
-                  }; // end stack
-               }; // end "motion" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Spread";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(){ // Emitter Angle Min
-                        isContainer = "1";
-                        class = "AggregateControl";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiBitmapCtrl(){ // 0 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+4 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "0 Degrees ( Up )";
-                        };
-                        new GuiBitmapCtrl(){ // 90 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/4)+1 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "90 Degrees ( Left )";
-                        };
-                        new GuiBitmapCtrl(){ // 180 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "180 Degrees ( Down )";
-                        };
-                        new GuiBitmapCtrl(){ // 270 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2+mCeil(getWord($PE_guielement_ext_slider,0)/4))-4 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "270 Degrees ( Right )";
-                        };
-                        new GuiBitmapCtrl(){ // 360 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0))-5 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "360 Degrees ( Up )";
-                        };
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Angle Min";
-                        };
-                        new GuiSliderCtrl(PEE_thetaMin) {
-                           internalName = "PEE_thetaMin_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 180";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalname = "PEE_thetaMin_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getText());";
-                        };             
-                     };
-                     new GuiControl(){ // Emitter Angle Max
-                        isContainer = "1";
-                        class = "AggregateControl";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiBitmapCtrl(){ // 0 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+4 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "0 Degrees ( Up )";
-                        };
-                        new GuiBitmapCtrl(){ // 90 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/4)+1 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "90 Degrees ( Left )";
-                        };
-                        new GuiBitmapCtrl(){ // 180 Degrees
-                           HorizSizing = "left";
-                           minExtent = "0 0";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0";
-                           Extent = "2 18";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "180 Degrees ( Down )";
-                        };
-                        new GuiBitmapCtrl(){ // 270 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2+mCeil(getWord($PE_guielement_ext_slider,0)/4))-4 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "270 Degrees ( Right )";
-                        };
-                        new GuiBitmapCtrl(){ // 360 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0))-5 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "360 Degrees ( Up )";
-                        };
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Angle Max";
-                        };
-                        new GuiSliderCtrl(PEE_thetaMax) {
-                           internalName = "PEE_thetaMax_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 180";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_thetaMax_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getText());";
-                        };             
-                     };
-                     
-                     new GuiControl(){ // Emitter Angle Variance
-                        isContainer = "1";
-                        class = "AggregateControl";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiBitmapCtrl(){ // 0 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+4 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "0 Degrees ( Up )";
-                        };
-                        new GuiBitmapCtrl(){ // 90 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/4)+1 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "45 Degrees";
-                        };
-                        new GuiBitmapCtrl(){ // 180 Degrees
-                           HorizSizing = "left";
-                           minExtent = "0 0";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0";
-                           Extent = "2 18";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "90 Degrees";
-                        };
-                        new GuiBitmapCtrl(){ // 270 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2+mCeil(getWord($PE_guielement_ext_slider,0)/4))-4 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "135 Degrees";
-                        };
-                        new GuiBitmapCtrl(){ // 360 Degrees
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0))-5 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "180 Degrees";
-                        };
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Angle Variance";
-                        };
-                        new GuiSliderCtrl(PEE_thetaVar) {
-                           internalName = "PEE_thetaVar_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateEmitter( \"thetaVariance\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaVariance\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 180";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_thetaVar_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaVariance\", $ThisControl.getText());";
-                        };             
-                     };
-                     
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Emitter Depth
-                        isContainer = "1";
-                        class = "AggregateControl";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Depth";
-                        };
-                        new GuiSliderCtrl(PEE_phiVariance) {
-                           internalName = "PEE_phiVariance_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 360";
-                           ticks = "0";
-                           value = "360";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_phiVariance_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getText());";
-                        };             
-                     };
-                     new GuiControl(){ // Emitter Offset
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Offset";
-                        };
-                        new GuiSliderCtrl(PEE_ejectionOffset) {
-                           internalName = "PEE_ejectionOffset_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_ejectionOffset_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getText());";
-                        };
-					 };
-                     new GuiControl(){ // Emitter Offset Variance
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "OffsetVariance";
-                        };
-                        new GuiSliderCtrl(PEE_ejectionOffsetVariance) {
-                           internalName = "PEE_ejectionOffsetVariance_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 25";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_ejectionOffsetVariance_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getText());";
-                        };               
-                     };
-                  }; // end stack
-               }; // end "spread" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Particles";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(PEE_EmitterParticle1){ // emmiter particle 1
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Particle 1";
-                        };
-                        new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector1) {
-                           internalName = "PopUpMenu";
-                           Profile = "ToolsGuiPopUpMenuProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_textedit;
-                           Extent = $PE_guielement_ext_textedit;
-                           text = "";
-                           command = "PE_EmitterEditor.updateParticlesFields($ThisControl);";
-                        };  
-                     };
-                     new GuiControl(PEE_EmitterParticle2){ // emmiter particle 2
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Particle 2";
-                        };
-                        new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector2) {
-                           internalName = "PopUpMenu";
-                           Profile = "ToolsGuiPopUpMenuProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_textedit;
-                           Extent = $PE_guielement_ext_textedit;
-                           text = "None";
-                           command = "PE_EmitterEditor.updateParticlesFields();";
-                        };
-                        // Clear particle 2
-                        new GuiBitmapButtonCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "56 1";
-                           Extent = "17 17";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "$_particleId = PEE_EmitterParticle2-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle2-->PopUpMenu.setSelected( $_particleId );PE_EmitterEditor.updateParticlesFields();"; 
-                           hovertime = "1000";
-                           tooltip = "Clear Particle 2 from Emitter";
-                           text = "";
-                           bitmapAsset = "ToolsModule:clear_icon_n_image";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                        }; 
-                     };
-                     new GuiControl(PEE_EmitterParticle3){ // emmiter particle 3
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Particle 3";
-                        };
-                        new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector3) {
-                           internalName = "PopUpMenu";
-                           Profile = "ToolsGuiPopUpMenuProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_textedit;
-                           Extent = $PE_guielement_ext_textedit;
-                           text = "None";
-                           command = "PE_EmitterEditor.updateParticlesFields();";
-                        };
-                        // Clear particle 3
-                        new GuiBitmapButtonCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "56 1";
-                           Extent = "17 17";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "$_particleId = PEE_EmitterParticle3-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle3-->PopUpMenu.setSelected( $_particleId );PE_EmitterEditor.updateParticlesFields();"; 
-                           hovertime = "1000";
-                           tooltip = "Clear Particle 3 from Emitter";
-                           text = "";
-                           bitmapAsset = "ToolsModule:clear_icon_n_image";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                        }; 
-                     };
-                     new GuiControl(PEE_EmitterParticle4){ // emmiter particle 4
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Particle 4";
-                        };
-                        new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector4) {
-                           internalName = "PopUpMenu";
-                           Profile = "ToolsGuiPopUpMenuProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_textedit;
-                           Extent = $PE_guielement_ext_textedit;
-                           text = "None";
-                           command = "PE_EmitterEditor.updateParticlesFields();";
-                        };
-                        // Clear particle 4
-                        new GuiBitmapButtonCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "56 1";
-                           Extent = "17 17";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "$_particleId = PEE_EmitterParticle4-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle4-->PopUpMenu.setSelected( $_particleId );PE_EmitterEditor.updateParticlesFields();"; 
-                           hovertime = "1000";
-                           tooltip = "Clear Particle 4 from Emitter";
-                           text = "";
-                           bitmapAsset = "ToolsModule:clear_icon_n_image";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                        }; 
-                     };
-                  }; // end stack
-               }; // end "particles" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Blending";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(){ // Blend type
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Blend Type";
-                        };
-                        new GuiPopUpMenuCtrl() {
-                           Profile = "ToolsGuiPopUpMenuProfile";
-                           internalName = "PEE_blendType";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_textedit;
-                           Extent = $PE_guielement_ext_textedit;
-                           command = "PE_EmitterEditor.updateEmitter( \"blendStyle\", $ThisControl.getText());";
-                        };
-                     };  
-                     new GuiControl(){ // softness Distance 
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Softness Distance ";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEE_softnessDistance_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1000";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_softnessDistance_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Ambient Factor 
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Ambient Factor";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEE_ambientFactor_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 10";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEE_ambientFactor_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getText));";
-                        };
-                     };
-                        
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Sort Particles
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Sort Particles";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEE_softParticles";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           text = "";
-                           command = "PE_EmitterEditor.updateEmitter( \"softParticles\", $ThisControl.getValue());";
-                        };
-                     };
-                     new GuiControl(){ // Emitter Reverse Order
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Reverse Order";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEE_reverseOrder";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           text = "";
-                           command = "PE_EmitterEditor.updateEmitter( \"reverseOrder\", $ThisControl.getValue());";
-                        };
-                     };
-                     new GuiControl(){ // Emitter Use Emitter Size
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Use Emitter Size";
-                        };
-                        new GuiCheckBoxCtrl(PEE_useEmitterSizes) {
-                           internalName = "PEE_useEmitterSizes";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           text = "";
-                           command = "PE_EmitterEditor.updateEmitter( \"useEmitterSizes\", $ThisControl.getValue());";
-                        };
-                     };
-                     new GuiControl(){ // Emitter use Material Effect Color
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_checkbox_name;
-                           text = "Use Material Effect Color";
-                        };
-                        new GuiCheckBoxCtrl(PEE_useEmitterColors) {
-                           internalName = "PEE_useEmitterColors";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_checkbox;
-                           Extent = $PE_guielement_ext_checkbox;
-                           text = "";
-                           command = "PE_EmitterEditor.updateEmitter( \"useEmitterColors\", $ThisControl.getValue());";
-                        };
-                     };
-                  }; // end stack
-               }; // end "Blending" rollout
-            };// end stack "Emitter"
-         };// end scroll "Emitter"
-      };// end tab page "Emitter"
-      new GuiTabPageCtrl(PE_ParticleEditor) {
-         canSaveDynamicFields = "0";
-         Enabled = "1";
-         isContainer = "1";
-         Profile = "ToolsGuiEditorTabPage";
-         HorizSizing = "width";
-         VertSizing = "height";
-         position = "0 19";
-         Extent = "197 271";
-         MinExtent = "8 2";
-         canSave = "1";
-         Visible = "1";
-         hovertime = "1000";
-         Margin = "0 0 0 0";
-         Padding = "0 0 0 0";
-         AnchorTop = "1";
-         AnchorBottom = "0";
-         AnchorLeft = "1";
-         AnchorRight = "0";
-         text = "Particle";
-         maxLength = "1024";
-         
-         new GuiScrollCtrl() {
-            canSaveDynamicFields = "0";
-            Enabled = "1";
-            isContainer = "1";
-            Profile = "ToolsGuiScrollProfile";
-            HorizSizing = "width";
-            VertSizing = "height";
-            Position = "0 0";
-            Extent = "197 271";
-            MinExtent = "8 8";
-            canSave = "1";
-            Visible = "1";
-            hovertime = "1000";
-            willFirstRespond = "1";
-            hScrollBar = "alwaysOff";
-            vScrollBar = "dynamic";
-            lockHorizScroll = false;
-            lockVertScroll = "false";
-            constantThumbHeight = "0";
-            childMargin = "0 0";
-            
-            new GuiStackControl() {
-               StackingType = "Vertical";
-               HorizStacking = "Left to Right";
-               VertStacking = "Top to Bottom";
-               Padding = "0";
-               canSaveDynamicFields = "0";
-               Enabled = "1";
-               isContainer = "1";
-               Profile = "ToolsGuiDefaultProfile";
-               HorizSizing = "width";
-               VertSizing = "bottom";
-               Position = "1 3";
-               Extent = "197 16";
-               MinExtent = "16 16";
-               canSave = "1";
-               isDecoy = "0";
-               Visible = "1";
-               tooltipprofile = "ToolsGuiToolTipProfile";
-               hovertime = "1000";
-               
-               new GuiControl(PEP_ParticleSelector_Control){ // PEP_ParticleSelector
-                  isContainer = "1";
-                  class = "QuickEditDropDownTextEditCtrl";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = $PE_guielement_pos_single_container ;
-                  Extent = "197 26" ;
-                  
-                  new GuiPopUpMenuCtrl(PEP_ParticleSelector) {
-                     internalName =  "PopUpMenu";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiPopUpMenuProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     position = "4 4";
-                     Extent = "123 18";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     Command = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.onNewParticle();";
-                     hovertime = "1000";
-                     Margin = "0 0 0 0";
-                     Padding = "0 0 0 0";
-                     AnchorTop = "1";
-                     AnchorBottom = "0";
-                     AnchorLeft = "1";
-                     AnchorRight = "0";
-                     maxLength = "255";
-                     maxPopupHeight = "200";
-                     sbUsesNAColor = "0";
-                     reverseTextList = "0";
-                     bitmapBounds = "16 16";
-                  };
-                  new GuiTextEditCtrl() {
-                     internalName = "TextEdit";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "GuiDropdownTextEditProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     position = "4 4";
-                     Extent = "107 18";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     hovertime = "1000";
-                     Margin = "0 0 0 0";
-                     Padding = "0 0 0 0";
-                     AnchorTop = "1";
-                     AnchorBottom = "0";
-                     AnchorLeft = "1";
-                     AnchorRight = "0";
-                     text = "None";
-                     maxLength = "1024";
-                     altCommand = "$ThisControl.getParent().updateFromChild($ThisControl);";
-                  }; 
-                  new GuiBitmapButtonCtrl( PEP_NewParticleButton ) {
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "left";
-                     VertSizing = "bottom";
-                     position = "131 5";
-                     Extent = "17 17";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     hovertime = "1000";
-                     groupNum = "-1";
-                     buttonType = "PushButton";
-                     useMouseEvents = "0";
-                     bitmapAsset = "ToolsModule:new_n_image";
-                     tooltip = "Add New Particle To Current Emitter";
-                     useModifiers = "1";
-                  };
-                  new GuiBitmapButtonCtrl() {
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "left";
-                     VertSizing = "bottom";
-                     position = "147 5";
-                     Extent = "17 17";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     hovertime = "1000";
-                     groupNum = "-1";
-                     buttonType = "PushButton";
-                     useMouseEvents = "0";
-                     bitmapAsset = "ToolsModule:save_icon_n_image";
-                     command = "PE_ParticleEditor.saveParticle( PE_ParticleEditor.currParticle );";
-                     tooltip = "Save Current Particle";
-                  };
-                  new GuiBitmapButtonCtrl() {
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "0";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "left";
-                     VertSizing = "bottom";
-                     position = "164 5";
-                     Extent = "17 17";
-                     MinExtent = "8 2";
-                     canSave = "1";
-                     Visible = "1";
-                     Command = "PE_ParticleEditor.showDeleteDialog();";
-                     hovertime = "1000";
-                     groupNum = "-1";
-                     buttonType = "PushButton";
-                     useMouseEvents = "0";
-                     bitmapAsset = "ToolsModule:delete_n_image";
-                     tooltip = "Delete Current Particle";
-                  };
-               };
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Basic";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiContainer(){ // particle texture map
-                        profile="ToolsGuiDefaultProfile";
-                        isContainer = "1";
-                        position = "0 0";
-                        Extent = "185 52";
-                        HorizSizing = "width";
-                        
-                        new GuiBitmapCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiDefaultProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "1 1";
-                           Extent = "48 48";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           bitmapAsset = "ToolsModule:unknownImage_image";
-                           wrap = "0";
-                        };
-                        new GuiTextCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "EditorTextProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "56 -2";
-                           Extent = "72 18";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "Texture Map";
-                           maxLength = "1024";
-                        };
-                        new GuiBitmapButtonCtrl() {
-                           internalName = "PEP_previewImage";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiDefaultProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "1 1";
-                           Extent = "48 48";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           tooltipprofile = "ToolsGuiDefaultProfile";
-                           ToolTip = "Edit Selected Particle.";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                           bitmapAsset = "ToolsModule:cubemapBtnBorder_n_image";
-                        };
-                        new GuiBitmapButtonCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiDefaultProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "1 1";
-                           Extent = "48 48";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           tooltipprofile = "ToolsGuiDefaultProfile";
-                           ToolTip = "Edit Selected Particle.";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                           bitmapAsset = "ToolsModule:cubemapBtnBorder_n_image";
-                           Command = "PE_ParticleEditor.updateParticleTexture(1);";
-                        };
-                        new GuiCheckBoxCtrl() {
-                           internalName = "PEP_inverseAlpha";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = "55 14";
-                           Extent = "84 18";
-                           MinExtent = "8 2";
-                           text = "Inverse Alpha";
-                           command = "PE_ParticleEditor.updateParticle( \"useInvAlpha\", $ThisControl.getValue());";
-                        };
-                        new GuiTextEditCtrl(PEP_textureName) {
-                           internalName = "PEP_previewImageName";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = "55 31";
-                           Extent = "120 18";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "None";
-                           maxLength = "1024";
-                        };
-                        new GuiButtonCtrl(){
-                           profile="ToolsGuiButtonProfile";
-                           text ="Edit";
-                           HorizSizing = "left";
-                           VertSizing = "bottom"; 
-                           position = "138 0";
-                           Extent = "36 18" ;
-                           buttonType = "PushButton";
-                           Command = "PE_ParticleEditor.updateParticleTexture(1);";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        //visible = false;
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // particle life
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "Life";
-                           maxLength = "255";
-                        };
-                        new GuiSliderCtrl(PEP_lifetimeMS) {
-                           internalName = "PEP_lifetimeMS_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1"; 
-                           Command = "PE_ParticleEditor.updateLifeFields( false, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( false, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "1 9000";
-                           ticks = "0";
-                           value = "3000";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_lifetimeMS_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( false, $ThisControl.getText() );";
-                        };
-                     };
-                     new GuiControl(){ // particle life Random
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "Life Random";
-                           maxLength = "255";
-                        };
-                        new GuiSliderCtrl(PEP_lifetimeVarianceMS) {
-                           internalName = "PEP_lifetimeVarianceMS_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateLifeFields( true, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( true, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 8999";
-                           ticks = "0";
-                           value = "3000";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_lifetimeVarianceMS_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( true, $ThisControl.getText() );";
-                        };
-                     };
-                  }; // end stack
-               }; // end "Particles Basic" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Motion";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(){ // Particle Initial speed
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Initial Speed";
-                        };
-                        new GuiSliderCtrl(PEP_inheritedVelFactor) {
-                           internalName = "PEP_inheritedVelFactor_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 10";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_inheritedVelFactor_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Acceleration
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Acceleration";
-                        };
-                        new GuiSliderCtrl(PEP_constantAcceleration) {
-                           internalName = "PEP_constantAcceleration_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getValue(), true, false);";
-                           hovertime = "1000";
-                           range = "-10 10";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_constantAcceleration_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getText());";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Particle Gravity
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiBitmapCtrl(){ // 0 Gravity
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "0 Gravity";
-                        };
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Gravity";
-                        };
-                        new GuiSliderCtrl(PEP_gravityCoefficient) {
-                           internalName = "PEP_gravityCoefficient_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "-1 1";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_gravityCoefficient_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Drag
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Drag";
-                        };
-                        new GuiSliderCtrl(PEP_dragCoefficient) {
-                           internalName = "PEP_dragCoefficient_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0.298143";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_dragCoefficient_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getText());";
-                        };
-                     }; //End Particle Drag
-                     new GuiControl(){ // Particle Wind
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Wind Coeff";
-                        };
-                        new GuiSliderCtrl(PEP_windCoefficient) {
-                           internalName = "PEP_windCoefficient_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateParticle( \"windCoefficient\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"windCoefficient\", $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0.298143";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_windCoefficient_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"windCoefficient\", $ThisControl.getText());";
-                        };
-                     };
-                  }; // end stack
-               }; // end "motion" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Spin";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(){ // Particle spin Min
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiBitmapCtrl(){ // No Spin
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "No Spin";
-                        };
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Spin Min";
-                        };
-                        new GuiSliderCtrl(PEP_spinRandomMin) {
-                           internalName = "PEP_spinRandomMin_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateSpinFields( true, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( true, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "-1000 999";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_spinRandomMin_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( true, $ThisControl.getText() );";
-                        };
-                     };
-                     new GuiControl(){ // Particle Spin Max
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiBitmapCtrl(){ // No Spin
-                           HorizSizing = "left";
-                           position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0";
-                           Extent = "2 18";
-                           minExtent = "0 0";
-                           bitmapAsset = "ToolsModule:separator_h_image";
-                           tooltip = "No Spin";
-                        };
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Spin Max";
-                        };
-                        new GuiSliderCtrl(PEP_spinRandomMax) {
-                           internalName = "PEP_spinRandomMax_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "PE_ParticleEditor.updateSpinFields( false, $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( false, $ThisControl.getValue(), true, false );";
-                           hovertime = "1000";
-                           range = "-999 1000";
-                           ticks = "0";
-                           value = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_spinRandomMax_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( false, $ThisControl.getText() );";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Particle spin Speed
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Spin Speed";
-                        };
-                        new GuiSliderCtrl(PEP_spinSpeed) {
-                           internalName = "PEP_spinSpeed_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_spinSpeed_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getText());";
-                        };
-                     };
-                  }; // end stack
-               }; // end "Spin" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Animation";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiCheckBoxCtrl() {
-                        internalName = "PEP_animateTexture";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        position = "55 14";
-                        Extent = "84 18";
-                        MinExtent = "8 2";
-                        text = "Animate Texture";
-                        command = "PE_ParticleEditor.updateParticle( \"animateTexture\", $ThisControl.getValue());";
-                     };
-                     new GuiControl(){ // Particle framesPerSec
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "framesPerSec";
-                        };
-                        new GuiSliderCtrl(PEP_framesPerSec) {
-                           internalName = "PEP_framesPerSec_slider";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           range = "0 60";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"framesPerSec\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"framesPerSec\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_framesPerSec_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"framesPerSec\", $ThisControl.getText());";
-                        };
-                     }; // end framesPerSec
-                     new GuiControl(){ // Particle animTexFramesList
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container;
-                        Extent = $PE_guielement_ext_single_container;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "animTexFrames";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_animTexFramesList_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_textedit;
-                           Extent = $PE_guielement_ext_textedit;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"animTexFrames\", $ThisControl.getText());";
-                        };
-				    }; // end animTexFramesList
-                     new GuiControl(){ // Particle animTileCount
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container;
-                        Extent = $PE_guielement_ext_single_container;
-						
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "TileCount (X Y)";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_animTileCount_textEdit";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"animTexTiling\", $ThisControl.getText());";
-                        };
-				    }; // end animTileCount
-                  }; // end stack
-               }; // end "Anim" rollout
-               new GuiRolloutCtrl() {
-                  class = "BehaviorQuickEditRollout";
-                  superclass = LBQuickEditRollout;
-                  Profile = "GuiRolloutProfile";
-                  HorizSizing = "width";
-                  VertSizing = "bottom";
-                  Position = "0 0";
-                  Extent = "197 0";
-                  Caption = "Overtime";
-                  Margin = "4 4 4 0";
-                  DragSizable = false;
-                  container = true;
-                  
-                  new GuiStackControl() {
-                     StackingType = "Vertical";
-                     HorizStacking = "Left to Right";
-                     VertStacking = "Top to Bottom";
-                     Padding = "0";
-                     canSaveDynamicFields = "0";
-                     Enabled = "1";
-                     isContainer = "1";
-                     Profile = "ToolsGuiDefaultProfile";
-                     HorizSizing = "width";
-                     VertSizing = "bottom";
-                     Position = "1 3";
-                     Extent = "197 16";
-                     MinExtent = "16 16";
-                     canSave = "1";
-                     isDecoy = "0";
-                     Visible = "1";
-                     tooltipprofile = "ToolsGuiToolTipProfile";
-                     hovertime = "1000";
-                     
-                     new GuiControl(){ // Particle Point Colors
-                        class = "";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Colors";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch0) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "20 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[0], \"PE_ColorTintSwatch0.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "0";
-                           class = "PE_ColorTintSwatch";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch1) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "40 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[1], \"PE_ColorTintSwatch1.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "1";
-                           class = "PE_ColorTintSwatch";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch2) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "60 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[2], \"PE_ColorTintSwatch2.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "2";
-                           class = "PE_ColorTintSwatch";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch3) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "80 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[3], \"PE_ColorTintSwatch3.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "3";
-                           class = "PE_ColorTintSwatch";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch4) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "100 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[4], \"PE_ColorTintSwatch4.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "4";
-                           class = "PE_ColorTintSwatch";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch5) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "120 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[5], \"PE_ColorTintSwatch5.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "5";
-                           class = "PE_ColorTintSwatch";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch6) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "140 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[6], \"PE_ColorTintSwatch6.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "6";
-                           class = "PE_ColorTintSwatch";
-                        };
-                        new GuiSwatchButtonCtrl(PE_ColorTintSwatch7) {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "160 0";
-                           Extent = $PE_guielement_ext_colorpicker;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF( PE_ParticleEditor.currParticle.colors[7], \"PE_ColorTintSwatch7.updateParticleColor\");";
-                           altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "1";
-                           arrayNum = "7";
-                           class = "PE_ColorTintSwatch";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 1";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider0";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit0";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 2";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider1";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit1";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 3";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider2";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit2";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 4";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider3";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit3";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 5";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider4";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[4]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[4]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit4";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[4]\", $ThisControl.getText());";
-                        };
-					};
-                     new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 6";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider5";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[5]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[5]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit5";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[5]\", $ThisControl.getText());";
-                        };
-					};
-					new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 7";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider6";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[6]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[6]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit6";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[6]\", $ThisControl.getText());";
-                        };
-					};
-                     new GuiControl(){ // Particle Point Size
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Size 8";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointSize_slider7";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 50";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"sizes[7]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[7]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointSize_textEdit7";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[7]\", $ThisControl.getText());";
-                        };
-                     };
-                     
-                     new GuiControl(){ // Spacer ----------------------------
-                        isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8";
-                        new GuiBitmapCtrl(){
-                           position="0 3"; extent ="188 2"; HorizSizing = "width";
-                           bitmapAsset ="ToolsModule:separator_v_image"; 
-                        };
-                     };// end spacer ----------------------------------------
-                     
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 1";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider0";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit0";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 2";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider1";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit1";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 3";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider2";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit2";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 4";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider3";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit3";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 5";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider4";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[4]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[4]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit4";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[4]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 6";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider5";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[5]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[5]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit5";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[5]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 7";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider6";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[6]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[6]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit6";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[6]\", $ThisControl.getText());";
-                        };
-                     };
-                     new GuiControl(){ // Particle Point Time
-                        class = "AggregateControl";
-                        isContainer = "1";
-                        HorizSizing = "width";
-                        VertSizing = "bottom";
-                        Position = $PE_guielement_pos_single_container ;
-                        Extent = $PE_guielement_ext_single_container ;
-                        
-                        new GuiTextCtrl() {
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_name;
-                           Extent = $PE_guielement_ext_name;
-                           text = "Time 8";
-                        };
-                        new GuiSliderCtrl() {
-                           internalName = "PEP_pointTime_slider7";
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiSliderProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_slider;
-                           Extent = $PE_guielement_ext_slider;
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "";
-                           hovertime = "1000";
-                           range = "0 1";
-                           ticks = "0";
-                           value = "0";
-                           Command = "PE_ParticleEditor.updateParticle( \"times[7]\", $ThisControl.getValue(), true, true );";
-                           altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[7]\", $ThisControl.getValue(), true, false );";
-                        };
-                        new GuiTextEditCtrl() {
-                           internalName = "PEP_pointTime_textEdit7";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = $PE_guielement_pos_value;
-                           Extent = $PE_guielement_ext_value;
-                           altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[7]\", $ThisControl.getText());";
-                        };
-                     };
-                  }; // end stack
-               }; // end "Overtime" rollout
-            };// end stack "Particles"
-         };// end scroll "Particles"
-      };// end tab page "Particles"
-   };// end tab book
-   new GuiBitmapButtonCtrl() {
-      canSaveDynamicFields = "0";
-      Enabled = "1";
-      isContainer = "0";
-      Profile = "ToolsGuiButtonProfile";
-      HorizSizing = "left";
-      VertSizing = "bottom";
-      Position = "169 25";
-      Extent = "18 18";
-      MinExtent = "8 2";
-      canSave = "1";
-      Visible = "1";
-      Command = "ParticleEditor.updateEmitterNode();";
-      tooltipprofile = "ToolsGuiToolTipProfile";
-      ToolTip = "Play Particle Effect from Start";
-      hovertime = "1000";
-      bitmapAsset = "ToolsModule:play_btn_n_image";
-      buttonType = "PushButton";
-      groupNum = "-1";
-      text = "";
-      useMouseEvents = "0";
-   };
-   
-   new GuiBitmapButtonCtrl() {
-      canSaveDynamicFields = "0";
-      Enabled = "1";
-      isContainer = "0";
-      Profile = "ToolsGuiButtonProfile";
-      HorizSizing = "left";
-      VertSizing = "bottom";
-      Position = "189 26";
-      Extent = "16 16";
-      MinExtent = "8 2";
-      canSave = "1";
-      Visible = "1";
-      Command = "ParticleEditor.resetEmitterNode();";
-      tooltipprofile = "ToolsGuiToolTipProfile";
-      ToolTip = "Drops Particle Effect in front of the Camera";
-      hovertime = "1000";
-      bitmapAsset = "ToolsModule:camera_image";
-      buttonType = "PushButton";
-      groupNum = "-1";
-      text = "";
-      useMouseEvents = "0";
-   };
-};// end window
-//--- OBJECT WRITE END ---

+ 86 - 0
Templates/BaseGame/game/tools/particleEditor/guis/PETabTemplate.gui

@@ -0,0 +1,86 @@
+$guiContent = new GuiTabPageCtrl() {
+   position = "2 50";
+   extent = "361 615";
+   horizSizing = "width";
+   vertSizing = "height";
+   profile = "GuiDefaultProfile";
+   tooltipProfile = "GuiToolTipProfile";
+   fitBook = "1";
+
+   new GuiControl() {
+      extent = "342 26";
+      horizSizing = "width";
+      profile = "GuiDefaultProfile";
+      tooltipProfile = "GuiToolTipProfile";
+      isContainer = "1";
+      class = "QuickEditDropDownTextEditCtrl";
+
+      new GuiButtonCtrl() {
+         Text = "";
+         maxLength = "255";
+         position = "4 4";
+         extent = "268 18";
+         horizSizing = "width";
+         profile = "ToolsGuiButtonProfile";
+         command = "ParticleEditorGui.openList($ThisControl.getParent().getParent());";
+         tooltipProfile = "GuiToolTipProfile";
+         isContainer = "0";
+         internalName = "PopupMenu";
+      };
+      new GuiBitmapButtonCtrl() {
+         BitmapAsset = "ToolsModule:new_n_image";
+         position = "276 5";
+         extent = "17 17";
+         horizSizing = "left";
+         profile = "ToolsGuiDefaultProfile";
+         command = "";
+         tooltipProfile = "GuiToolTipProfile";
+         ToolTip = "Create New";
+         internalName = "CreateNewBtn";
+      };
+      new GuiBitmapButtonCtrl() {
+         BitmapAsset = "ToolsModule:save_icon_n_image";
+         position = "292 5";
+         extent = "17 17";
+         horizSizing = "left";
+         profile = "ToolsGuiDefaultProfile";
+         command = "";
+         tooltipProfile = "GuiToolTipProfile";
+         ToolTip = "Save Current";
+         internalName = "SaveCurrentBtn";
+      };
+      new GuiBitmapButtonCtrl() {
+         BitmapAsset = "ToolsModule:delete_n_image";
+         position = "309 5";
+         extent = "17 17";
+         horizSizing = "left";
+         profile = "ToolsGuiDefaultProfile";
+         command = "";
+         tooltipProfile = "GuiToolTipProfile";
+         ToolTip = "Delete Current";
+         internalName = "DeleteCurrentBtn";
+      };
+   };
+   new GuiScrollCtrl() {
+      hScrollBar = "alwaysOff";
+      vScrollBar = "dynamic";
+      position = "0 30";
+      extent = "356 586";
+      minExtent = "8 8";
+      horizSizing = "width";
+      vertSizing = "height";
+      profile = "ToolsGuiScrollProfile";
+      tooltipProfile = "GuiToolTipProfile";
+
+      new GuiInspector() {
+         class = "ParticleEditorInspector";
+         groupFilters = "-Internal -Editing -Object -Persistence -Dynamic Fields -Scripting -AFX -AFX Pooled Particles";
+         position = "1 1";
+         extent = "339 48";
+         horizSizing = "width";
+         profile = "GuiInspectorProfile";
+         tooltipProfile = "GuiToolTipProfile";
+         internalName = "inspector";
+      };
+   };
+};

+ 83 - 0
Templates/BaseGame/game/tools/particleEditor/guis/ParticleEditor.ed.gui

@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------------
+// Torque
+// Copyright GarageGames, LLC 2011
+//-----------------------------------------------------------------------------
+
+$PE_guielement_pos_single_container = "0 0";
+$PE_guielement_ext_single_container = "184 20";
+$PE_guielement_pos_name = "1 0";
+$PE_guielement_ext_name = "70 18";
+$PE_guielement_pos_slider = "74 2";
+$PE_guielement_ext_slider = "58 12";
+$PE_guielement_pos_value = "138 0";
+$PE_guielement_ext_value = "36 18";
+$PE_guielement_pos_textedit = "74 0";
+$PE_guielement_ext_textedit = "100 18";
+$PE_guielement_ext_checkbox_name = "156 18";
+$PE_guielement_pos_checkbox = "161 0";
+$PE_guielement_ext_checkbox = "15 18";
+$PE_guielement_pos_colorpicker = "158 0";
+$PE_guielement_ext_colorpicker = "18 18";
+
+//--- OBJECT WRITE BEGIN ---
+$guiContent = new GuiControl(ParticleEditorGui) {
+   extent = "1280 720";
+   profile = "GuiNonModalDefaultProfile";
+   tooltipProfile = "GuiToolTipProfile";
+   isContainer = "1";
+   canSaveDynamicFields = "0";
+
+   new GuiWindowCollapseCtrl(PE_Window) {
+      Text = ":: Particle Editor - Emitters";
+      canMove = "0";
+      canClose = "0";
+      canMinimize = "0";
+      canMaximize = "0";
+      canCollapse = "0";
+      edgeSnap = "0";
+      position = "920 39";
+      extent = "360 1345";
+      minExtent = "300 140";
+      horizSizing = "windowRelative";
+      vertSizing = "windowRelative";
+      profile = "ToolsGuiWindowProfile";
+      tooltipProfile = "GuiToolTipProfile";
+
+      new GuiTabBookCtrl(PE_TabBook) {
+         tabMargin = "0";
+         tabHeight = "20";
+         selectedPage = "0";
+         docking = "Client";
+         margin = "3 2 3 3";
+         position = "9 29";
+         extent = "342 1306";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "ToolsGuiTabBookProfile";
+         tooltipProfile = "GuiToolTipProfile";
+         internalName = "EditorTabBook";
+      };
+      
+      new GuiBitmapButtonCtrl() {
+         BitmapAsset = "ToolsModule:play_btn_n_image";
+         position = "318 25";
+         extent = "18 18";
+         horizSizing = "left";
+         profile = "ToolsGuiButtonProfile";
+         command = "ParticleEditor.updateEmitterNode();";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         ToolTip = "Play Particle Effect from Start";
+      };
+      new GuiBitmapButtonCtrl() {
+         BitmapAsset = "ToolsModule:camera_image";
+         position = "338 26";
+         extent = "16 16";
+         horizSizing = "left";
+         profile = "ToolsGuiButtonProfile";
+         command = "ParticleEditor.resetEmitterNode();";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         ToolTip = "Drops Particle Effect in front of the Camera";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 197 - 0
Templates/BaseGame/game/tools/particleEditor/guis/createNewPrompt.ed.gui

@@ -0,0 +1,197 @@
+//--- OBJECT WRITE BEGIN ---
+$guiContent = new GuiControl(ParticleEditorCreatePrompt) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "ToolsGuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "ToolsGuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      fixedAspectRatio = "0";
+
+   new GuiWindowCtrl() {
+      text = "Create New Datablock";
+      resizeWidth = "0";
+      resizeHeight = "0";
+      canMove = "0";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      canCollapse = "0";
+      closeCommand = "canvas.popDialog(ParticleEditorCreatePrompt);";
+      edgeSnap = "0";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "758 420";
+      extent = "400 167";
+      minExtent = "8 2";
+      horizSizing = "center";
+      vertSizing = "center";
+      profile = "ToolsGuiWindowProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "ToolsGuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      internalName = "promptWindow";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiTextCtrl() {
+         text = "Your new object must have a name";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "7 26";
+         extent = "250 15";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "ToolsGuiTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+         internalName = "namePromptText";
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         placeholderText = "Name";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "7 45";
+         extent = "294 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "ToolsGuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "nameText";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Create";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "111 137";
+         extent = "122 22";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "ToolsGuiButtonProfile";
+         visible = "1";
+         active = "1";
+         accelerator = "return";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+         internalName = "createBtn";
+      };
+      new GuiButtonCtrl() {
+         text = "Cancel";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "239 137";
+         extent = "63 22";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "ToolsGuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "canvas.popDialog(ParticleEditorCreatePrompt);";
+         accelerator = "escape";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Inherit values from";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "7 66";
+         extent = "120 17";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "ToolsGuiTextProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiPopUpMenuCtrl() {
+         maxPopupHeight = "200";
+         sbUsesNAColor = "0";
+         reverseTextList = "0";
+         bitmapBounds = "16 16";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "7 87";
+         extent = "294 19";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "ToolsGuiPopUpMenuProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "ToolsGuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "CopySourceDropdown";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 33 - 0
Templates/BaseGame/game/tools/particleEditor/guis/createNewPrompt.ed.tscript

@@ -0,0 +1,33 @@
+function ParticleEditorCreatePrompt::show(%this, %name, %typeFilter, %callback)
+{
+   Canvas.pushDialog(%this);
+   %this-->promptWindow.text = "Create New " @ %name;
+   
+   %this-->namePromptText.text = "Your new " @ %name @ " must have a name";
+   %this-->nameText.placeholderText = "new" @ %name;
+   
+   %this-->createBtn.command = %callback;
+   
+   // Need to prompt for a name.
+   %this-->nameText.setText("");
+   %this-->nameText.selectAllText();
+   
+   // Populate the copy source dropdown.
+   
+   %list = %this-->CopySourceDropdown;
+   %list.clear();
+   %list.add( "", 0 );
+   
+   %set = DataBlockSet;
+   %count = %set.getCount();
+   for( %i = 0; %i < %count; %i ++ )
+   {
+      %datablock = %set.getObject( %i );
+      %datablockClass = %datablock.getClassName();
+      
+      if( !isMemberOfClass( %datablockClass, %typeFilter ) )
+         continue;
+         
+      %list.add( %datablock.getName(), %i + 1 );
+   }
+}

+ 141 - 166
Templates/BaseGame/game/tools/particleEditor/particleEditor.ed.tscript → Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript

@@ -40,145 +40,126 @@
 function ParticleEditor::initEditor( %this )
 {
    echo( "Initializing ParticleEmitterData and ParticleData DataBlocks..." );
+
+   PE_TabBook.clear();
    
-   datablock ParticleEmitterData(PE_EmitterEditor_NotDirtyEmitter)
-   {
-      particles = "DefaultParticle";
-   };
-   datablock ParticleData(PE_ParticleEditor_NotDirtyParticle)
+   for(%i=0; %i < PE_ParticleDataTypes.count(); %i++)
    {
-      textureName = "art/particles/defaultParticle";
-   };
-   
-   PE_UnlistedEmitters.add( PE_EmitterEditor_NotDirtyEmitter );
-   PE_UnlistedEmitters.add( PE_ParticleEditor_NotDirtyParticle );
-   
-   PEE_EmitterSelector.clear();
-   PEE_EmitterParticleSelector1.clear();
-   PEE_EmitterParticleSelector2.clear();
-   PEE_EmitterParticleSelector3.clear();
-   PEE_EmitterParticleSelector4.clear();
-   
-   PEP_ParticleSelector.clear();
-   
-   ParticleEditor.createParticleList();
+      %groupName = PE_ParticleDataTypes.getKey(%i);
+      %typesList = getField(PE_ParticleDataTypes.getValue(%i), 0);
+      %editorName = getField(PE_ParticleDataTypes.getValue(%i), 1);
+      
+      if(exec("./PETabTemplate.gui"))
+      {
+         echo("MADE A NEW TAB PAGE: " @ $guiContent);
          
-   PEE_EmitterParticleSelector2.add( "None", 0 );
-   PEE_EmitterParticleSelector3.add( "None", 0 );
-   PEE_EmitterParticleSelector4.add( "None", 0 );
-   
-   PEE_EmitterParticleSelector1.sort();
-   PEE_EmitterParticleSelector2.sort();
-   PEE_EmitterParticleSelector3.sort();
-   PEE_EmitterParticleSelector4.sort();
+         $guiContent.text = %groupName;
+         $guiContent.typesList = %typesList;
+         $guiContent.setName(%editorName);
+         
+         $guiContent.saver = new PersistenceManager( "PE_" @ %groupName @ "Saver" );
+         $guiContent.unlistedSet = new SimSet( "PE_Unlisted" @ %groupName );
+         
+         $guiContent-->CreateNewBtn.tooltip = "Create New " @ %groupName;
+         $guiContent-->CreateNewBtn.command = %editorName @ ".showNewDialog();";
          
-   PE_EmitterEditor-->PEE_blendType.clear();
-   PE_EmitterEditor-->PEE_blendType.add( "NORMAL", 0 );
-   PE_EmitterEditor-->PEE_blendType.add( "ADDITIVE", 1 );
-   PE_EmitterEditor-->PEE_blendType.add( "SUBTRACTIVE", 2 );
-   PE_EmitterEditor-->PEE_blendType.add( "PREMULTALPHA", 3 );
+         $guiContent-->SaveCurrentBtn.tooltip = "Save Current " @ %groupName;
+         $guiContent-->SaveCurrentBtn.command = %editorName @ ".save" @ %groupName @ "();";
+         
+         $guiContent-->DeleteCurrentBtn.tooltip = "Delete Current " @ %groupName;
+         $guiContent-->DeleteCurrentBtn.command = %editorName @ ".showDeleteDialog();";
+         
+         PE_TabBook.add($guiContent);
+         
+         if($guiContent.isMethod("init"))
+            $guiContent.init();
+      }
+      else
+      {
+         error("Something went wrong when trying to generatea a ParticleEditor tab for type: " @ %groupName);
+      }
+   }
    
-
-   PEE_EmitterSelector.setFirstSelected();
-
    PE_Window-->EditorTabBook.selectPage( 0 );
 }
 
-function ParticleEditor::createParticleList( %this )
+function ParticleEditorGui::openList( %this, %editorCtrl )
 {
    // This function creates the list of all particles and particle emitters
    
-   %emitterCount = 0;
-   %particleCount = 0;
+   %listCount = 0;
+   
+   %listSet = new SimSet(){ internalName = %editorCtrl.text; };
    
    foreach( %obj in DatablockGroup )
    {
-      if( %obj.isMemberOfClass( "ParticleEmitterData" ) )
+      %typesListCount = getWordCount(%editorCtrl.typesList);
+      for(%i=0; %i < %typesListCount; %i++)
       {
-         // Filter out emitters on the PE_UnlistedEmitters list.
+         %type = getWord(%editorCtrl.typesList, %i);
          
-         %unlistedFound = false;
-         foreach( %unlisted in PE_UnlistedEmitters )
-            if( %unlisted.getId() == %obj.getId() )
-            {
-               %unlistedFound = true;
-               break;
-            }
-      
-         if( %unlistedFound )
-            continue;
+         if( %obj.isMemberOfClass( %type ) )
+         {
+            // Filter out emitters on the PE_UnlistedEmitters list.
             
-         // To prevent our default emitters from getting changed,
-         // prevent them from populating the list. Default emitters
-         // should only be used as a template for creating new ones.
-         if ( %obj.getName() $= "DefaultEmitter")
-            continue;
+            %unlistedFound = false;
+            foreach( %unlisted in %editorCtrl.unlistedSet ){
+               if( %unlisted.getId() == %obj.getId() )
+               {
+                  %unlistedFound = true;
+                  break;
+               }
+            }
          
-         PEE_EmitterSelector.add( %obj.getName(), %obj.getId() );
-         %emitterCount ++;
-      }
-      else if( %obj.isMemberOfClass( "ParticleData" ) )
-      {
-         %unlistedFound = false;
-         foreach( %unlisted in PE_UnlistedParticles )
-            if( %unlisted.getId() == %obj.getId() )
+            if( %unlistedFound )
+               continue;
+               
+            // To prevent our default emitters from getting changed,
+            // prevent them from populating the list. Default emitters
+            // should only be used as a template for creating new ones.
+            if ( %obj.getName() $= "DefaultEmitter")
+               continue;
+               
+            if(%typesListCount > 1)
             {
-               %unlistedFound = true;
-               break;
+               %typeSet = %listSet.findObjectByInternalName(%type);
+               if(!isObject(%typeSet))
+               {
+                  %typeSet = new SimSet(){ internalName = %type; };
+                  %listSet.add(%typeSet);
+               }
+               
+               %typeSet.add(%obj);
             }
-      
-         if( %unlistedFound )
-            continue;
-            
-         %name = %obj.getName();
-         %id = %obj.getId();
-         
-         if ( %name $= "DefaultParticle")
-            continue;
-
-         // Add to particle dropdown selectors.
-         
-         PEE_EmitterParticleSelector1.add( %name, %id );
-         PEE_EmitterParticleSelector2.add( %name, %id );
-         PEE_EmitterParticleSelector3.add( %name, %id );
-         PEE_EmitterParticleSelector4.add( %name, %id );
-                  
-         %particleCount ++;
+            else
+            {
+               %listSet.add(%obj);
+            }
+            %listCount++;
+         }
       }
    }
    
-   PEE_EmitterSelector.sort();
-   PEE_EmitterParticleSelector1.sort();   
-   PEE_EmitterParticleSelector2.sort();
-   PEE_EmitterParticleSelector3.sort();
-   PEE_EmitterParticleSelector4.sort();   
-   
-   echo( "Found" SPC %emitterCount SPC "emitters and" SPC %particleCount SPC "particles." );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ParticleEditor::openEmitterPane( %this )
-{
-   PE_Window.text = ":: Particle Editor - Emitters";
-   PE_EmitterEditor.guiSync();
-   ParticleEditor.activeEditor = PE_EmitterEditor;
-   
-   if( !PE_EmitterEditor.dirty )
-      PE_EmitterEditor.setEmitterNotDirty();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ParticleEditor::openParticlePane( %this )
-{
-   PE_Window.text = ":: Particle Editor - Particles";
+   ContextedDropdownListGui.show(%listSet, "Select", "" @ %editorCtrl @ ".selectObject", %this-->PopupMenu);
+   if(%this-->PopupMenu.getText() !$= "")
+   {
+      %obj = %this-->PopupMenu.getText().getId();
+      ContextedDropdownListGui.seekItemObject(%obj);
+   }
    
-   PE_ParticleEditor.guiSync();
-   ParticleEditor.activeEditor = PE_ParticleEditor;
+   //ContextedDropdownListGui-->tree.sort(0, true);
    
-   if( !PE_ParticleEditor.dirty )
-      PE_ParticleEditor.setParticleNotDirty();
+   //Go through and mark any items that are indicated as dirty
+   for(%i=0; %i < %editorCtrl.saver.getDirtyObjectCount(); %i++)
+   {
+      %dirtyObj = %editorCtrl.saver.getDirtyObject(%i);
+      %itemId = ContextedDropdownListGui-->tree.findItemByObjectId(%dirtyObj.getId());
+      
+      if(%itemId != -1) //can happen if it was previously marked as unlisted or somehow removed
+      {
+         ContextedDropdownListGui-->tree.markItem(%itemId, true);
+      }
+   }
 }
 
 //---------------------------------------------------------------------------------------------
@@ -191,62 +172,45 @@ function ParticleEditor::resetEmitterNode( %this )
    %tform = setWord( %tform, 0, getWord( %tform, 0 ) + getWord( %vec, 0 ) );
    %tform = setWord( %tform, 1, getWord( %tform, 1 ) + getWord( %vec, 1 ) );
    %tform = setWord( %tform, 2, getWord( %tform, 2 ) + getWord( %vec, 2 ) );
-
-   if( !isObject( $ParticleEditor::emitterNode ) )
-   {
-      if( !isObject( TestEmitterNodeData ) )
-      {
-         datablock ParticleEmitterNodeData( TestEmitterNodeData )
-         {
-            timeMultiple = 1;
-         };
-      }
-
-      $ParticleEditor::emitterNode = new ParticleEmitterNode()
-      {
-         emitter = PEE_EmitterSelector.getText();
-         velocity = 1;
-         position = getWords( %tform, 0, 2 );
-         rotation = getWords( %tform, 3, 6 );
-         datablock = TestEmitterNodeData;
-         parentGroup = MissionCleanup;
-      };
-   }
-   else
-   {
-      $ParticleEditor::emitterNode.setTransform( %tform );
-      
-      %clientObject = $ParticleEditor::emitterNode.getClientObject();
-      if( isObject( %clientObject ) )
-         %clientObject.setTransform( %tform );
-      
-      ParticleEditor.updateEmitterNode();
-   }
-   if (EWorldEditor.getSelectionSize()>0)
-   {
-        %obj = EWorldEditor.getSelectedObject(0);
-        if (%obj.isMemberOfClass("ParticleEmitterNode"))
-            $ParticleEditor::emitterNode.sethidden(true);
-   }
-        
+   
+   %this.selectedEditor.resetVizNode(%tform);
 }
 
 //---------------------------------------------------------------------------------------------
 
 function ParticleEditor::updateEmitterNode( %this )
 {
-   if( isObject( $ParticleEditor::emitterNode ) )
+   %this.selectedEditor.updateVizNode();
+}
+
+//------------------------------------------------------------------------------
+function ParticleEditor::open(%this, %datablock)
+{
+   //TODO:
+   //Check if we're dirty and if so, prompt about saving the change first
+   
+   for(%i=0; %i < PE_ParticleDataTypes.count(); %i++)
    {
-      %id = PEE_EmitterSelector_Control-->PopUpMenu.getSelected();
+      %groupName = PE_ParticleDataTypes.getKey(%i);
+      %typesList = getField(PE_ParticleDataTypes.getValue(%i), 0);
+      %editorName = getField(PE_ParticleDataTypes.getValue(%i), 1);
       
-      %clientObject = $ParticleEditor::emitterNode.getClientObject();
-      if( isObject( %clientObject ) )
-         %clientObject.setEmitterDataBlock( %id );
-   }
-   else
-      %this.resetEmitterNode();
+      %typesListCount = getWordCount(%typesList);
+      for(%t=0; %t < %typesListCount; %t++)
+      {
+         %type = getWord(%typesList, %t);
+         
+         if( %datablock.isMemberOfClass( %type ) )
+         {
+            PE_TabBook.selectPage(%i);
+            %editorName.selectObject(%datablock);
+            return true;
+         }         
+      }
+   } 
+   
+   return false; 
 }
-
 //=============================================================================================
 //    PE_TabBook.
 //=============================================================================================
@@ -255,10 +219,13 @@ function ParticleEditor::updateEmitterNode( %this )
 
 function PE_TabBook::onTabSelected( %this, %text, %idx )
 {
-   if( %idx == 0 )
-      ParticleEditor.openEmitterPane();
-   else
-      ParticleEditor.openParticlePane();
+   if(isObject(ParticleEditor.selectedEditor))
+      ParticleEditor.selectedEditor.closeEditorTab();
+   
+   %tab = %this.getObject(%idx);
+   %tab.openEditorTab();
+   
+   ParticleEditor.selectedEditor = %tab;
 }
 
 //------------------------------------------------------------------------------
@@ -348,4 +315,12 @@ function ParticleEditor::onResize(%this, %newPosition, %newExtent)
    FieldInfoControl.position = 5 SPC EWInspectorWindow.extent.y - 40;
 }
 
-//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+function ParticleEditorInspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   if(%oldValue $= %newValue)
+      return;
+      
+   ParticleEditor.selectedEditor.onInspectorFieldModified(%object, %fieldName, %arrayIndex, %oldValue, %newValue);
+   ParticleEditor.selectedEditor.setDirty(true);
+}

+ 60 - 23
Templates/BaseGame/game/tools/particleEditor/main.tscript

@@ -29,14 +29,19 @@ function initializeParticleEditor()
 {
    echo( " % - Initializing Particle Editor" );
      
-   exec( "./ParticleEditor.ed.gui" );
-   exec( "./particleEditor.ed." @ $TorqueScriptFileExtension );
-   exec( "./particleEditorUndo.ed." @ $TorqueScriptFileExtension );   
-   exec( "./particleEmitterEditor.ed." @ $TorqueScriptFileExtension );
-   exec( "./particleParticleEditor.ed." @ $TorqueScriptFileExtension );
+   exec( "./guis/ParticleEditor.ed.gui" );
+   exec( "./guis/particleEditor.ed." @ $TorqueScriptFileExtension );
+   exec( "./guis/createNewPrompt.ed.gui" );
+   exec( "./guis/createNewPrompt.ed." @ $TorqueScriptFileExtension );
    
-   PE_Window.setVisible( false );
-   MainSceneTabPanel.add( PE_Window );
+   exec( "./scripts/particleEditorUndo.ed." @ $TorqueScriptFileExtension ); 
+     
+   exec( "./scripts/particleEmitterEditor.ed." @ $TorqueScriptFileExtension );
+   exec( "./scripts/particleParticleEditor.ed." @ $TorqueScriptFileExtension );
+   exec( "./scripts/explosionEditor.ed." @ $TorqueScriptFileExtension );
+   exec( "./scripts/particleRibbonEditor.ed." @ $TorqueScriptFileExtension );
+   exec( "./scripts/afxZodiacEditor.ed." @ $TorqueScriptFileExtension );
+   exec( "./scripts/afxChoreoEditor.ed." @ $TorqueScriptFileExtension );
    
    new ScriptObject( ParticleEditorPlugin )
    {
@@ -53,12 +58,13 @@ function initializeParticleEditor()
    ParticleEditorPlugin.map = %map;
 
    new ScriptObject( ParticleEditor );
-
-   new PersistenceManager( PE_EmitterSaver );
-   new PersistenceManager( PE_ParticleSaver );
-
-   new SimSet( PE_UnlistedParticles );
-   new SimSet( PE_UnlistedEmitters );
+   
+   ParticleEditor.registerParticleEdType("Emitter", "ParticleEmitterData", "PE_EmitterEditor");
+   ParticleEditor.registerParticleEdType("Particle", "ParticleData", "PE_ParticleEditor");
+   ParticleEditor.registerParticleEdType("Explosion", "ExplosionData", "PE_ExplosionEditor");
+   ParticleEditor.registerParticleEdType("Ribbon", "RibbonData", "PE_RibbonParticleEditor");
+   ParticleEditor.registerParticleEdType("Zodiac", "afxZodiacData", "PE_AFXZodiacEditor");
+   ParticleEditor.registerParticleEdType("Choreography", "afxChoreographerData", "PE_AFXChoreoEditor");
 }
 
 //---------------------------------------------------------------------------------------------
@@ -94,8 +100,9 @@ function ParticleEditorPlugin::onActivated( %this )
    }
    
    EditorGui-->WorldEditorToolbar.setVisible( true );
-   EditorGui.bringToFront( PE_Window);
-   PE_Window.setVisible( true );
+   
+   Canvas.pushDialog(ParticleEditorGui);
+
    PE_Window.makeFirstResponder( true );
    
    %this.map.push();
@@ -114,11 +121,12 @@ function ParticleEditorPlugin::onActivated( %this )
 function ParticleEditorPlugin::onDeactivated( %this )
 {   
    EditorGui-->WorldEditorToolbar.setVisible( false );
-   PE_Window.setVisible( false );
+
+   ParticleEditor.selectedEditor.closeEditorTab();
    
-   if( isObject( $ParticleEditor::emitterNode) )
-      $ParticleEditor::emitterNode.delete();
-        
+   Canvas.popDialog(ParticleEditorGui);
+   ParticleEditorGui.quit();
+    
    %this.map.pop(); 
    
    Parent::onDeactivated( %this );
@@ -153,11 +161,19 @@ function ParticleEditorPlugin::readSettings( %this )
    
       %selectedEmitter = EditorSettings.value( "selectedEmitter" );
       if( isObject( %selectedEmitter ) )
-         PEE_EmitterSelector.setSelected( %selectedEmitter.getId() );
+         PE_EmitterEditor.loadNewEmitter( %selectedEmitter.getId() );
 
       %selectedParticle = EditorSettings.value( "selectedParticle" );
       if( isObject( %selectedParticle ) )
-         PEP_ParticleSelector.setSelected( %selectedParticle.getId() );
+         PE_EmitterEditor.loadNewParticle( %selectedParticle.getId() );
+         
+      %selectedExplosion = EditorSettings.value( "selectedExplosion" );
+      if( isObject( %selectedExplosion ) )
+         PE_ExplosionEditor.loadNewExplosion( %selectedExplosion.getId() );
+         
+      %selectedRibbon = EditorSettings.value( "selectedRibbon" );
+      if( isObject( %selectedRibbon ) )
+         PE_RibbonParticleEditor.loadNewRibbon( %selectedRibbon.getId() );
    
       PE_TabBook.selectPage( EditorSettings.value( "selectedPage" ) );
 
@@ -170,9 +186,30 @@ function ParticleEditorPlugin::writeSettings( %this )
 {
    EditorSettings.beginGroup( "ParticleEditor", true );
    
-      EditorSettings.setValue( "selectedEmitter", PEE_EmitterSelector.getText() );
-      EditorSettings.setValue( "selectedParticle", PEP_ParticleSelector.getText() );
+      EditorSettings.setValue( "selectedEmitter", PE_EmitterEditor-->popupMenu.getText() );
+      EditorSettings.setValue( "selectedParticle", PE_EmitterEditor-->popupMenu.getText() );
+      EditorSettings.setValue( "selectedExplosion", PE_ExplosionEditor-->popupMenu.getText() );
+      EditorSettings.setValue( "selectedRibbon", PE_RibbonParticleEditor-->popupMenu.getText() );
+      
       EditorSettings.setValue( "selectedTab", PE_TabBook.getSelectedPage() );
 
    EditorSettings.endGroup();
 }
+
+//------------------------------------------------------------------------------
+function ParticleEditor::registerParticleEdType(%this, %groupName, %typesList, %editorName)
+{
+   if(!isObject(PE_ParticleDataTypes))
+   {
+      new ArrayObject(PE_ParticleDataTypes){};  
+   }
+   
+   if(PE_ParticleDataTypes.getIndexFromKey(%groupName) != -1)
+   {
+      error("ParticleEditor::registerParticleEdType() - Attempted to register an existing group name of a particle type!");
+      return;
+   }
+   
+   PE_ParticleDataTypes.add(%groupName, %typesList TAB %editorName);
+}
+

+ 0 - 606
Templates/BaseGame/game/tools/particleEditor/particleEditorUndo.ed.tscript

@@ -1,606 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2012 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-
-//=============================================================================================
-//    ParticleEditor.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ParticleEditor::createUndo( %this, %class, %desc )
-{
-   pushInstantGroup();
-   %action = new UndoScriptAction()
-   {
-      class = %class;
-      superClass = BaseParticleEdAction;
-      actionName = %desc;
-   };
-   popInstantGroup();
-   return %action;
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ParticleEditor::submitUndo( %this, %action )
-{
-   %action.addToManager( Editor.getUndoManager() );
-}
-
-//=============================================================================================
-//    BaseParticleEdAction.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function BaseParticleEdAction::sync( %this )
-{
-   // Sync particle state.
-   
-   if( isObject( %this.particle ) )
-   {
-      %this.particle.reload();
-      PE_ParticleEditor.guiSync();
-      
-      if( %this.particle.getId() == PE_ParticleEditor.currParticle.getId() )
-         PE_ParticleEditor.setParticleDirty();
-   }
-
-   // Sync emitter state.
-
-   if( isObject( %this.emitter ) )
-   {
-      %this.emitter.reload();
-      
-      PE_EmitterEditor.guiSync();
-
-      if( %this.emitter.getId() == PE_EmitterEditor.currEmitter.getId() )
-         PE_EmitterEditor.setEmitterDirty();
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function BaseParticleEdAction::redo( %this )
-{
-   %this.sync();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function BaseParticleEdAction::undo( %this )
-{
-   %this.sync();
-}
-
-//=============================================================================================
-//    ActionRenameEmitter.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-//TODO
-
-//=============================================================================================
-//    ActionCreateNewEmitter.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionCreateNewEmitter::redo( %this )
-{
-   %emitter = %this.emitter;
-   
-   // Assign name.
-   
-   %emitter.name = %this.emitterName;
-   
-   // Remove from unlisted.
-   
-   PE_UnlistedEmitters.remove( %emitter );
-   
-   // Drop it in the dropdown and select it.
-   
-   %popup = PEE_EmitterSelector;
-
-   %popup.add( %emitter.getName(), %emitter.getId() );
-   %popup.sort();
-   %popup.setSelected( %emitter.getId() );   
-   
-   // Sync up.
-   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionCreateNewEmitter::undo( %this )
-{
-   %emitter = %this.emitter;
-      
-   // Prevent a save dialog coming up on the emitter.
-   
-   if( %emitter == PE_EmitterEditor.currEmitter )
-      PE_EmitterEditor.setEmitterNotDirty();
-   
-   // Add to unlisted.
-
-   PE_UnlistedEmitters.add( %emitter );
-   
-   // Remove it from in the dropdown and select prev emitter.
-   
-   %popup = PEE_EmitterSelector;
-      
-   if( isObject( %this.prevEmitter ) )
-      %popup.setSelected( %this.prevEmitter.getId() );
-   else
-      %popup.setFirstSelected();
-
-   %popup.clearEntry( %emitter.getId() );
-      
-   // Unassign name.
-   
-   %this.emitterName = %emitter.name;
-   %emitter.name = "";
-
-   // Sync up.
-   
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionDeleteEmitter.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionDeleteEmitter::redo( %this )
-{
-   %emitter = %this.emitter;
-      
-   // Unassign name.
-   
-   %this.emitterName = %emitter.name;
-   %emitter.name = "";
-
-   // Add to unlisted.
-   
-   PE_UnlistedEmitters.add( %emitter );
-   
-   // Remove from file.
-   
-   if(    %emitter.getFileName() !$= ""
-       && %emitter.getFilename() !$= "tools/particleEditor/particleEmitterEditor.ed." @ $TorqueScriptFileExtension )
-      PE_EmitterSaver.removeObjectFromFile( %emitter );
-      
-   // Select DefaultEmitter or first in list.
-   
-   %popup = PEE_EmitterSelector_Control-->PopUpMenu;
-
-   %popup.setFirstSelected();
-      
-   // Remove from dropdown.
-
-   %popup.clearEntry( %emitter );
-
-   // Sync up.
-
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionDeleteEmitter::undo( %this )
-{
-   %emitter = %this.emitter;
-      
-   // Re-assign name.
-   
-   %emitter.name = %this.emitterName;
-
-   // Remove from unlisted.
-   
-   PE_UnlistedEmitters.remove( %emitter );
-   
-   // Resave to file.
-   
-   if(    %this.emitterFname !$= ""
-       && %this.emitterFname !$= "tools/particleEditor/particleEmitterEditor.ed.gui" )
-   {
-      PE_EmitterSaver.setDirty( %emitter, %this.emitterFname );
-      PE_EmitterSaver.saveDirty();
-   }
-
-   // Add it to the dropdown and selet it.
-   
-   %popup = PEE_EmitterSelector_Control-->PopUpMenu;
-   %popup.add( %emitter.getName(), %emitter.getId() );
-   %popup.sort();
-   %popup.setSelected( %emitter.getId() );
-   
-   // Sync up.
-   
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionUpdateActiveEmitter.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitter::redo( %this )
-{
-   %emitter = %this.emitter;
-   %emitter.setFieldValue( %this.field, %this.newValue );
-   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitter::undo( %this )
-{
-   %emitter = %this.emitter;
-   %emitter.setFieldValue( %this.field, %this.oldValue );
-   
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionUpdateActiveEmitterLifeFields.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitterLifeFields::redo( %this )
-{
-   %emitter = %this.emitter;
-   
-   %emitter.lifetimeMS = %this.newValueLifetimeMS;
-   %emitter.lifetimeVarianceMS = %this.newValueLifetimeVarianceMS;
-   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitterLifeFields::undo( %this )
-{
-   %emitter = %this.emitter;
-
-   %emitter.lifetimeMS = %this.oldValueLifetimeMS;
-   %emitter.lifetimeVarianceMS = %this.oldValueLifetimeVarianceMS;
-   
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionUpdateActiveEmitterAmountFields.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitterAmountFields::redo( %this )
-{
-   %emitter = %this.emitter;
-   
-   %emitter.ejectionPeriodMS = %this.newValueEjectionPeriodMS;
-   %emitter.periodVarianceMS = %this.newValuePeriodVarianceMS;
-   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitterAmountFields::undo( %this )
-{
-   %emitter = %this.emitter;
-   
-   %emitter.ejectionPeriodMS = %this.oldValueEjectionPeriodMS;
-   %emitter.periodVarianceMS = %this.oldValuePeriodVarianceMS;
-   
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionUpdateActiveEmitterSpeedFields.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitterSpeedFields::redo( %this )
-{
-   %emitter = %this.emitter;
-   
-   %emitter.ejectionVelocity = %this.newValueEjectionVelocity;
-   %emitter.velocityVariance = %this.newValueVelocityVariance;
-   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveEmitterSpeedFields::undo( %this )
-{
-   %emitter = %this.emitter;
-
-   %emitter.ejectionVelocity = %this.oldValueEjectionVelocity;
-   %emitter.velocityVariance = %this.oldValueVelocityVariance;
-   
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionCreateNewParticle.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionCreateNewParticle::redo( %this )
-{
-   %particle = %this.particle.getName();
-   %particleId = %this.particle.getId();
-   %particleIndex = %this.particleIndex;
-   %emitter = %this.emitter;
-   
-   // Remove from unlisted.
-   
-   PE_UnlistedParticles.remove( %particleId );
-   
-   // Add it to the dropdown.
-   
-   PEP_ParticleSelector.add( %particle, %particleId );
-   PEP_ParticleSelector.sort();
-   PEP_ParticleSelector.setSelected( %particleId, false );
-         
-   // Add particle to dropdowns in the emitter editor.
-   
-   for( %i = 1; %i < 5; %i ++ )
-   {
-      %emitterParticle = "PEE_EmitterParticle" @ %i;
-      %popup = %emitterParticle-->PopupMenu;
-      
-      %popup.add( %particle, %particleId );
-      %popup.sort();
-      
-      if( %i == %particleIndex + 1 )
-         %popup.setSelected( %particleId );
-   }
-   
-   // Sync up.
-   
-   PE_ParticleEditor.loadNewParticle();
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionCreateNewParticle::undo( %this )
-{
-   %particle = %this.particle.getName();
-   %particleId = %this.particle.getId();
-   %emitter = %this.emitter;
-   
-   // Add to unlisted.
-   
-   PE_UnlistedParticles.add( %particleId );
-      
-   // Remove from dropdown.
-   
-   PEP_ParticleSelector.clearEntry( %particleId );
-   PEP_ParticleSelector.setFirstSelected( false );
-      
-   // Remove from particle dropdowns in emitter editor.
-   
-   for( %i = 1; %i < 5; %i ++ )
-   {
-      %emitterParticle = "PEE_EmitterParticle" @ %i;
-      %popup = %emitterParticle-->PopUpMenu;
-      
-      if( %popup.getSelected() == %particleId )
-         %popup.setSelected( %this.prevParticle );
-         
-      %popup.clearEntry( %particleId );
-   }
-   
-   // Sync up.
-   
-   PE_ParticleEditor.loadNewParticle();
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionDeleteParticle.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionDeleteParticle::redo( %this )
-{
-   %particle = %this.particle.getName();
-   %particleId = %this.particle.getId();
-   %emitter = %this.emitter;
-   
-   // Add to unlisted.
-   
-   PE_UnlistedParticles.add( %particleId );
-   
-   // Remove from file.
-   
-   if(    %particle.getFileName() !$= ""
-       && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed." @ $TorqueScriptFileExtension )
-      PE_ParticleSaver.removeObjectFromFile( %particleId );
-      
-   // Remove from dropdown.
-   
-   PEP_ParticleSelector.clearEntry( %particleId );
-   PEP_ParticleSelector.setFirstSelected();
-   
-   // Remove from particle selectors in emitter.
-   
-   for( %i = 1; %i < 5; %i ++ )
-   {
-      %emitterParticle = "PEE_EmitterParticle" @ %i;
-      %popup = %emitterParticle-->PopUpMenu;
-      
-      if( %popup.getSelected() == %particleId )
-      {
-         %this.particleIndex = %i - 1;
-         %popup.setSelected( 0 ); // Select "None".
-      }
-      
-      %popup.clearEntry( %particleId );
-   }
-   
-   // Sync up.
-   
-   PE_ParticleEditor.loadNewParticle();   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionDeleteParticle::undo( %this )
-{
-   %particle = %this.particle.getName();
-   %particleId = %this.particle.getId();
-   %particleIndex = %this.particleIndex;
-   %emitter = %this.emitter;
-   
-   // Remove from unlisted.
-   
-   PE_UnlistedParticles.remove( %particleId );
-
-   // Resave to file.
-   
-   if(    %particle.getFilename() !$= ""
-       && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed.gui" )
-   {
-      PE_ParticleSaver.setDirty( %particle );
-      PE_ParticleSaver.saveDirty();
-   }
-   
-   // Add to dropdown.
-   
-   PEP_ParticleSelector.add( %particle, %particleId );
-   PEP_ParticleSelector.sort();
-   PEP_ParticleSelector.setSelected( %particleId );
-         
-   // Add particle to dropdowns in the emitter editor.
-   
-   for( %i = 1; %i < 5; %i ++ )
-   {
-      %emitterParticle = "PEE_EmitterParticle" @ %i;
-      %popup = %emitterParticle-->PopUpMenu;
-      
-      %popup.add( %particle, %particleId );
-      %popup.sort();
-      
-      if( %i == %particleIndex + 1 )
-         %popup.setSelected( %particleId );
-   }
-   
-   // Sync up.
-   
-   PE_ParticleEditor.loadNewParticle();
-   Parent::undo( %This );
-}
-
-//=============================================================================================
-//    ActionUpdateActiveParticle.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveParticle::redo( %this )
-{
-   %particle = %this.particle;
-   %particle.setFieldValue( %this.field, %this.newValue );
-   
-   Parent::redo( %this );
-}
-
-function ActionUpdateActiveParticle::undo( %this )
-{
-   %particle = %this.particle;   
-   %particle.setFieldValue( %this.field, %this.oldValue );
-   
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionUpdateActiveParticleLifeFields.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveParticleLifeFields::redo( %this )
-{
-   %particle = %this.particle;
-   
-   %particle.lifetimeMS = %this.newValueLifetimeMS;
-   %particle.lifetimeVarianceMS = %this.newValueLifetimeVarianceMS;
-   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveParticleLifeFields::undo( %this )
-{
-   %particle = %this.particle;
-
-   %particle.lifetimeMS = %this.oldValueLifetimeMS;
-   %particle.lifetimeVarianceMS = %this.oldValueLifetimeVarianceMS;
-
-   Parent::undo( %this );
-}
-
-//=============================================================================================
-//    ActionUpdateActiveParticleSpinFields.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveParticleSpinFields::redo( %this )
-{
-   %particle = %this.particle;
-   
-   %particle.spinRandomMax = %this.newValueSpinRandomMax;
-   %particle.spinRandomMin = %this.newValueSpinRandomMin;
-   
-   Parent::redo( %this );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function ActionUpdateActiveParticleSpinFields::undo( %this )
-{
-   %particle = %this.particle;
-
-   %particle.spinRandomMax = %this.oldValueSpinRandomMax;
-   %particle.spinRandomMin = %this.oldValueSpinRandomMin;
-   
-   Parent::undo( %this );
-}

+ 0 - 680
Templates/BaseGame/game/tools/particleEditor/particleEmitterEditor.ed.tscript

@@ -1,680 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2012 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-
-$PE_EMITTEREDITOR_DEFAULT_FILENAME = "data/managedParticleEmitterData." @ $TorqueScriptFileExtension;
-
-
-//=============================================================================================
-//    PE_EmitterEditor.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::guiSync( %this )
-{
-   %data = PE_EmitterEditor.currEmitter;
-   
-   // Sync up sliders and number boxes.
-      
-   if( PE_EmitterEditor-->PEE_infiniteLoop.isStateOn() )
-   {
-      PE_EmitterEditor-->PEE_lifetimeMS_slider.setActive( false );
-      PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setActive( false );
-      PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setActive( false );
-      PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setActive( false );
-   }
-   else
-   {
-      PE_EmitterEditor-->PEE_lifetimeMS_slider.setActive( true );
-      PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setActive( true );
-      PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setActive( true );
-      PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setActive( true );
-      
-      PE_EmitterEditor-->PEE_lifetimeMS_slider.setValue( %data.lifetimeMS );
-      PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setText( %data.lifetimeMS );
-      PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setValue( %data.lifetimeVarianceMS );
-      PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setText( %data.lifetimeVarianceMS );
-   }
-         
-   PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.setValue( %data.ejectionPeriodMS );
-   PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.setText( %data.ejectionPeriodMS );
-
-   PE_EmitterEditor-->PEE_periodVarianceMS_slider.setValue( %data.periodVarianceMS );
-   PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.setText( %data.periodVarianceMS );
-   
-   PE_EmitterEditor-->PEE_ejectionVelocity_slider.setValue( %data.ejectionVelocity );
-   PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.setText( %data.ejectionVelocity );
-   
-   PE_EmitterEditor-->PEE_velocityVariance_slider.setValue( %data.velocityVariance );
-   PE_EmitterEditor-->PEE_velocityVariance_textEdit.setText( %data.velocityVariance );
-   
-   PE_EmitterEditor-->PEE_orientParticles.setValue( %data.orientParticles );
-   PE_EmitterEditor-->PEE_alignParticles.setValue( %data.alignParticles );
-   PE_EmitterEditor-->PEE_alignDirection.setText( %data.alignDirection );
-   PE_EmitterEditor-->PEE_ribbonParticles.setValue( %data.ribbonParticles );
-   
-   PE_EmitterEditor-->PEE_thetaMin_slider.setValue( %data.thetaMin );
-   PE_EmitterEditor-->PEE_thetaMin_textEdit.setText( %data.thetaMin );
-   
-   PE_EmitterEditor-->PEE_thetaMax_slider.setValue( %data.thetaMax );
-   PE_EmitterEditor-->PEE_thetaMax_textEdit.setText( %data.thetaMax );
-   
-   PE_EmitterEditor-->PEE_thetaVar_slider.setValue( %data.thetaVariance );
-   PE_EmitterEditor-->PEE_thetaVar_textEdit.setText( %data.thetaVariance );
-   
-   PE_EmitterEditor-->PEE_phiVariance_slider.setValue( %data.phiVariance );
-   PE_EmitterEditor-->PEE_phiVariance_textEdit.setText( %data.phiVariance );
-   
-   PE_EmitterEditor-->PEE_ejectionOffset_slider.setValue( %data.ejectionOffset );
-   PE_EmitterEditor-->PEE_ejectionOffset_textEdit.setText( %data.ejectionOffset );
-   
-   PE_EmitterEditor-->PEE_ejectionOffsetVariance_slider.setValue( %data.ejectionOffsetVariance );
-   PE_EmitterEditor-->PEE_ejectionOffsetVariance_textEdit.setText( %data.ejectionOffsetVariance );
-   
-   %blendTypeId = PE_EmitterEditor-->PEE_blendType.findText( %data.blendStyle );
-   PE_EmitterEditor-->PEE_blendType.setSelected( %blendTypeId, false );
-   
-   PE_EmitterEditor-->PEE_softnessDistance_slider.setValue( %data.softnessDistance );
-   PE_EmitterEditor-->PEE_softnessDistance_textEdit.setText( %data.softnessDistance );
-   
-   PE_EmitterEditor-->PEE_ambientFactor_slider.setValue( %data.ambientFactor );
-   PE_EmitterEditor-->PEE_ambientFactor_textEdit.setText( %data.ambientFactor );
-   
-   PE_EmitterEditor-->PEE_softParticles.setValue( %data.softParticles );
-   PE_EmitterEditor-->PEE_reverseOrder.setValue( %data.reverseOrder );
-   PE_EmitterEditor-->PEE_useEmitterSizes.setValue( %data.useEmitterSizes );
-   PE_EmitterEditor-->PEE_useEmitterColors.setValue( %data.useEmitterColors );
-   
-   PE_EmitterEditor-->PEE_glow.setValue( %data.glow );
-
-   // Sync up particle selectors.
-   
-   for( %index = 0; %index < 4; %index ++ )
-   {
-      %ctrl = "PEE_EmitterParticle" @ ( %index + 1 );
-      %popup = %ctrl-->PopUpMenu;
-
-      %particle = getWord( %data.particles, %index );
-      if( isObject( %particle ) )
-         %popup.setSelected( %particle.getId(), false );
-      else
-         %popup.setSelected( 0, false ); // Select "None".
-   }   
-}
-
-//---------------------------------------------------------------------------------------------
-
-// Generic updateEmitter method
-function PE_EmitterEditor::updateEmitter( %this, %propertyField, %value, %isSlider, %onMouseUp )
-{
-   PE_EmitterEditor.setEmitterDirty();
-         
-   %emitter = PE_EmitterEditor.currEmitter;
-      
-   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
-   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
-   {
-      %last.field = %propertyField;
-      %last.isSlider = %isSlider;
-      %last.onMouseUp = %onMouseUp;
-      %last.newValue = %value;
-   }
-   else
-   {
-      %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Update Active Emitter");
-      %action.emitter = %emitter;
-      %action.field = %propertyField;
-      %action.isSlider = %isSlider;
-      %action.onMouseUp = %onMouseUp;
-      %action.newValue = %value;
-      %action.oldValue = %emitter.getFieldValue( %propertyField );
-      
-      ParticleEditor.submitUndo( %action );
-   }
-   	
-	%emitter.setFieldValue( %propertyField, %value );
-	%emitter.reload();
-}
-
-//---------------------------------------------------------------------------------------------
-
-// Special case updateEmitter methods
-function PE_EmitterEditor::updateLifeFields( %this, %isRandom, %value, %isSlider, %onMouseUp )
-{
-   PE_EmitterEditor.setEmitterDirty();
-   
-   %emitter = PE_EmitterEditor.currEmitter;
-      
-   // Transfer values over to gui controls.
-   
-   if( %isRandom )
-   {
-      if( %value > 0 )
-         %value++;
-          
-      if( %value > PE_EmitterEditor-->PEE_lifetimeMS_slider.getValue() )
-      {
-         PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setText( %value );
-         PE_EmitterEditor-->PEE_lifetimeMS_slider.setValue( %value );
-      }
-   }
-   else
-   {
-      if( %value > 0 )
-         %value --;
-         
-      if( %value < PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.getValue() )
-      {
-         PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setText( %value );
-         PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setValue( %value );
-      }
-   }
-   
-   // Submit undo.
-   
-   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
-   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
-   {
-      %last.isSlider = %isSlider;
-      %last.onMouseUp = %onMouseUp;
-      %last.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText();
-      %last.newValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText();
-   }
-   else
-   {
-      %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterLifeFields, "Update Active Emitter");
-      %action.emitter = %emitter;
-      %action.isSlider = %isSlider;
-      %action.onMouseUp = %onMouseUp;
-      
-      %action.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText();
-      %action.oldValueLifetimeMS = %emitter.lifetimeMS;
-      
-      %action.newValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText();
-      %action.oldValueLifetimeVarianceMS = %emitter.lifetimeVarianceMS;
-      
-      ParticleEditor.submitUndo( %action );
-   }
-   
-   // Set the values on the current emitter.
-   
-   %emitter.lifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText();
-   %emitter.lifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText();
-   %emitter.reload();
-   
-   // Keep the infiniteLoop checkbox up to date.
-   
-   PE_EmitterEditor-->PEE_infiniteLoop.setStateOn(
-      %emitter.lifetimeMS == 0
-   );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::updateLifeFieldsInfiniteLoop( %this )
-{
-   %emitter = PE_EmitterEditor.currEmitter;
-   %isEnabled = PE_EmitterEditor-->PEE_infiniteLoop.isStateOn();
-      
-   // Submit undo.
-   
-   %action = ParticleEditor.createUndo( ActionUpdateActiveEmitterLifeFields, "Update Active Emitter" );
-   %action.emitter = %emitter;
-   
-   if( %isEnabled )
-   {
-      %action.newValueLifetimeMS = 0;
-      %action.newvalueLifetimeVarianceMS = 0;
-      %action.oldValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText();
-      %action.oldValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText();
-   }
-   else
-   {
-      %action.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText();
-      %action.newvalueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText();
-      %action.oldValueLifetimeMS = 0;
-      %action.oldValueLifetimeVarianceMS = 0;
-   }
-            
-   ParticleEditor.submitUndo( %action );
-   
-   // Execute action.
-   
-   %action.redo();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::updateAmountFields( %this, %isRandom, %value, %isSlider, %onMouseUp )
-{
-   PE_EmitterEditor.setEmitterDirty();
-   %emitter = PE_EmitterEditor.currEmitter;
-      
-   // Transfer values over to gui controls.
-   
-   if( %isRandom )
-   {
-      %value ++;
-      if( %value > PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.getValue() )
-      {
-         PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.setText( %value );
-         PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.setValue( %value );
-      }
-   }
-   else
-   {
-      %value --;
-      if( %value < PE_EmitterEditor-->PEE_periodVarianceMS_slider.getValue() )
-      {
-         PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.setText( %value );
-         PE_EmitterEditor-->PEE_periodVarianceMS_slider.setValue( %value );
-      }
-   }
-   
-   // Submit undo.
-   
-   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
-   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
-   {
-      %last.isSlider = %isSlider;
-      %last.onMouseUp = %onMouseUp;
-      %last.newValueEjectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText();
-      %last.newValuePeriodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText();
-   }
-   else
-   {
-      %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterAmountFields, "Update Active Emitter");
-      %action.emitter = %emitter;
-      %action.isSlider = %isSlider;
-      %action.onMouseUp = %onMouseUp;
-      
-      %action.newValueEjectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText();
-      %action.oldValueEjectionPeriodMS = %emitter.ejectionPeriodMS;
-      
-      %action.newValuePeriodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText();
-      %action.oldValuePeriodVarianceMS = %emitter.periodVarianceMS;
-      
-      ParticleEditor.submitUndo( %action );
-   }
-   
-   // Set the values on the current emitter.
-   
-   %emitter.ejectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText();
-   %emitter.periodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText();
-   %emitter.reload();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::updateSpeedFields( %this, %isRandom, %value, %isSlider, %onMouseUp )
-{
-   PE_EmitterEditor.setEmitterDirty();
-   %emitter = PE_EmitterEditor.currEmitter;
-      
-   // Transfer values over to gui controls.
-   
-   if( %isRandom )
-   {
-      if( %value > PE_EmitterEditor-->PEE_ejectionVelocity_slider.getValue() )
-      {
-         PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.setText( %value );
-         PE_EmitterEditor-->PEE_ejectionVelocity_slider.setValue( %value );
-      }
-   }
-   else
-   {
-      if( %value < PE_EmitterEditor-->PEE_velocityVariance_slider.getValue() )
-      {
-         PE_EmitterEditor-->PEE_velocityVariance_textEdit.setText( %value );
-         PE_EmitterEditor-->PEE_velocityVariance_slider.setValue( %value );
-      }
-   }
-   
-   // Submit undo.
-   
-   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
-   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
-   {
-      %last.isSlider = %isSlider;
-      %last.onMouseUp = %onMouseUp;
-      %last.newValueEjectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText();
-      %last.newValueVelocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText();
-   }
-   else
-   {
-      %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterSpeedFields, "Update Active Emitter");
-      %action.emitter = %emitter;
-      %action.isSlider = %isSlider;
-      %action.onMouseUp = %onMouseUp;
-      
-      %action.newValueEjectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText();
-      %action.oldValueEjectionVelocity = %emitter.ejectionVelocity;
-      
-      %action.newValueVelocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText();
-      %action.oldValueVelocityVariance = %emitter.velocityVariance;
-      
-      ParticleEditor.submitUndo( %action );
-   }
-   
-   // Set the values on the current emitter.
-   
-   %emitter.ejectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText();
-   %emitter.velocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText();
-   %emitter.reload();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::updateParticlesFields( %this )
-{
-   %particles = "";
-   for( %i = 1; %i < 5; %i ++ )
-   {
-      %emitterParticle = "PEE_EmitterParticle" @ %i;
-      %popup = %emitterParticle-->PopUpMenu;
-      %text = %popup.getText();
-      
-      if( %text $= "" || %text $= "None" )
-         continue;
-         
-      if( %particles $= "" )
-         %particles = %text;
-      else
-         %particles = %particles SPC %text;
-   }
-   
-   %changedEditParticle = 1;
-   %currParticle = PE_ParticleEditor.currParticle.getName();
-
-   foreach$( %particleName in %particles )
-   {
-      if( %particleName $= %currParticle )
-      {
-         %changedEditParticle = 0; 
-         break;
-      }
-   }
-   
-   // True only if the currently edited particle has not been found and the 
-   // ParticleEditor is dirty.
-   
-   if( %changedEditParticle && PE_ParticleEditor.dirty )
-   {
-      toolsMessageBoxYesNoCancel("Save Particle Changes?", 
-         "Do you wish to save the changes made to the <br>current particle before changing the particle?", 
-         "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", 
-         "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", 
-         "PE_EmitterEditor.guiSync();" );
-   }
-   else
-   {
-      PE_EmitterEditor.updateEmitter( "particles", %particles );
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::onNewEmitter( %this )
-{
-   if(    isObject( PE_EmitterEditor.currEmitter )
-       && PE_EmitterEditor.currEmitter $= PEE_EmitterSelector.getSelected() )
-      return;
-      
-   //FIXME: disregards particle tab dirty state
-   
-   if( PE_EmitterEditor.dirty )
-   {   
-      
-      if( PE_ParticleEditor.dirty )
-      {         
-         toolsMessageBoxYesNo("Save Existing Particle?", 
-            "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), 
-            "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");"
-         );
-      }
-            
-      %savedEmitter = PE_EmitterEditor.currEmitter;
-      toolsMessageBoxYesNoCancel("Save Existing Emitter?", 
-         "Do you want to save changes to <br><br>" @ %savedEmitter.getName(), 
-         "PE_EmitterEditor.saveEmitter(" @ %savedEmitter@ "); PE_EmitterEditor.loadNewEmitter();", 
-         "PE_EmitterEditor.saveEmitterDialogDontSave(" @ %savedEmitter @ "); PE_EmitterEditor.loadNewEmitter();"
-      );
-      
-
-   }
-   else
-   {
-      PE_EmitterEditor.loadNewEmitter();
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::loadNewEmitter( %this, %emitter )
-{
-   if( isObject( %emitter ) )
-      %current = %emitter.getId();
-   else
-      %current = PEE_EmitterSelector.getSelected();
-   
-   PE_EmitterEditor.currEmitter = %current;
-   PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %current );
-   PE_EmitterEditor_NotDirtyEmitter.originalName = %current.name;
-   
-   PE_EmitterEditor.guiSync();
-   PE_EmitterEditor.setEmitterNotDirty();
-      
-   PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) );
-   
-   ParticleEditor.updateEmitterNode();
-   
-   PE_EmitterEditor-->PEE_infiniteLoop.setStateOn( %current.lifetimeMS == 0 );
-}
-   
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::setEmitterDirty( %this )
-{
-   PE_EmitterEditor.text = "Emitter *";
-   PE_EmitterEditor.dirty = true;
-   
-   %emitter = PE_EmitterEditor.currEmitter;
-   %filename = %emitter.getFilename();
-   %editorFilename = "tools/particleEditor/particleEmitterEditor.ed." @ $TorqueScriptFileExtension;
-   
-   if( %filename $= "" || %filename $= %editorFilename )
-      PE_EmitterSaver.setDirty( %emitter, $PE_EMITTEREDITOR_DEFAULT_FILENAME );
-   else
-      PE_EmitterSaver.setDirty( %emitter );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::setEmitterNotDirty( %this )
-{   
-   PE_EmitterEditor.text = "Emitter";
-   PE_EmitterEditor.dirty = false;
-   
-   PE_EmitterSaver.clearAll();
-}
-
-//---------------------------------------------------------------------------------------------
-
-// Create Functionality
-function PE_EmitterEditor::showNewDialog( %this )
-{
-   //FIXME: disregards particle tab dirty state
-
-   // Open a dialog if the current emitter is dirty.
-   
-   if( PE_ParticleEditor.dirty )
-   {         
-      toolsMessageBoxYesNo("Save Existing Particle?", 
-         "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), 
-         "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");"
-      );
-   }   
-   
-   if( PE_EmitterEditor.dirty )
-   {
-      toolsMessageBoxYesNoCancel("Save Emitter Changes?", 
-         "Do you wish to save the changes made to the <br>current emitter before changing the emitter?", 
-         "PE_EmitterEditor.saveEmitter( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();", 
-         "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();"
-      );
-   }
-   else
-   {
-      PE_EmitterEditor.createEmitter();
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::createEmitter( %this )
-{
-   AssetBrowser_SelectModule.showDialog("PE_EmitterEditor.pickedNewEmitterTargetModule");
-   AssetBrowser_SelectModuleWindow.selectWindow();
-}
-
-function PE_EmitterEditor::pickedNewEmitterTargetModule( %this, %module )
-{
-   %moduleDef = ModuleDatabase.findModule(%module);
-   PE_EmitterEditor.targetModule = %module;
-   $PE_EMITTEREDITOR_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedParticleEmitterData." @ $TorqueScriptFileExtension;
-   
-   if(!isDirectory(filePath($PE_EMITTEREDITOR_DEFAULT_FILENAME)))
-   {
-      AssetBrowser.dirHandler.createFolder(filePath($PE_EMITTEREDITOR_DEFAULT_FILENAME));
-   }
-   
-   // Create a new emitter.
-   %emitter = getUniqueName( "newEmitter" );
-   datablock ParticleEmitterData( %emitter : DefaultEmitter )
-   {
-   };
-   
-   // Submit undo.
-   
-   %action = ParticleEditor.createUndo( ActionCreateNewEmitter, "Create New Emitter" );
-   %action.prevEmitter = PE_EmitterEditor.currEmitter;
-   %action.emitter = %emitter.getId();
-   %action.emitterName = %emitter;
-
-   ParticleEditor.submitUndo( %action );
-
-   // Execute action.
-   
-   %action.redo();
-   
-   PE_ParticleEditor.createParticle(false);
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::showDeleteDialog( %this )
-{
-   if( PE_EmitterEditor.currEmitter.getName() $= "DefaultEmitter" )
-   {
-      toolsMessageBoxOK( "Error", "Cannot delete DefaultEmitter");
-      return;
-   }
-   
-   if( isObject( PE_EmitterEditor.currEmitter ) )
-   {
-      toolsMessageBoxYesNoCancel("Delete Emitter?", 
-         "Are you sure you want to delete<br><br>" @ PE_EmitterEditor.currEmitter.getName() @ "<br><br> Emitter deletion won't take affect until the level is exited.", 
-         "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.deleteEmitter();"
-      );
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::deleteEmitter( %this )
-{  
-   %emitter = PE_EmitterEditor.currEmitter;
-   
-   // Create undo.
-   
-   %action = ParticleEditor.createUndo( ActionDeleteEmitter, "Delete Emitter" );
-   %action.emitter = %emitter;
-   %action.emitterFname = %emitter.getFilename();
-
-   ParticleEditor.submitUndo( %action );
-   
-   // Execute action.
-
-   %action.redo();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::saveEmitter( %this, %emitter )
-{   
-   
-   
-   if ( %emitter $= "" )
-      %newName = PEE_EmitterSelector_Control->TextEdit.getText();
-   else
-      %newName = %emitter.getName();
-   
-   PE_EmitterEditor.currEmitter.setName( %newName );
-   PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %emitter );
-   PE_EmitterEditor_NotDirtyEmitter.originalName = %newName;
-   
-   PE_EmitterSaver.saveDirty(); 
-   
-   PE_EmitterEditor.currEmitter = %newName.getId();
-   PE_EmitterEditor.setEmitterNotDirty();
-   
-   ParticleEditor.createParticleList(); 
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_EmitterEditor::saveEmitterDialogDontSave( %this, %emitter)
-{  
-   %emitter.setName( PE_EmitterEditor_NotDirtyEmitter.originalName );
-   %emitter.assignFieldsFrom( PE_EmitterEditor_NotDirtyEmitter );
-   PE_EmitterEditor.setEmitterNotDirty();
-}
-
-//=============================================================================================
-//    PEE_EmitterSelector_Control.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function PEE_EmitterSelector_Control::onRenameItem( %this )
-{
-   Parent::onRenameItem( %this );
-   
-   //FIXME: need to check for validity of name and name clashes
-
-   PE_EmitterEditor.setEmitterDirty();
-   
-   // Resort menu.
-   
-   %this-->PopupMenu.sort();
-}

+ 0 - 662
Templates/BaseGame/game/tools/particleEditor/particleParticleEditor.ed.tscript

@@ -1,662 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2012 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-
-$PE_PARTICLEEDITOR_DEFAULT_FILENAME = "data/managedParticleData." @ $TorqueScriptFileExtension;
-
-
-//=============================================================================================
-//    PE_ParticleEditor.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::guiSync( %this )
-{
-   // Populate the selector with the particles assigned
-   // to the current emitter.
-   
-   %containsCurrParticle = false;
-   %popup = PEP_ParticleSelector;
-   %popup.clear();
-   
-   foreach$( %particle in PE_EmitterEditor.currEmitter.particles )
-   {
-      if( %particle.getId() == PE_ParticleEditor.currParticle )
-         %containsCurrParticle = true;
-      
-      %popup.add( %particle, %particle.getId() );
-   }
-   
-   // Just in case the particle doesn't exist, fallback gracefully
-
-   if( !%containsCurrParticle )
-      PE_ParticleEditor.currParticle = getWord( PE_EmitterEditor.currEmitter.particles, 0 ).getId();
-
-   %data = PE_ParticleEditor.currParticle;
-   
-   %popup.sort();
-   %popup.setSelected( %data );
-         
-   %bitmap = %data.getTexture();
-   %bitmapText = %bitmap !$= "" && %bitmap !$= $MaterialEditor::emptyMaterialImage ? %data.getTextureAsset() : "None";
-   PE_ParticleEditor-->PEP_previewImageName.setText( %bitmapText );    
-   PE_ParticleEditor-->PEP_previewImageName.tooltip = %bitmapText;  
-   PE_ParticleEditor-->PEP_previewImage.setBitmap( getAssetPreviewImage(%bitmap) );
-   
-   PE_ParticleEditor-->PEP_inverseAlpha.setValue( %data.useInvAlpha );
-   
-   PE_ParticleEditor-->PEP_lifetimeMS_slider.setValue( %data.lifetimeMS );
-   PE_ParticleEditor-->PEP_lifetimeMS_textEdit.setText( %data.lifetimeMS );
-   
-   PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.setValue( %data.lifetimeVarianceMS );
-   PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.setText( %data.lifetimeVarianceMS );
-   
-   PE_ParticleEditor-->PEP_inheritedVelFactor_slider.setValue( %data.inheritedVelFactor );
-   PE_ParticleEditor-->PEP_inheritedVelFactor_textEdit.setText( %data.inheritedVelFactor );
-   
-   PE_ParticleEditor-->PEP_constantAcceleration_slider.setValue( %data.constantAcceleration );
-   PE_ParticleEditor-->PEP_constantAcceleration_textEdit.setText( %data.constantAcceleration );
-   
-   PE_ParticleEditor-->PEP_gravityCoefficient_slider.setValue( %data.gravityCoefficient );
-   PE_ParticleEditor-->PEP_gravityCoefficient_textEdit.setText( %data.gravityCoefficient );
-   
-   PE_ParticleEditor-->PEP_dragCoefficient_slider.setValue( %data.dragCoefficient );
-   PE_ParticleEditor-->PEP_dragCoefficient_textEdit.setText( %data.dragCoefficient );
-   
-   PE_ParticleEditor-->PEP_windCoefficient_slider.setValue( %data.windCoefficient );
-   PE_ParticleEditor-->PEP_windCoefficient_textEdit.setText( %data.windCoefficient );
-   
-   PE_ParticleEditor-->PEP_spinRandomMin_slider.setValue( %data.spinRandomMin );
-   PE_ParticleEditor-->PEP_spinRandomMin_textEdit.setText( %data.spinRandomMin );
-   
-   PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %data.spinRandomMax );
-   PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %data.spinRandomMax  );
-   
-   PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %data.spinRandomMax );
-   PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %data.spinRandomMax  );
-   
-   PE_ParticleEditor-->PEP_spinSpeed_slider.setValue( %data.spinSpeed );
-   PE_ParticleEditor-->PEP_spinSpeed_textEdit.setText( %data.spinSpeed );
-   
-   PE_ColorTintSwatch0.color = %data.colors[ 0 ];
-   PE_ColorTintSwatch1.color = %data.colors[ 1 ];
-   PE_ColorTintSwatch2.color = %data.colors[ 2 ];
-   PE_ColorTintSwatch3.color = %data.colors[ 3 ];
-   PE_ColorTintSwatch4.color = %data.colors[ 4 ];
-   PE_ColorTintSwatch5.color = %data.colors[ 5 ];
-   PE_ColorTintSwatch6.color = %data.colors[ 6 ];
-   PE_ColorTintSwatch7.color = %data.colors[ 7 ];
-   
-   PE_ParticleEditor-->PEP_pointSize_slider0.setValue( %data.sizes[ 0 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit0.setText( %data.sizes[ 0 ] );
-   
-   PE_ParticleEditor-->PEP_pointSize_slider1.setValue( %data.sizes[ 1 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit1.setText( %data.sizes[ 1 ] );
-   
-   PE_ParticleEditor-->PEP_pointSize_slider2.setValue( %data.sizes[ 2 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit2.setText( %data.sizes[ 2 ] );
-   
-   PE_ParticleEditor-->PEP_pointSize_slider3.setValue( %data.sizes[ 3 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit3.setText( %data.sizes[ 3 ] );
-   
-   PE_ParticleEditor-->PEP_pointSize_slider4.setValue( %data.sizes[ 4 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit4.setText( %data.sizes[ 4 ] );
-   
-   PE_ParticleEditor-->PEP_pointSize_slider5.setValue( %data.sizes[ 5 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit5.setText( %data.sizes[ 5 ] );
-   
-   PE_ParticleEditor-->PEP_pointSize_slider6.setValue( %data.sizes[ 6 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit6.setText( %data.sizes[ 6 ] );
-   
-   PE_ParticleEditor-->PEP_pointSize_slider7.setValue( %data.sizes[ 7 ] );
-   PE_ParticleEditor-->PEP_pointSize_textEdit7.setText( %data.sizes[ 7 ] );
-   
-   PE_ParticleEditor-->PEP_pointTime_slider0.setValue( %data.times[ 0 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit0.setText( %data.times[ 0 ] );
-   
-   PE_ParticleEditor-->PEP_pointTime_slider1.setValue( %data.times[ 1 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit1.setText( %data.times[ 1 ] );
-   
-   PE_ParticleEditor-->PEP_pointTime_slider2.setValue( %data.times[ 2 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit2.setText( %data.times[ 2 ] );
-   
-   PE_ParticleEditor-->PEP_pointTime_slider3.setValue( %data.times[ 3 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit3.setText( %data.times[ 3 ] );
-
-   PE_ParticleEditor-->PEP_pointTime_slider4.setValue( %data.times[ 4 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit4.setText( %data.times[ 4 ] );
-   
-   PE_ParticleEditor-->PEP_pointTime_slider5.setValue( %data.times[ 5 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit5.setText( %data.times[ 5 ] );
-   
-   PE_ParticleEditor-->PEP_pointTime_slider6.setValue( %data.times[ 6 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit6.setText( %data.times[ 6 ] );
-   
-   PE_ParticleEditor-->PEP_pointTime_slider7.setValue( %data.times[ 7 ] );
-   PE_ParticleEditor-->PEP_pointTime_textEdit7.setText( %data.times[ 7 ] );   
-   
-   //particle animation
-   PE_ParticleEditor-->PEP_animateTexture.setValue( %data.animateTexture );
-   
-   PE_ParticleEditor-->PEP_framesPerSec_slider.setValue( %data.framesPerSec );
-   PE_ParticleEditor-->PEP_framesPerSec_textEdit.setText( %data.framesPerSec );
-   
-   PE_ParticleEditor-->PEP_animTexFramesList_textEdit.setText( %data.animTexFrames );
-   
-   PE_ParticleEditor-->PEP_animTileCount_textEdit.setText( %data.animTexTiling );
-   
-}
-
-//---------------------------------------------------------------------------------------------
-
-// Generic updateParticle method
-function PE_ParticleEditor::updateParticle(%this, %propertyField, %value, %isSlider, %onMouseUp)
-{
-   PE_ParticleEditor.setParticleDirty();
-   %particle = PE_ParticleEditor.currParticle;
-      
-   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
-   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
-   {
-      %last.field = %propertyField;
-      %last.isSlider = %isSlider;
-      %last.onMouseUp = %onMouseUp;
-      %last.newValue = %value;
-   }
-   else
-   {
-      %action = ParticleEditor.createUndo(ActionUpdateActiveParticle, "Update Active Particle");
-      %action.particle = %particle;
-      %action.field = %propertyField;
-      %action.isSlider = %isSlider;
-      %action.onMouseUp = %onMouseUp;
-      %action.newValue = %value;
-      %action.oldValue = %particle.getFieldValue( %propertyField );
-      
-      ParticleEditor.submitUndo( %action );
-   }
-   
-   %particle.setFieldValue( %propertyField, %value );
-   %particle.reload();
-}
-
-//---------------------------------------------------------------------------------------------
-
-// Special case updateEmitter methods
-function PE_ParticleEditor::updateParticleTexture( %this, %action )
-{
-   if( %action )
-   {
-      AssetBrowser.showDialog("ImageAsset", "PE_ParticleEditor.onImageAssetSelected");
-   }
-   else
-   {
-      PE_ParticleEditor-->PEP_previewImage.setBitmap("");
-      PE_ParticleEditor-->PEP_previewImageName.setText("");
-      PE_ParticleEditor-->PEP_previewImageName.tooltip = "";
-      
-      PE_ParticleEditor.updateParticle( "textureName", "" );
-   }
-}
-
-function PE_ParticleEditor::onImageAssetSelected(%this, %assetId)
-{
-   if( AssetDatabase.isDeclaredAsset(%assetId) )
-   {
-      PE_ParticleEditor-->PEP_previewImage.setBitmap(%assetId);
-      PE_ParticleEditor-->PEP_previewImageName.setText(%assetId);
-      PE_ParticleEditor-->PEP_previewImageName.tooltip = %assetId;
-      
-      PE_ParticleEditor.updateParticle( "textureAsset", %assetId );
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::updateLifeFields( %this, %isRandom, %value, %isSlider, %onMouseUp )
-{
-   PE_ParticleEditor.setParticleDirty();
-   %particle = PE_ParticleEditor.currParticle;
-      
-   //Transfer values over to gui controls.
-   
-   if( %isRandom )
-   {
-      %value ++;
-      if( %value > PE_ParticleEditor-->PEP_lifetimeMS_slider.getValue() )
-      {
-         PE_ParticleEditor-->PEP_lifetimeMS_textEdit.setText( %value );
-         PE_ParticleEditor-->PEP_lifetimeMS_slider.setValue( %value );
-      }
-   }
-   else
-   {
-      %value --;
-      if( %value < PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.getValue() )
-      {
-         PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.setText( %value );
-         PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.setValue( %value );
-      }
-   }
-   
-   // Submit undo.
-   
-   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
-   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
-   {
-      %last.isSlider = %isSlider;
-      %last.onMouseUp = %onMouseUp;
-      %last.newValueLifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText();
-      %last.newValueLifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText();
-   }
-   else
-   {
-      %action = ParticleEditor.createUndo(ActionUpdateActiveParticleLifeFields, "Update Active Particle");
-      %action.particle = %particle;
-      %action.isSlider = %isSlider;
-      %action.onMouseUp = %onMouseUp;
-      
-      %action.newValueLifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText();
-      %action.oldValueLifetimeMS = %particle.lifetimeMS;
-      
-      %action.newValueLifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText();
-      %action.oldValueLifetimeVarianceMS = %particle.lifetimeVarianceMS;
-      
-      ParticleEditor.submitUndo( %action );
-   }
-   
-   %particle.lifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText();
-   %particle.lifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText();
-   %particle.reload();   
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::updateSpinFields( %this, %isMax, %value, %isSlider, %onMouseUp )
-{
-   PE_ParticleEditor.setParticleDirty();
-   %particle = PE_ParticleEditor.currParticle;
-      
-   // Transfer values over to gui controls.
-   if( %isMax )
-   {
-      %value ++;
-      if( %value > PE_ParticleEditor-->PEP_spinRandomMax_slider.getValue() )
-      {
-         PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %value );
-         PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %value );
-      }
-   }
-   else
-   {
-      %value --;
-      if( %value < PE_ParticleEditor-->PEP_spinRandomMin_slider.getValue() )
-      {
-         PE_ParticleEditor-->PEP_spinRandomMin_textEdit.setText( %value );
-         PE_ParticleEditor-->PEP_spinRandomMin_slider.setValue( %value );
-      }
-   }
-   
-   // Submit undo.
-   
-   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
-   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
-   {
-      %last.isSlider = %isSlider;
-      %last.onMouseUp = %onMouseUp;
-      %last.newValueSpinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText();
-      %last.newValueSpinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText();
-   }
-   else
-   {
-      %action = ParticleEditor.createUndo(ActionUpdateActiveParticleSpinFields, "Update Active Particle");
-      %action.particle = %particle;
-      %action.isSlider = %isSlider;
-      %action.onMouseUp = %onMouseUp;
-      
-      %action.newValueSpinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText();
-      %action.oldValueSpinRandomMax = %particle.spinRandomMax;
-      
-      %action.newValueSpinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText();
-      %action.oldValueSpinRandomMin = %particle.spinRandomMin;
-      
-      ParticleEditor.submitUndo( %action );
-   }
-   
-   %particle.spinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText();
-   %particle.spinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText();
-
-   %particle.reload();   
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::onNewParticle( %this )
-{
-   // Bail if the user selected the same particle.
-   
-   %id = PEP_ParticleSelector.getSelected();
-   if( %id == PE_ParticleEditor.currParticle )
-      return;
-   
-   // Load new particle if we're not in a dirty state
-   if( PE_ParticleEditor.dirty )
-   {         
-      toolsMessageBoxYesNoCancel("Save Existing Particle?", 
-         "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), 
-         "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");", 
-         "PE_ParticleEditor.saveParticleDialogDontSave(" @ PE_ParticleEditor.currParticle @ "); PE_ParticleEditor.loadNewParticle();"
-      );
-   }
-   else
-   {
-      PE_ParticleEditor.loadNewParticle();
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::loadNewParticle( %this, %particle )
-{
-   if( isObject( %particle ) )
-      %particle = %particle.getId();
-   else
-      %particle = PEP_ParticleSelector.getSelected();
-      
-   if( !isObject( %particle ) )
-      return;
-      
-   PE_ParticleEditor.currParticle = %particle;
-   
-   error("PE_ParticleEditor::loadNewParticle() - Loading particle: " @ %particle.getName());
-   error("Particle TextureName: " @ %particle.getTexture());
-   
-   error("ReloadingParticle...");
-   %particle.reload();
-   
-   PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %particle );
-   PE_ParticleEditor_NotDirtyParticle.originalName = %particle.getName();
-
-   error("Post duplicate Particle TextureName: " @ %particle.getTexture());
-   error("Post duplicate PE_ParticleEditor_NotDirtyParticle TextureName: " @ PE_ParticleEditor_NotDirtyParticle.getTexture());
-
-   PE_ParticleEditor.guiSync();
-   PE_ParticleEditor.setParticleNotDirty();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::setParticleDirty( %this )
-{
-   PE_ParticleEditor.text = "Particle *";
-   PE_ParticleEditor.dirty = true;
-   
-   %particle = PE_ParticleEditor.currParticle;
-   %filename = %particle.getFilename();
-   %editorFilename = "tools/particleEditor/particleParticleEditor.ed." @ $TorqueScriptFileExtension;
-   
-   if( %filename $= "" || %filename $= %editorFilename )
-      PE_ParticleSaver.setDirty( %particle, $PE_PARTICLEEDITOR_DEFAULT_FILENAME );
-   else
-      PE_ParticleSaver.setDirty( %particle );
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::setParticleNotDirty( %this )
-{
-   PE_ParticleEditor.text = "Particle";
-   PE_ParticleEditor.dirty = false;
-   
-   PE_ParticleSaver.clearAll();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::showNewDialog( %this, %replaceSlot )
-{
-   // Open a dialog if the current Particle is dirty
-   if( PE_ParticleEditor.dirty ) 
-   {
-      toolsMessageBoxYesNoCancel("Save Particle Changes?", 
-         "Do you wish to save the changes made to the <br>current particle before changing the particle?", 
-         "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );", 
-         "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );"
-      );
-   }
-   else
-   {
-      PE_ParticleEditor.createParticle( %replaceSlot );
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::createParticle( %this, %replaceSlot )
-{
-   // Make sure we have a spare slot on the current emitter.
-   
-   if( !%replaceSlot )
-   {
-      %numExistingParticles = getWordCount( PE_EmitterEditor.currEmitter.particles );
-      if( %numExistingParticles > 3 )
-      {
-         toolsMessageBoxOK( "Error", "An emitter cannot have more than 4 particles assigned to it." );
-         return;
-      }
-      
-      %particleIndex = %numExistingParticles;
-   }
-   else
-      %particleIndex = %replaceSlot - 1;
-   
-   PE_ParticleEditor.newParticleSlot = %particleIndex;
-   
-   if(%replaceSlot $= "" || %replaceSlot != 0)
-   {
-      AssetBrowser_SelectModule.showDialog("PE_ParticleEditor.pickedNewParticleTargetModule");
-      AssetBrowser_SelectModuleWindow.selectWindow();
-   }
-   else
-   {
-      PE_ParticleEditor.pickedNewParticleTargetModule(PE_EmitterEditor.targetModule);
-   }
-}
-
-function PE_ParticleEditor::pickedNewParticleTargetModule(%this, %module)
-{
-   %moduleDef = ModuleDatabase.findModule(%module);
-   $PE_PARTICLEEDITOR_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedParticleData." @ $TorqueScriptFileExtension;
-   
-   if(!isDirectory(filePath($PE_PARTICLEEDITOR_DEFAULT_FILENAME)))
-   {
-      AssetBrowser.dirHandler.createFolder(filePath($PE_PARTICLEEDITOR_DEFAULT_FILENAME));
-   }
-   
-   // Create the particle datablock and add to the emitter.
-   
-   %newParticle = getUniqueName( "newParticle" );
-   
-   datablock ParticleData( %newParticle : DefaultParticle )
-   {
-   };
-         
-   // Submit undo.
-   
-   %action = ParticleEditor.createUndo( ActionCreateNewParticle, "Create New Particle" );
-   %action.particle = %newParticle.getId();
-   %action.particleIndex = PE_ParticleEditor.newParticleSlot;
-   %action.prevParticle = ( "PEE_EmitterParticleSelector" @ ( PE_ParticleEditor.newParticleSlot + 1 ) ).getSelected();
-   %action.emitter = PE_EmitterEditor.currEmitter;
-   
-   ParticleEditor.submitUndo( %action );
-   
-   // Execute action.
-   
-   %action.redo();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::showDeleteDialog( %this )
-{
-   // Don't allow deleting DefaultParticle.
-   
-   if( PE_ParticleEditor.currParticle.getName() $= "DefaultParticle" )
-   {
-      toolsMessageBoxOK( "Error", "Cannot delete DefaultParticle");
-      return;
-   }
-   
-   // Check to see if the particle emitter has more than 1 particle on it.
-   
-   if( getWordCount( PE_EmitterEditor.currEmitter.particles ) == 1 )
-   {
-      toolsMessageBoxOK( "Error", "At least one particle must remain on the particle emitter.");
-      return;
-   }
-   
-   // Bring up requester for confirmation.
-   
-   if( isObject( PE_ParticleEditor.currParticle ) )
-   {
-      toolsMessageBoxYesNoCancel( "Delete Particle?", 
-         "Are you sure you want to delete<br><br>" @ PE_ParticleEditor.currParticle.getName() @ "<br><br> Particle deletion won't take affect until the engine is quit.", 
-         "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.deleteParticle();", 
-         "", 
-         ""
-      );
-   }
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::deleteParticle( %this )
-{
-   %particle = PE_ParticleEditor.currParticle;
-   
-   // Submit undo.
-   
-   %action = ParticleEditor.createUndo( ActionDeleteParticle, "Delete Particle" );
-   %action.particle = %particle;
-   %action.emitter = PE_EmitterEditor.currEmitter;
-
-   ParticleEditor.submitUndo( %action );
-   
-   // Execute action.
-   
-   %action.redo();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::saveParticle( %this, %particle )
-{
-   %particle.setName( PEP_ParticleSelector.getText() );
-   
-   PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %particle );
-   PE_ParticleEditor_NotDirtyParticle.originalName = %particle.getName();
-   
-   PE_ParticleSaver.saveDirty(); 
-   PE_ParticleEditor.setParticleNotDirty();
-   
-   ParticleEditor.createParticleList(); 
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ParticleEditor::saveParticleDialogDontSave( %this, %particle )
-{
-   %particle.setName( PE_ParticleEditor_NotDirtyParticle.originalName );
-   %particle.assignFieldsFrom( PE_ParticleEditor_NotDirtyParticle );
-   
-   PE_ParticleEditor.setParticleNotDirty();
-}
-
-//=============================================================================================
-//    PE_ColorTintSwatch.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function PE_ColorTintSwatch::updateParticleColor( %this, %color )
-{
-   %arrayNum = %this.arrayNum;
-   
-   %r = getWord( %color, 0 );
-   %g = getWord( %color, 1 );
-   %b = getWord( %color, 2 );
-   %a = getWord( %color, 3 );
-   
-   %color = %r SPC %g SPC %b SPC %a;   
-   %this.color = %color;
-   
-	PE_ParticleEditor.updateParticle( "colors[" @ %arrayNum @ "]", %color );
-}
-
-//=============================================================================================
-//    PEP_ParticleSelector_Control.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function PEP_ParticleSelector_Control::onRenameItem( %this )
-{
-   Parent::onRenameItem( %this );
-   
-   //FIXME: need to check for validity of name and name clashes
-   
-   PE_ParticleEditor.setParticleDirty();
-   
-   // Resort menu.
-   
-   %this-->PopupMenu.sort();
-}
-
-//=============================================================================================
-//    PEP_NewParticleButton.
-//=============================================================================================
-
-//---------------------------------------------------------------------------------------------
-
-function PEP_NewParticleButton::onDefaultClick( %this )
-{
-   PE_ParticleEditor.showNewDialog();
-}
-
-//---------------------------------------------------------------------------------------------
-
-function PEP_NewParticleButton::onCtrlClick( %this )
-{
-   for( %i = 1; %i < 5; %i ++ )
-   {
-      %popup = "PEE_EmitterParticleSelector" @ %i;
-      if( %popup.getSelected() == PEP_ParticleSelector.getSelected() )
-      {
-         %replaceSlot = %i;
-         break;
-      }
-   }
-
-   PE_ParticleEditor.showNewDialog( %replaceSlot );
-}

+ 398 - 0
Templates/BaseGame/game/tools/particleEditor/scripts/afxChoreoEditor.ed.tscript

@@ -0,0 +1,398 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+$PE_AFXChoreoEditor_DEFAULT_FILENAME = "data/managedChoreographyData." @ $TorqueScriptFileExtension;
+
+
+//=============================================================================================
+//    PE_AFXChoreoEditor.
+//=============================================================================================
+function PE_AFXChoreoEditor::init(%this)
+{
+   datablock afxChoreographerData(PE_AFXChoreoEditor_NotDirtyEmitter)
+   {
+   };
+   
+   %this.unlistedSet.add(PE_AFXChoreoEditor_NotDirtyEmitter);
+}
+
+function PE_AFXChoreoEditor::openEditorTab(%this)
+{
+   PE_Window.text = ":: Particle Editor - AFX Choreographer";
+   %this.guiSync();
+   ParticleEditor.activeEditor = %this;
+
+   if( !%this.dirty )
+      %this.setNotDirty();
+     
+   if( isObject( $ParticleEditor::choreographyNode ) )
+      $ParticleEditor::choreographyNode.setHidden(false);
+}
+
+function PE_AFXChoreoEditor::closeEditorTab(%this)
+{
+   if( isObject( $ParticleEditor::choreographyNode) )
+      $ParticleEditor::choreographyNode.delete();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::guiSync( %this )
+{
+   %this-->inspector.refresh();
+}
+
+function PE_AFXChoreoEditor::resetVizNode(%this, %tform)
+{
+   /*if( !isObject( $ParticleEditor::choreographyNode ) )
+   {
+      if( !isObject( TestChoreographyData ) )
+      {
+         datablock afxChoreographerData( TestChoreographyData )
+         {
+            timeMultiple = 1;
+         };
+      }
+
+      $ParticleEditor::choreographyNode = new afxChoreographer()
+      {
+         position = getWords( %tform, 0, 2 );
+         rotation = getWords( %tform, 3, 6 );
+         datablock = TestChoreographyData;
+         parentGroup = MissionCleanup;
+      };
+   }
+   else
+   {
+      $ParticleEditor::choreographyNode.setTransform( %tform );
+      
+      %clientObject = $ParticleEditor::choreographyNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.setTransform( %tform );
+      
+      ParticleEditor.updateVizNode();
+   }
+   if (EWorldEditor.getSelectionSize()>0)
+   {
+        %obj = EWorldEditor.getSelectedObject(0);
+        if (%obj.isMemberOfClass("afxChoreographerData"))
+            $ParticleEditor::choreographyNode.sethidden(true);
+   }*/
+}
+
+function PE_AFXChoreoEditor::updateVizNode(%this)
+{
+   /*if( isObject( $ParticleEditor::choreographyNode ) )
+   {
+      %id = %this.currChoreography;
+      
+      %clientObject = $ParticleEditor::choreographyNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.assignFieldsFrom( %id );
+   }
+   else
+      %this.resetVizNode(); */ 
+}
+
+//------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::selectObject(%this, %obj)
+{
+   if( isObject(%obj )
+       && %obj.getName() $= %this-->popupMenu.text )
+      return;
+      
+   //FIXME: disregards particle tab dirty state
+   if( %this.dirty )
+   {   
+      %savedChoreography = %this.currChoreography;
+      toolsMessageBoxYesNoCancel("Save Existing AFX Choreographer?", 
+         "Do you want to save changes to <br><br>" @ %savedChoreography.getName(), 
+         "PE_AFXChoreoEditor.saveChoreography(" @ %savedChoreography@ "); PE_AFXChoreoEditor.loadNewChoreography(" @ %obj @ ");", 
+         "PE_AFXChoreoEditor.saveChoreographyDialogDontSave(" @ %savedChoreography @ "); PE_AFXChoreoEditor.loadNewChoreography(" @ %obj @ ");"
+      );
+   }
+   else
+   {
+      %this.loadNewChoreography(%obj);
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::loadNewChoreography( %this, %choreography )
+{
+   %this-->popupMenu.setText(%choreography.getName());
+   %this-->inspector.inspect(%choreography);
+   
+   if( isObject( %choreography ) )
+      %current = %choreography.getId();
+   else
+      %current = %this-->popupMenu.text;
+   
+   %this.currChoreography = %current;
+   PE_AFXChoreoEditor_NotDirtyChoreography.assignFieldsFrom( %current );
+   PE_AFXChoreoEditor_NotDirtyChoreography.originalName = %current.name;
+   
+   %this.guiSync();
+   %this.setNotDirty();
+      
+   //PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) );
+
+   %this.guiSync();
+   
+   PE_AFXChoreoEditor.updateVizNode();
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_AFXChoreoEditor::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   %action = ParticleEditor.createUndo(ActionUpdateActiveChoreography, "Update Active AFX Choreographer");
+   %action.choreography = %object;
+   %action.field = %fieldName;
+   %action.isSlider = false;
+   %action.onMouseUp = true;
+   %action.newValue = %newValue;
+   %action.oldValue = %oldValue;
+   
+   ParticleEditor.submitUndo( %action );
+}
+
+// Generic updateChoreography method
+function PE_AFXChoreoEditor::updateChoreography( %this, %propertyField, %value, %isSlider, %onMouseUp )
+{
+   PE_AFXChoreoEditor.setDirty();
+         
+   %choreography = %this.currChoreography;
+      
+   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
+   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
+   {
+      %last.field = %propertyField;
+      %last.isSlider = %isSlider;
+      %last.onMouseUp = %onMouseUp;
+      %last.newValue = %value;
+   }
+   else
+   {
+      %action = ParticleEditor.createUndo(ActionUpdateActiveChoreography, "Update Active AFX Choreographer");
+      %action.choreography = %choreography;
+      %action.field = %propertyField;
+      %action.isSlider = %isSlider;
+      %action.onMouseUp = %onMouseUp;
+      %action.newValue = %value;
+      %action.oldValue = %choreography.getFieldValue( %propertyField );
+      
+      ParticleEditor.submitUndo( %action );
+   }
+   	
+	%choreography.setFieldValue( %propertyField, %value );
+	%choreography.reload();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::setDirty( %this )
+{
+   %this.text = "*Choreography";
+   %this.dirty = true;
+   
+   if(!startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = "*" @ %this-->PopupMenu.text;
+   }
+   
+   %choreography = %this.currChoreography;
+   %filename = %choreography.getFilename();
+   %editorFilename = "tools/particleEditor/scripts/afxChoreographyEditor.ed." @ $TorqueScriptFileExtension;
+   
+   if( %filename $= "" || %filename $= %editorFilename )
+      %this.saver.setDirty( %choreography, $PE_AFXChoreoEditor_DEFAULT_FILENAME );
+   else
+      %this.saver.setDirty( %choreography );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::setNotDirty( %this )
+{   
+   PE_AFXChoreoEditor.text = "Choreography";
+   PE_AFXChoreoEditor.dirty = false;
+   
+   if(startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = stripChars(%this-->PopupMenu.text, "*");
+   }
+   
+   %this.saver.clearAll();
+}
+
+//---------------------------------------------------------------------------------------------
+
+// Create Functionality
+function PE_AFXChoreoEditor::showNewDialog( %this )
+{
+   if( PE_AFXChoreoEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save AFX Choreographer Changes?", 
+         "Do you wish to save the changes made to the <br>current choreography before changing the choreography?", 
+         "PE_AFXChoreoEditor.saveChoreography( " @ PE_AFXChoreoEditor.currChoreography.getName() @ " ); PE_AFXChoreoEditor.createChoreography();", 
+         "PE_AFXChoreoEditor.saveChoreographyDialogDontSave( " @ PE_AFXChoreoEditor.currChoreography.getName() @ " ); PE_AFXChoreoEditor.createChoreography();"
+      );
+   }
+   else
+   {
+      PE_AFXChoreoEditor.createChoreography();
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::createChoreography( %this )
+{
+   AssetBrowser_SelectModule.showDialog("PE_AFXChoreoEditor.pickedNewChoreographyTargetModule");
+   AssetBrowser_SelectModuleWindow.selectWindow();
+}
+
+function PE_AFXChoreoEditor::pickedNewChoreographyTargetModule( %this, %module )
+{
+   ParticleEditorCreatePrompt.show("Choreography", "afxChoreographerData", "PE_AFXChoreoEditor.doCreateNewChoreography(\"" @ %module @ "\");" );
+}
+
+function PE_AFXChoreoEditor::doCreateNewChoreography( %this, %module )
+{
+   //Sanity checks
+   %newName = ParticleEditorCreatePrompt-->nameText.getText();
+   if(%newName $= "")
+   {
+      toolsMessageBoxOK("Error", "New Choreography requires a name!");
+      return;
+   }
+   
+   Canvas.popDialog(ParticleEditorCreatePrompt);
+   
+   %sourceDB = ParticleEditorCreatePrompt-->CopySourceDropdown.getText();
+   
+   if(%sourceDB $= "")
+      %sourceDB = DefaultChoreography;
+   
+   %moduleDef = ModuleDatabase.findModule(%module);
+   PE_AFXChoreoEditor.targetModule = %module;
+   $PE_AFXChoreoEditor_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedChoreographyData." @ $TorqueScriptFileExtension;
+   
+   if(!isDirectory(filePath($PE_AFXChoreoEditor_DEFAULT_FILENAME)))
+   {
+      AssetBrowser.dirHandler.createFolder(filePath($PE_AFXChoreoEditor_DEFAULT_FILENAME));
+   }
+   
+   // Create a new choreography.
+   %choreography = getUniqueName( %newName );
+   eval("datablock ChoreographyData( " @ %choreography @ " : " @ %sourceDB @ " ){};");
+   
+   // Submit undo.
+   
+   %action = ParticleEditor.createUndo( ActionCreateNewChoreography, "Create New AFX Choreographer" );
+   %action.prevChoreography = PE_AFXChoreoEditor.currChoreography;
+   %action.choreography = %choreography.getId();
+   %action.choreographyName = %choreography;
+
+   ParticleEditor.submitUndo( %action );
+
+   // Execute action.
+   %action.redo();
+   
+   %this.saver.setDirty(%choreography, $PE_AFXChoreoEditor_DEFAULT_FILENAME);
+   
+   %this.loadNewChoreography(%choreography);
+   %this.setDirty();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::showDeleteDialog( %this )
+{
+   if( PE_AFXChoreoEditor.currChoreography.getName() $= "DefaultChoreography" )
+   {
+      toolsMessageBoxOK( "Error", "Cannot delete DefaultChoreography");
+      return;
+   }
+   
+   if( isObject( PE_AFXChoreoEditor.currChoreography ) )
+   {
+      toolsMessageBoxYesNoCancel("Delete Choreography?", 
+         "Are you sure you want to delete<br><br>" @ PE_AFXChoreoEditor.currChoreography.getName() @ "<br><br> Choreography deletion won't take affect until the level is exited.", 
+         "PE_AFXChoreoEditor.saveChoreographyDialogDontSave( " @ PE_AFXChoreoEditor.currChoreography.getName() @ " ); PE_AFXChoreoEditor.deleteChoreography();"
+      );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::deleteChoreography( %this )
+{  
+   %choreography = PE_AFXChoreoEditor.currChoreography;
+   
+   // Create undo.
+   
+   %action = ParticleEditor.createUndo( ActionDeleteChoreography, "Delete AFX Choreographer" );
+   %action.choreography = %choreography;
+   %action.choreographyFname = %choreography.getFilename();
+
+   ParticleEditor.submitUndo( %action );
+   
+   // Execute action.
+
+   %action.redo();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::saveChoreography( %this, %choreography )
+{   
+   if ( %choreography $= "" )
+   {
+      %choreography = %this.currChoreography;
+      %newName = %this.currChoreography.getName();
+   }
+   else
+   {
+      %newName = %choreography.getName();
+   }
+   
+   %this.currChoreography.setName( %newName );
+   PE_AFXChoreoEditor_NotDirtyChoreography.assignFieldsFrom( %choreography );
+   PE_AFXChoreoEditor_NotDirtyChoreography.originalName = %newName;
+   
+   %this.saver.saveDirty(); 
+   
+   %this.loadNewChoreography(%newName.getId());
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXChoreoEditor::saveChoreographyDialogDontSave( %this, %choreography)
+{  
+   %choreography.setName( PE_AFXChoreoEditor_NotDirtyChoreography.originalName );
+   %choreography.assignFieldsFrom( PE_AFXChoreoEditor_NotDirtyChoreography );
+   PE_AFXChoreoEditor.setNotDirty();
+}

+ 398 - 0
Templates/BaseGame/game/tools/particleEditor/scripts/afxZodiacEditor.ed.tscript

@@ -0,0 +1,398 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+$PE_AFXZodiacEditor_DEFAULT_FILENAME = "data/managedZodiacData." @ $TorqueScriptFileExtension;
+
+
+//=============================================================================================
+//    PE_AFXZodiacEditor.
+//=============================================================================================
+function PE_AFXZodiacEditor::init(%this)
+{
+   datablock afxZodiacData(PE_AFXZodiacEditor_NotDirtyEmitter)
+   {
+   };
+   
+   %this.unlistedSet.add(PE_AFXZodiacEditor_NotDirtyEmitter);
+}
+
+function PE_AFXZodiacEditor::openEditorTab(%this)
+{
+   PE_Window.text = ":: Particle Editor - AFX Zodiacs";
+   %this.guiSync();
+   ParticleEditor.activeEditor = %this;
+
+   if( !%this.dirty )
+      %this.setNotDirty();
+     
+   if( isObject( $ParticleEditor::zodiacNode ) )
+      $ParticleEditor::zodiacNode.setHidden(false);
+}
+
+function PE_AFXZodiacEditor::closeEditorTab(%this)
+{
+   if( isObject( $ParticleEditor::zodiacNode) )
+      $ParticleEditor::zodiacNode.delete();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::guiSync( %this )
+{
+   %this-->inspector.refresh();
+}
+
+function PE_AFXZodiacEditor::resetVizNode(%this, %tform)
+{
+   /*if( !isObject( $ParticleEditor::zodiacNode ) )
+   {
+      if( !isObject( TestZodiacData ) )
+      {
+         datablock ZodiacData( TestZodiacData )
+         {
+            timeMultiple = 1;
+         };
+      }
+
+      $ParticleEditor::zodiacNode = new afxZodiacPolysoupRenderer()
+      {
+         position = getWords( %tform, 0, 2 );
+         rotation = getWords( %tform, 3, 6 );
+         datablock = TestZodiacData;
+         parentGroup = MissionCleanup;
+      };
+   }
+   else
+   {
+      $ParticleEditor::zodiacNode.setTransform( %tform );
+      
+      %clientObject = $ParticleEditor::zodiacNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.setTransform( %tform );
+      
+      ParticleEditor.updateVizNode();
+   }
+   if (EWorldEditor.getSelectionSize()>0)
+   {
+        %obj = EWorldEditor.getSelectedObject(0);
+        if (%obj.isMemberOfClass("afxZodiacData"))
+            $ParticleEditor::zodiacNode.sethidden(true);
+   }  */
+}
+
+function PE_AFXZodiacEditor::updateVizNode(%this)
+{
+   /*if( isObject( $ParticleEditor::zodiacNode ) )
+   {
+      %id = %this.currZodiac;
+      
+      %clientObject = $ParticleEditor::zodiacNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.assignFieldsFrom( %id );
+   }
+   else
+      %this.resetVizNode();  */
+}
+
+//------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::selectObject(%this, %obj)
+{
+   if( isObject(%obj )
+       && %obj.getName() $= %this-->popupMenu.text )
+      return;
+      
+   //FIXME: disregards particle tab dirty state
+   if( %this.dirty )
+   {   
+      %savedZodiac = %this.currZodiac;
+      toolsMessageBoxYesNoCancel("Save Existing Zodiac?", 
+         "Do you want to save changes to <br><br>" @ %savedZodiac.getName(), 
+         "PE_AFXZodiacEditor.saveZodiac(" @ %savedZodiac@ "); PE_AFXZodiacEditor.loadNewZodiac(" @ %obj @ ");", 
+         "PE_AFXZodiacEditor.saveZodiacDialogDontSave(" @ %savedZodiac @ "); PE_AFXZodiacEditor.loadNewZodiac(" @ %obj @ ");"
+      );
+   }
+   else
+   {
+      %this.loadNewZodiac(%obj);
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::loadNewZodiac( %this, %zodiac )
+{
+   %this-->popupMenu.setText(%zodiac.getName());
+   %this-->inspector.inspect(%zodiac);
+   
+   if( isObject( %zodiac ) )
+      %current = %zodiac.getId();
+   else
+      %current = %this-->popupMenu.text;
+   
+   %this.currZodiac = %current;
+   PE_AFXZodiacEditor_NotDirtyZodiac.assignFieldsFrom( %current );
+   PE_AFXZodiacEditor_NotDirtyZodiac.originalName = %current.name;
+   
+   %this.guiSync();
+   %this.setNotDirty();
+      
+   //PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) );
+
+   %this.guiSync();
+   
+   PE_AFXZodiacEditor.updateVizNode();
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_AFXZodiacEditor::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   %action = ParticleEditor.createUndo(ActionUpdateActiveZodiac, "Update Active AFX Zodiac");
+   %action.zodiac = %object;
+   %action.field = %fieldName;
+   %action.isSlider = false;
+   %action.onMouseUp = true;
+   %action.newValue = %newValue;
+   %action.oldValue = %oldValue;
+   
+   ParticleEditor.submitUndo( %action );
+}
+
+// Generic updateZodiac method
+function PE_AFXZodiacEditor::updateZodiac( %this, %propertyField, %value, %isSlider, %onMouseUp )
+{
+   PE_AFXZodiacEditor.setDirty();
+         
+   %zodiac = %this.currZodiac;
+      
+   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
+   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
+   {
+      %last.field = %propertyField;
+      %last.isSlider = %isSlider;
+      %last.onMouseUp = %onMouseUp;
+      %last.newValue = %value;
+   }
+   else
+   {
+      %action = ParticleEditor.createUndo(ActionUpdateActiveZodiac, "Update Active AFX Zodiac");
+      %action.zodiac = %zodiac;
+      %action.field = %propertyField;
+      %action.isSlider = %isSlider;
+      %action.onMouseUp = %onMouseUp;
+      %action.newValue = %value;
+      %action.oldValue = %zodiac.getFieldValue( %propertyField );
+      
+      ParticleEditor.submitUndo( %action );
+   }
+   	
+	%zodiac.setFieldValue( %propertyField, %value );
+	%zodiac.reload();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::setDirty( %this )
+{
+   %this.text = "*Zodiac";
+   %this.dirty = true;
+   
+   if(!startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = "*" @ %this-->PopupMenu.text;
+   }
+   
+   %zodiac = %this.currZodiac;
+   %filename = %zodiac.getFilename();
+   %editorFilename = "tools/particleEditor/scripts/afxZodiacEditor.ed." @ $TorqueScriptFileExtension;
+   
+   if( %filename $= "" || %filename $= %editorFilename )
+      %this.saver.setDirty( %zodiac, $PE_AFXZodiacEditor_DEFAULT_FILENAME );
+   else
+      %this.saver.setDirty( %zodiac );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::setNotDirty( %this )
+{   
+   PE_AFXZodiacEditor.text = "Zodiac";
+   PE_AFXZodiacEditor.dirty = false;
+   
+   if(startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = stripChars(%this-->PopupMenu.text, "*");
+   }
+   
+   %this.saver.clearAll();
+}
+
+//---------------------------------------------------------------------------------------------
+
+// Create Functionality
+function PE_AFXZodiacEditor::showNewDialog( %this )
+{
+   if( PE_AFXZodiacEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save Zodiac Changes?", 
+         "Do you wish to save the changes made to the <br>current zodiac before changing the zodiac?", 
+         "PE_AFXZodiacEditor.saveZodiac( " @ PE_AFXZodiacEditor.currZodiac.getName() @ " ); PE_AFXZodiacEditor.createZodiac();", 
+         "PE_AFXZodiacEditor.saveZodiacDialogDontSave( " @ PE_AFXZodiacEditor.currZodiac.getName() @ " ); PE_AFXZodiacEditor.createZodiac();"
+      );
+   }
+   else
+   {
+      PE_AFXZodiacEditor.createZodiac();
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::createZodiac( %this )
+{
+   AssetBrowser_SelectModule.showDialog("PE_AFXZodiacEditor.pickedNewZodiacTargetModule");
+   AssetBrowser_SelectModuleWindow.selectWindow();
+}
+
+function PE_AFXZodiacEditor::pickedNewZodiacTargetModule( %this, %module )
+{
+   ParticleEditorCreatePrompt.show("Zodiac", "afxZodiacData", "PE_AFXZodiacEditor.doCreateNewZodiac(\"" @ %module @ "\");" );
+}
+
+function PE_AFXZodiacEditor::doCreateNewZodiac( %this, %module )
+{
+   //Sanity checks
+   %newName = ParticleEditorCreatePrompt-->nameText.getText();
+   if(%newName $= "")
+   {
+      toolsMessageBoxOK("Error", "New Zodiac requires a name!");
+      return;
+   }
+   
+   Canvas.popDialog(ParticleEditorCreatePrompt);
+   
+   %sourceDB = ParticleEditorCreatePrompt-->CopySourceDropdown.getText();
+   
+   if(%sourceDB $= "")
+      %sourceDB = DefaultZodiac;
+   
+   %moduleDef = ModuleDatabase.findModule(%module);
+   PE_AFXZodiacEditor.targetModule = %module;
+   $PE_AFXZodiacEditor_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedZodiacData." @ $TorqueScriptFileExtension;
+   
+   if(!isDirectory(filePath($PE_AFXZodiacEditor_DEFAULT_FILENAME)))
+   {
+      AssetBrowser.dirHandler.createFolder(filePath($PE_AFXZodiacEditor_DEFAULT_FILENAME));
+   }
+   
+   // Create a new zodiac.
+   %zodiac = getUniqueName( %newName );
+   eval("datablock ZodiacData( " @ %zodiac @ " : " @ %sourceDB @ " ){};");
+   
+   // Submit undo.
+   
+   %action = ParticleEditor.createUndo( ActionCreateNewZodiac, "Create New AFX Zodiac" );
+   %action.prevZodiac = PE_AFXZodiacEditor.currZodiac;
+   %action.zodiac = %zodiac.getId();
+   %action.zodiacName = %zodiac;
+
+   ParticleEditor.submitUndo( %action );
+
+   // Execute action.
+   %action.redo();
+   
+   %this.saver.setDirty(%zodiac, $PE_AFXZodiacEditor_DEFAULT_FILENAME);
+   
+   %this.loadNewZodiac(%zodiac);
+   %this.setDirty();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::showDeleteDialog( %this )
+{
+   if( PE_AFXZodiacEditor.currZodiac.getName() $= "DefaultZodiac" )
+   {
+      toolsMessageBoxOK( "Error", "Cannot delete DefaultZodiac");
+      return;
+   }
+   
+   if( isObject( PE_AFXZodiacEditor.currZodiac ) )
+   {
+      toolsMessageBoxYesNoCancel("Delete Zodiac?", 
+         "Are you sure you want to delete<br><br>" @ PE_AFXZodiacEditor.currZodiac.getName() @ "<br><br> Zodiac deletion won't take affect until the level is exited.", 
+         "PE_AFXZodiacEditor.saveZodiacDialogDontSave( " @ PE_AFXZodiacEditor.currZodiac.getName() @ " ); PE_AFXZodiacEditor.deleteZodiac();"
+      );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::deleteZodiac( %this )
+{  
+   %zodiac = PE_AFXZodiacEditor.currZodiac;
+   
+   // Create undo.
+   
+   %action = ParticleEditor.createUndo( ActionDeleteZodiac, "Delete Zodiac" );
+   %action.zodiac = %zodiac;
+   %action.zodiacFname = %zodiac.getFilename();
+
+   ParticleEditor.submitUndo( %action );
+   
+   // Execute action.
+
+   %action.redo();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::saveZodiac( %this, %zodiac )
+{   
+   if ( %zodiac $= "" )
+   {
+      %zodiac = %this.currZodiac;
+      %newName = %this.currZodiac.getName();
+   }
+   else
+   {
+      %newName = %zodiac.getName();
+   }
+   
+   %this.currZodiac.setName( %newName );
+   PE_AFXZodiacEditor_NotDirtyZodiac.assignFieldsFrom( %zodiac );
+   PE_AFXZodiacEditor_NotDirtyZodiac.originalName = %newName;
+   
+   %this.saver.saveDirty(); 
+   
+   %this.loadNewZodiac(%newName.getId());
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_AFXZodiacEditor::saveZodiacDialogDontSave( %this, %zodiac)
+{  
+   %zodiac.setName( PE_AFXZodiacEditor_NotDirtyZodiac.originalName );
+   %zodiac.assignFieldsFrom( PE_AFXZodiacEditor_NotDirtyZodiac );
+   PE_AFXZodiacEditor.setNotDirty();
+}

+ 490 - 0
Templates/BaseGame/game/tools/particleEditor/scripts/explosionEditor.ed.tscript

@@ -0,0 +1,490 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+$PE_ExplosionEditor_DEFAULT_FILENAME = "data/managedExplosionData." @ $TorqueScriptFileExtension;
+
+
+//=============================================================================================
+//    PE_ExplosionEditor.
+//=============================================================================================
+function PE_ExplosionEditor::init(%this)
+{
+   datablock ExplosionData(PE_ExplosionEditor_NotDirtyEmitter)
+   {
+      emitters = "DefaultEmitter";
+   };
+   
+   %this.unlistedSet.add(PE_ExplosionEditor_NotDirtyEmitter);
+}
+
+function PE_ExplosionEditor::openEditorTab(%this)
+{
+   PE_Window.text = ":: Particle Editor - Explosions";
+   %this.guiSync();
+   ParticleEditor.activeEditor = %this;
+
+   if( !%this.dirty )
+      %this.setNotDirty();
+     
+   if( isObject( $ParticleEditor::explosionNode ) )
+      $ParticleEditor::explosionNode.setHidden(false);
+}
+
+function PE_ExplosionEditor::closeEditorTab(%this)
+{
+   if( isObject( $ParticleEditor::explosionNode) )
+      $ParticleEditor::explosionNode.delete();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::guiSync( %this )
+{
+   %this-->inspector.refresh();
+}
+
+function PE_ExplosionEditor::resetVizNode(%this, %tform)
+{
+   if( !isObject( $ParticleEditor::explosionNode ) )
+   {
+      if( !isObject( TestExplosionData ) )
+      {
+         datablock ExplosionData( TestExplosionData )
+         {
+            timeMultiple = 1;
+         };
+      }
+
+      $ParticleEditor::explosionNode = new Explosion()
+      {
+         position = getWords( %tform, 0, 2 );
+         rotation = getWords( %tform, 3, 6 );
+         datablock = TestExplosionData;
+         parentGroup = MissionCleanup;
+      };
+   }
+   else
+   {
+      $ParticleEditor::explosionNode.setTransform( %tform );
+      
+      %clientObject = $ParticleEditor::explosionNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.setTransform( %tform );
+      
+      %this.updateVizNode();
+   }
+   if (EWorldEditor.getSelectionSize()>0)
+   {
+        %obj = EWorldEditor.getSelectedObject(0);
+        if (%obj.isMemberOfClass("Explosion"))
+            $ParticleEditor::explosionNode.sethidden(true);
+   }  
+}
+
+function PE_ExplosionEditor::updateVizNode(%this)
+{
+   if( isObject( $ParticleEditor::explosionNode ) )
+   {
+      %id = %this.currExplosion;
+      
+      %clientObject = $ParticleEditor::explosionNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.assignFieldsFrom( %id );
+   }
+   else
+      %this.resetVizNode();  
+}
+
+//------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::selectObject(%this, %obj)
+{
+   if( isObject(%obj )
+       && %obj.getName() $= %this-->popupMenu.text )
+      return;
+      
+   //FIXME: disregards particle tab dirty state
+   if( %this.dirty )
+   {   
+      if( PE_ParticleEditor.dirty )
+      {         
+         toolsMessageBoxYesNo("Save Existing Explosion?", 
+            "Do you want to save changes to <br><br>" @ %this.currParticle.getName(), 
+            "PE_ParticleEditor.saveParticle(" @ %this.currParticle @ ");"
+         );
+      }
+            
+      %savedExplosion = %this.currExplosion;
+      toolsMessageBoxYesNoCancel("Save Existing Explosion?", 
+         "Do you want to save changes to <br><br>" @ %savedExplosion.getName(), 
+         "PE_ExplosionEditor.saveExplosion(" @ %savedExplosion@ "); PE_ExplosionEditor.loadNewExplosion(" @ %obj @ ");", 
+         "PE_ExplosionEditor.saveExplosionDialogDontSave(" @ %savedExplosion @ "); PE_ExplosionEditor.loadNewExplosion(" @ %obj @ ");"
+      );
+   }
+   else
+   {
+      %this.loadNewExplosion(%obj);
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::loadNewExplosion( %this, %explosion )
+{
+   %this-->popupMenu.setText(%explosion.getName());
+   %this-->inspector.inspect(%explosion);
+   
+   if( isObject( %explosion ) )
+      %current = %explosion.getId();
+   else
+      %current = %this-->popupMenu.text;
+   
+   %this.currExplosion = %current;
+   PE_ExplosionEditor_NotDirtyExplosion.assignFieldsFrom( %current );
+   PE_ExplosionEditor_NotDirtyExplosion.originalName = %current.name;
+   
+   %this.guiSync();
+   %this.setNotDirty();
+      
+   //PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) );
+
+   %this.guiSync();
+   
+   PE_ExplosionEditor.updateVizNode();
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_ExplosionEditor::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   %action = ParticleEditor.createUndo(ActionUpdateActiveExplosion, "Update Active Explosion");
+   %action.explosion = %object;
+   %action.field = %fieldName;
+   %action.isSlider = false;
+   %action.onMouseUp = true;
+   %action.newValue = %newValue;
+   %action.oldValue = %oldValue;
+   
+   ParticleEditor.submitUndo( %action );
+}
+
+// Generic updateExplosion method
+function PE_ExplosionEditor::updateExplosion( %this, %propertyField, %value, %isSlider, %onMouseUp )
+{
+   PE_ExplosionEditor.setDirty();
+         
+   %explosion = %this.currExplosion;
+      
+   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
+   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
+   {
+      %last.field = %propertyField;
+      %last.isSlider = %isSlider;
+      %last.onMouseUp = %onMouseUp;
+      %last.newValue = %value;
+   }
+   else
+   {
+      %action = ParticleEditor.createUndo(ActionUpdateActiveExplosion, "Update Active Explosion");
+      %action.explosion = %explosion;
+      %action.field = %propertyField;
+      %action.isSlider = %isSlider;
+      %action.onMouseUp = %onMouseUp;
+      %action.newValue = %value;
+      %action.oldValue = %explosion.getFieldValue( %propertyField );
+      
+      ParticleEditor.submitUndo( %action );
+   }
+   	
+	%explosion.setFieldValue( %propertyField, %value );
+	%explosion.reload();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::updateParticlesFields( %this )
+{
+   %particles = "";
+   for( %i = 1; %i < 5; %i ++ )
+   {
+      %explosionParticle = "PEE_ExplosionParticle" @ %i;
+      %popup = %explosionParticle-->PopUpMenu;
+      %text = %popup.getText();
+      
+      if( %text $= "" || %text $= "None" )
+         continue;
+         
+      if( %particles $= "" )
+         %particles = %text;
+      else
+         %particles = %particles SPC %text;
+   }
+   
+   %changedEditParticle = 1;
+   %currParticle = PE_ParticleEditor.currParticle.getName();
+
+   foreach$( %particleName in %particles )
+   {
+      if( %particleName $= %currParticle )
+      {
+         %changedEditParticle = 0; 
+         break;
+      }
+   }
+   
+   // True only if the currently edited particle has not been found and the 
+   // ParticleEditor is dirty.
+   
+   if( %changedEditParticle && PE_ParticleEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save Particle Changes?", 
+         "Do you wish to save the changes made to the <br>current particle before changing the particle?", 
+         "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ExplosionEditor.updateExplosion( \"particles\"," @ %particles @ ");", 
+         "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ExplosionEditor.updateExplosion( \"particles\"," @ %particles @ ");", 
+         "PE_ExplosionEditor.guiSync();" );
+   }
+   else
+   {
+      PE_ExplosionEditor.updateExplosion( "particles", %particles );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::setDirty( %this )
+{
+   %this.text = "*Explosion";
+   %this.dirty = true;
+   
+   if(!startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = "*" @ %this-->PopupMenu.text;
+   }
+   
+   %explosion = %this.currExplosion;
+   %filename = %explosion.getFilename();
+   %editorFilename = "tools/particleEditor/scripts/explosionEditor.ed." @ $TorqueScriptFileExtension;
+   
+   if( %filename $= "" || %filename $= %editorFilename )
+      %this.saver.setDirty( %explosion, $PE_ExplosionEditor_DEFAULT_FILENAME );
+   else
+      %this.saver.setDirty( %explosion );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::setNotDirty( %this )
+{   
+   PE_ExplosionEditor.text = "Explosion";
+   PE_ExplosionEditor.dirty = false;
+   
+   if(startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = stripChars(%this-->PopupMenu.text, "*");
+   }
+   
+   %this.saver.clearAll();
+}
+
+//---------------------------------------------------------------------------------------------
+
+// Create Functionality
+function PE_ExplosionEditor::showNewDialog( %this )
+{
+   //FIXME: disregards particle tab dirty state
+
+   // Open a dialog if the current explosion is dirty.
+   
+   if( PE_ParticleEditor.dirty )
+   {         
+      toolsMessageBoxYesNo("Save Existing Particle?", 
+         "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), 
+         "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");"
+      );
+   }   
+   
+   if( PE_ExplosionEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save Explosion Changes?", 
+         "Do you wish to save the changes made to the <br>current explosion before changing the explosion?", 
+         "PE_ExplosionEditor.saveExplosion( " @ PE_ExplosionEditor.currExplosion.getName() @ " ); PE_ExplosionEditor.createExplosion();", 
+         "PE_ExplosionEditor.saveExplosionDialogDontSave( " @ PE_ExplosionEditor.currExplosion.getName() @ " ); PE_ExplosionEditor.createExplosion();"
+      );
+   }
+   else
+   {
+      PE_ExplosionEditor.createExplosion();
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::createExplosion( %this )
+{
+   AssetBrowser_SelectModule.showDialog("PE_ExplosionEditor.pickedNewExplosionTargetModule");
+   AssetBrowser_SelectModuleWindow.selectWindow();
+}
+
+function PE_ExplosionEditor::pickedNewExplosionTargetModule( %this, %module )
+{
+   ParticleEditorCreatePrompt.show("Explosion", "ExplosionData", "PE_ExplosionEditor.doCreateNewExplosion(\"" @ %module @ "\");" );
+}
+
+function PE_ExplosionEditor::doCreateNewExplosion( %this, %module )
+{
+   //Sanity checks
+   %newName = ParticleEditorCreatePrompt-->nameText.getText();
+   if(%newName $= "")
+   {
+      toolsMessageBoxOK("Error", "New Explosion requires a name!");
+      return;
+   }
+   
+   Canvas.popDialog(ParticleEditorCreatePrompt);
+   
+   %sourceDB = ParticleEditorCreatePrompt-->CopySourceDropdown.getText();
+   
+   if(%sourceDB $= "")
+      %sourceDB = DefaultExplosion;
+   
+   %moduleDef = ModuleDatabase.findModule(%module);
+   PE_ExplosionEditor.targetModule = %module;
+   $PE_ExplosionEditor_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedExplosionData." @ $TorqueScriptFileExtension;
+   
+   if(!isDirectory(filePath($PE_ExplosionEditor_DEFAULT_FILENAME)))
+   {
+      AssetBrowser.dirHandler.createFolder(filePath($PE_ExplosionEditor_DEFAULT_FILENAME));
+   }
+   
+   // Create a new explosion.
+   %explosion = getUniqueName( %newName );
+   eval("datablock ExplosionData( " @ %explosion @ " : " @ %sourceDB @ " ){};");
+   
+   // Submit undo.
+   
+   %action = ParticleEditor.createUndo( ActionCreateNewExplosion, "Create New Explosion" );
+   %action.prevExplosion = PE_ExplosionEditor.currExplosion;
+   %action.explosion = %explosion.getId();
+   %action.explosionName = %explosion;
+
+   ParticleEditor.submitUndo( %action );
+
+   // Execute action.
+   %action.redo();
+   
+   %this.saver.setDirty(%explosion, $PE_ExplosionEditor_DEFAULT_FILENAME);
+   
+   %this.loadNewExplosion(%explosion);
+   %this.setDirty();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::showDeleteDialog( %this )
+{
+   if( PE_ExplosionEditor.currExplosion.getName() $= "DefaultExplosion" )
+   {
+      toolsMessageBoxOK( "Error", "Cannot delete DefaultExplosion");
+      return;
+   }
+   
+   if( isObject( PE_ExplosionEditor.currExplosion ) )
+   {
+      toolsMessageBoxYesNoCancel("Delete Explosion?", 
+         "Are you sure you want to delete<br><br>" @ PE_ExplosionEditor.currExplosion.getName() @ "<br><br> Explosion deletion won't take affect until the level is exited.", 
+         "PE_ExplosionEditor.saveExplosionDialogDontSave( " @ PE_ExplosionEditor.currExplosion.getName() @ " ); PE_ExplosionEditor.deleteExplosion();"
+      );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::deleteExplosion( %this )
+{  
+   %explosion = PE_ExplosionEditor.currExplosion;
+   
+   // Create undo.
+   
+   %action = ParticleEditor.createUndo( ActionDeleteExplosion, "Delete Explosion" );
+   %action.explosion = %explosion;
+   %action.explosionFname = %explosion.getFilename();
+
+   ParticleEditor.submitUndo( %action );
+   
+   // Execute action.
+
+   %action.redo();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::saveExplosion( %this, %explosion )
+{   
+   if ( %explosion $= "" )
+   {
+      %explosion = %this.currExplosion;
+      %newName = %this.currExplosion.getName();
+   }
+   else
+   {
+      %newName = %explosion.getName();
+   }
+   
+   //Sanity check our sub-explosions so we don't have recursions!
+   for(%i=0; %i < getWordCount(%explosion.subExplosion); %i++)
+   {
+      %subExpl = getWord(%explosion.subExplosion, %i);
+      if(%subExpl.getId() == %explosion.getId())
+      {
+         toolsMessageBoxOK("Error!", "Cannot save because subExplosion[" @ %i @ "] is pointed at this explosion, which would create a loop!");
+         return;  
+      }
+      
+      for(%si=0; %si < getWordCount(%subExpl.subExplosion); %si++)
+      {
+         %subSubExpl = getWord(%subExpl.subExplosion, %i);
+         if(%subSubExpl.getId() == %explosion.getId())
+         {
+            toolsMessageBoxOK("Error!", "Cannot save because subExplosion[" @ %i @ "] has a subExplosion that is pointed at this explosion, which would create a loop!");
+            return;  
+         }  
+      }
+   }
+   
+   %this.currExplosion.setName( %newName );
+   PE_ExplosionEditor_NotDirtyExplosion.assignFieldsFrom( %explosion );
+   PE_ExplosionEditor_NotDirtyExplosion.originalName = %newName;
+   
+   %this.saver.saveDirty(); 
+   
+   %this.loadNewExplosion(%newName.getId());
+
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ExplosionEditor::saveExplosionDialogDontSave( %this, %explosion)
+{  
+   %explosion.setName( PE_ExplosionEditor_NotDirtyExplosion.originalName );
+   %explosion.assignFieldsFrom( PE_ExplosionEditor_NotDirtyExplosion );
+   PE_ExplosionEditor.setNotDirty();
+}

+ 1070 - 0
Templates/BaseGame/game/tools/particleEditor/scripts/particleEditorUndo.ed.tscript

@@ -0,0 +1,1070 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+//=============================================================================================
+//    ParticleEditor.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ParticleEditor::createUndo( %this, %class, %desc )
+{
+   pushInstantGroup();
+   %action = new UndoScriptAction()
+   {
+      class = %class;
+      superClass = BaseParticleEdAction;
+      actionName = %desc;
+   };
+   popInstantGroup();
+   return %action;
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ParticleEditor::submitUndo( %this, %action )
+{
+   %action.addToManager( Editor.getUndoManager() );
+}
+
+//=============================================================================================
+//    BaseParticleEdAction.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function BaseParticleEdAction::sync( %this )
+{
+   // Sync particle state.
+   
+   if( isObject( %this.particle ) )
+   {
+      %this.particle.reload();
+      PE_ParticleEditor.guiSync();
+      
+      if( %this.particle.getId() == PE_ParticleEditor.currParticle.getId() )
+         PE_ParticleEditor.setDirty();
+   }
+
+   // Sync emitter state.
+
+   if( isObject( %this.emitter ) )
+   {
+      %this.emitter.reload();
+      
+      PE_EmitterEditor.guiSync();
+
+      if( %this.emitter.getId() == PE_EmitterEditor.currEmitter.getId() )
+         PE_EmitterEditor.setDirty();
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function BaseParticleEdAction::redo( %this )
+{
+   %this.sync();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function BaseParticleEdAction::undo( %this )
+{
+   %this.sync();
+}
+
+//=============================================================================================
+//    ActionRenameEmitter.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+//TODO
+
+//=============================================================================================
+//    ActionCreateNewEmitter.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewEmitter::redo( %this )
+{
+   %emitter = %this.emitter;
+   
+   // Assign name.
+   %emitter.name = %this.emitterName;
+   
+   // Remove from unlisted.
+   PE_EmitterEditor.unlistedSet.remove( %emitter );
+   
+   // Drop it in the dropdown and select it.
+   PE_EmitterEditor.selectObject(%emitter);
+   
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewEmitter::undo( %this )
+{
+   %emitter = %this.emitter;
+      
+   // Prevent a save dialog coming up on the emitter.
+   if( %emitter == PE_EmitterEditor.currEmitter )
+      PE_EmitterEditor.setNotDirty();
+   
+   // Add to unlisted.
+   PE_EmitterEditor.unlistedSet.add( %emitter );
+   
+   // Remove it from in the dropdown and select prev emitter.
+   %popup = PE_EmitterEditor-->popupMenu;
+      
+   if( isObject( %this.prevEmitter ) )
+   {
+      PE_EmitterEditor.selectedObject(%this.prevEmitter);
+   }
+   else
+   {
+      PE_EmitterEditor-->popupMenu.text = "";
+      PE_EmitterEditor-->inspector.inspect();
+   }
+
+   // Unassign name.
+   %this.emitterName = %emitter.name;
+   %emitter.name = "";
+
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionDeleteEmitter.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteEmitter::redo( %this )
+{
+   %emitter = %this.emitter;
+      
+   // Unassign name.
+   
+   %this.emitterName = %emitter.name;
+   %emitter.name = "";
+
+   // Add to unlisted.
+   
+   PE_EmitterEditor.unlistedSet.add( %emitter );
+   
+   // Remove from file.
+   
+   if(    %emitter.getFileName() !$= ""
+       && %emitter.getFilename() !$= "tools/particleEditor/scripts/particleEmitterEditor.ed." @ $TorqueScriptFileExtension )
+      PE_EmitterEditor.saver.removeObjectFromFile( %emitter );
+      
+   // Select DefaultEmitter or first in list.
+   
+   %popup = PE_EmitterEditor-->PopUpMenu.text = "";
+
+   PE_EmitterEditor-->inspector.inspect();
+
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteEmitter::undo( %this )
+{
+   %emitter = %this.emitter;
+      
+   // Re-assign name.
+   
+   %emitter.name = %this.emitterName;
+
+   // Remove from unlisted.
+   
+   PE_EmitterEditor.unlistedSet.remove( %emitter );
+   
+   // Resave to file.
+   
+   if(    %emitter.getFilename() !$= ""
+       && %emitter.getFilename() !$= "tools/particleEditor/scripts/particleEmitterEditor.ed." @ $TorqueScriptFileExtension )
+   {
+      PE_EmitterEditor.saver.setDirty( %emitter, %emitter.getFilename() );
+      PE_EmitterEditor.saver.saveDirty();
+   }
+
+   // Add it to the dropdown and selet it.
+   PE_EmitterEditor.selectedObject(%emitter);
+   
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveEmitter.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveEmitter::redo( %this )
+{
+   %emitter = %this.emitter;
+   %emitter.setFieldValue( %this.field, %this.newValue );
+   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveEmitter::undo( %this )
+{
+   %emitter = %this.emitter;
+   %emitter.setFieldValue( %this.field, %this.oldValue );
+   
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionCreateNewParticle.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewParticle::redo( %this )
+{
+   %particle = %this.particle.getName();
+   %particleId = %this.particle.getId();
+   %particleIndex = %this.particleIndex;
+   %emitter = %this.emitter;
+   
+   // Remove from unlisted.
+   
+   PE_UnlistedParticles.remove( %particleId );
+   
+   // Add it to the dropdown.
+   
+   PEP_ParticleSelector.add( %particle, %particleId );
+   PEP_ParticleSelector.sort();
+   PEP_ParticleSelector.setSelected( %particleId, false );
+         
+   // Add particle to dropdowns in the emitter editor.
+   
+   for( %i = 1; %i < 5; %i ++ )
+   {
+      %emitterParticle = "PEE_EmitterParticle" @ %i;
+      %popup = %emitterParticle-->PopupMenu;
+      
+      %popup.add( %particle, %particleId );
+      %popup.sort();
+      
+      if( %i == %particleIndex + 1 )
+         %popup.setSelected( %particleId );
+   }
+   
+   // Sync up.
+   
+   PE_ParticleEditor.loadNewParticle();
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewParticle::undo( %this )
+{
+   %particle = %this.particle.getName();
+   %particleId = %this.particle.getId();
+   %emitter = %this.emitter;
+   
+   // Add to unlisted.
+   
+   PE_UnlistedParticles.add( %particleId );
+      
+   // Remove from dropdown.
+   
+   PEP_ParticleSelector.clearEntry( %particleId );
+   PEP_ParticleSelector.setFirstSelected( false );
+      
+   // Remove from particle dropdowns in emitter editor.
+   
+   for( %i = 1; %i < 5; %i ++ )
+   {
+      %emitterParticle = "PEE_EmitterParticle" @ %i;
+      %popup = %emitterParticle-->PopUpMenu;
+      
+      if( %popup.getSelected() == %particleId )
+         %popup.setSelected( %this.prevParticle );
+         
+      %popup.clearEntry( %particleId );
+   }
+   
+   // Sync up.
+   
+   PE_ParticleEditor.loadNewParticle();
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionDeleteParticle.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteParticle::redo( %this )
+{
+   %particle = %this.particle.getName();
+   %particleId = %this.particle.getId();
+   %emitter = %this.emitter;
+   
+   // Add to unlisted.
+   
+   PE_UnlistedParticles.add( %particleId );
+   
+   // Remove from file.
+   
+   if(    %particle.getFileName() !$= ""
+       && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed." @ $TorqueScriptFileExtension )
+      PE_ParticleSaver.removeObjectFromFile( %particleId );
+      
+   // Remove from dropdown.
+   
+   PEP_ParticleSelector.clearEntry( %particleId );
+   PEP_ParticleSelector.setFirstSelected();
+   
+   // Remove from particle selectors in emitter.
+   
+   for( %i = 1; %i < 5; %i ++ )
+   {
+      %emitterParticle = "PEE_EmitterParticle" @ %i;
+      %popup = %emitterParticle-->PopUpMenu;
+      
+      if( %popup.getSelected() == %particleId )
+      {
+         %this.particleIndex = %i - 1;
+         %popup.setSelected( 0 ); // Select "None".
+      }
+      
+      %popup.clearEntry( %particleId );
+   }
+   
+   // Sync up.
+   
+   PE_ParticleEditor.loadNewParticle();   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteParticle::undo( %this )
+{
+   %particle = %this.particle.getName();
+   %particleId = %this.particle.getId();
+   %particleIndex = %this.particleIndex;
+   %emitter = %this.emitter;
+   
+   // Remove from unlisted.
+   
+   PE_UnlistedParticles.remove( %particleId );
+
+   // Resave to file.
+   
+   if(    %particle.getFilename() !$= ""
+       && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed." @ $TorqueScriptFileExtension )
+   {
+      PE_ParticleSaver.setDirty( %particle );
+      PE_ParticleSaver.saveDirty();
+   }
+   
+   // Add to dropdown.
+   
+   PEP_ParticleSelector.add( %particle, %particleId );
+   PEP_ParticleSelector.sort();
+   PEP_ParticleSelector.setSelected( %particleId );
+         
+   // Add particle to dropdowns in the emitter editor.
+   
+   for( %i = 1; %i < 5; %i ++ )
+   {
+      %emitterParticle = "PEE_EmitterParticle" @ %i;
+      %popup = %emitterParticle-->PopUpMenu;
+      
+      %popup.add( %particle, %particleId );
+      %popup.sort();
+      
+      if( %i == %particleIndex + 1 )
+         %popup.setSelected( %particleId );
+   }
+   
+   // Sync up.
+   
+   PE_ParticleEditor.loadNewParticle();
+   Parent::undo( %This );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveParticle.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveParticle::redo( %this )
+{
+   %particle = %this.particle;
+   %particle.setFieldValue( %this.field, %this.newValue );
+   
+   Parent::redo( %this );
+}
+
+function ActionUpdateActiveParticle::undo( %this )
+{
+   %particle = %this.particle;   
+   %particle.setFieldValue( %this.field, %this.oldValue );
+   
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveParticleLifeFields.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveParticleLifeFields::redo( %this )
+{
+   %particle = %this.particle;
+   
+   %particle.lifetimeMS = %this.newValueLifetimeMS;
+   %particle.lifetimeVarianceMS = %this.newValueLifetimeVarianceMS;
+   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveParticleLifeFields::undo( %this )
+{
+   %particle = %this.particle;
+
+   %particle.lifetimeMS = %this.oldValueLifetimeMS;
+   %particle.lifetimeVarianceMS = %this.oldValueLifetimeVarianceMS;
+
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveParticleSpinFields.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveParticleSpinFields::redo( %this )
+{
+   %particle = %this.particle;
+   
+   %particle.spinRandomMax = %this.newValueSpinRandomMax;
+   %particle.spinRandomMin = %this.newValueSpinRandomMin;
+   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveParticleSpinFields::undo( %this )
+{
+   %particle = %this.particle;
+
+   %particle.spinRandomMax = %this.oldValueSpinRandomMax;
+   %particle.spinRandomMin = %this.oldValueSpinRandomMin;
+   
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionCreateNewExplosion.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewExplosion::redo( %this )
+{
+   %explosion = %this.explosion;
+   
+   // Assign name.
+   %explosion.name = %this.explosionName;
+   
+   // Remove from unlisted.
+   PE_ExplosionEditor.unlistedSet.remove( %explosion );
+   
+   // Drop it in the dropdown and select it.
+   PE_ExplosionEditor.selectObject(%explosion);
+   
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewExplosion::undo( %this )
+{
+   %explosion = %this.explosion;
+      
+   // Prevent a save dialog coming up on the emitter.
+   if( %explosion == PE_ExplosionEditor.currExplosion )
+      PE_ExplosionEditor.setNotDirty();
+   
+   // Add to unlisted.
+   PE_ExplosionEditor.unlistedSet.add( %explosion );
+   
+   // Remove it from in the dropdown and select prev emitter.
+   %popup = PE_ExplosionEditor-->popupMenu;
+      
+   if( isObject( %this.prevExplosion ) )
+   {
+      PE_ExplosionEditor.selectedObject(%this.prevExplosion);
+   }
+   else
+   {
+      PE_ExplosionEditor-->popupMenu.text = "";
+      PE_ExplosionEditor-->inspector.inspect();
+   }
+
+   // Unassign name.
+   %this.explosionName = %explosion.name;
+   %explosion.name = "";
+
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionDeleteExplosion.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteExplosion::redo( %this )
+{
+   %explosion = %this.explosion;
+      
+   // Unassign name.
+   %this.explosionName = %explosion.name;
+   %explosion.name = "";
+
+   // Add to unlisted.
+   PE_ExplosionEditor.unlistedSet.add( %explosion );
+   
+   // Remove from file.
+   if(    %explosion.getFileName() !$= ""
+       && %explosion.getFilename() !$= "tools/particleEditor/scripts/explosionEditor.ed." @ $TorqueScriptFileExtension )
+      PE_ExplosionEditor.saver.removeObjectFromFile( %explosion );
+      
+   // Select DefaultExplosion or first in list.
+   
+   %popup = PE_ExplosionEditor-->PopUpMenu.text = "";
+
+   PE_ExplosionEditor-->inspector.inspect();
+
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteExplosion::undo( %this )
+{
+   %explosion = %this.explosion;
+      
+   // Re-assign name.
+   %explosion.name = %this.explosionName;
+
+   // Remove from unlisted.
+   
+   PE_ExplosionEditor.unlistedSet.remove( %explosion );
+   
+   // Resave to file.
+   
+   if(    %explosion.getFilename() !$= ""
+       && %explosion.getFilename() !$= "tools/particleEditor/scripts/particleExplosionEditor.ed." @ $TorqueScriptFileExtension )
+   {
+      PE_ExplosionEditor.saver.setDirty( %explosion, %explosion.getFilename() );
+      PE_ExplosionEditor.saver.saveDirty();
+   }
+
+   // Add it to the dropdown and selet it.
+   PE_ExplosionEditor.selectedObject(%explosion);
+   
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveExplosion.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveExplosion::redo( %this )
+{
+   %explosion = %this.explosion;
+   %explosion.setFieldValue( %this.field, %this.newValue );
+   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveExplosion::undo( %this )
+{
+   %explosion = %this.explosion;
+   %explosion.setFieldValue( %this.field, %this.oldValue );
+   
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionCreateNewZodiac.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewZodiac::redo( %this )
+{
+   %zodiac = %this.zodiac;
+   
+   // Assign name.
+   %zodiac.name = %this.zodiacName;
+   
+   // Remove from unlisted.
+   PE_ZodiacEditor.unlistedSet.remove( %zodiac );
+   
+   // Drop it in the dropdown and select it.
+   PE_ZodiacEditor.selectObject(%zodiac);
+   
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewZodiac::undo( %this )
+{
+   %zodiac = %this.zodiac;
+      
+   // Prevent a save dialog coming up on the emitter.
+   if( %zodiac == PE_ZodiacEditor.currZodiac )
+      PE_ZodiacEditor.setNotDirty();
+   
+   // Add to unlisted.
+   PE_ZodiacEditor.unlistedSet.add( %zodiac );
+   
+   // Remove it from in the dropdown and select prev emitter.
+   %popup = PE_ZodiacEditor-->popupMenu;
+      
+   if( isObject( %this.prevZodiac ) )
+   {
+      PE_ZodiacEditor.selectedObject(%this.prevZodiac);
+   }
+   else
+   {
+      PE_ZodiacEditor-->popupMenu.text = "";
+      PE_ZodiacEditor-->inspector.inspect();
+   }
+
+   // Unassign name.
+   %this.zodiacName = %zodiac.name;
+   %zodiac.name = "";
+
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionDeleteZodiac.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteZodiac::redo( %this )
+{
+   %zodiac = %this.zodiac;
+      
+   // Unassign name.
+   %this.zodiacName = %zodiac.name;
+   %zodiac.name = "";
+
+   // Add to unlisted.
+   PE_ZodiacEditor.unlistedSet.add( %zodiac );
+   
+   // Remove from file.
+   if(    %zodiac.getFileName() !$= ""
+       && %zodiac.getFilename() !$= "tools/particleEditor/scripts/afxZodiacEditor.ed." @ $TorqueScriptFileExtension )
+      PE_ZodiacEditor.saver.removeObjectFromFile( %zodiac );
+      
+   // Select DefaultZodiac or first in list.
+   
+   %popup = PE_ZodiacEditor-->PopUpMenu.text = "";
+
+   PE_ZodiacEditor-->inspector.inspect();
+
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteZodiac::undo( %this )
+{
+   %zodiac = %this.zodiac;
+      
+   // Re-assign name.
+   %zodiac.name = %this.zodiacName;
+
+   // Remove from unlisted.
+   
+   PE_ZodiacEditor.unlistedSet.remove( %zodiac );
+   
+   // Resave to file.
+   
+   if(    %zodiac.getFilename() !$= ""
+       && %zodiac.getFilename() !$= "tools/particleEditor/scripts/afxZodiacEditor.ed." @ $TorqueScriptFileExtension )
+   {
+      PE_ZodiacEditor.saver.setDirty( %zodiac, %zodiac.getFilename() );
+      PE_ZodiacEditor.saver.saveDirty();
+   }
+
+   // Add it to the dropdown and selet it.
+   PE_ZodiacEditor.selectedObject(%zodiac);
+   
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveZodiac.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveZodiac::redo( %this )
+{
+   %zodiac = %this.zodiac;
+   %zodiac.setFieldValue( %this.field, %this.newValue );
+   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveZodiac::undo( %this )
+{
+   %zodiac = %this.zodiac;
+   %zodiac.setFieldValue( %this.field, %this.oldValue );
+   
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionCreateNewRibbon.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewRibbon::redo( %this )
+{
+   %ribbon = %this.ribbon;
+   
+   // Assign name.
+   %ribbon.name = %this.ribbonName;
+   
+   // Remove from unlisted.
+   PE_RibbonParticleEditor.unlistedSet.remove( %ribbon );
+   
+   // Drop it in the dropdown and select it.
+   PE_RibbonParticleEditor.selectObject(%ribbon);
+   
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewRibbon::undo( %this )
+{
+   %ribbon = %this.ribbon;
+      
+   // Prevent a save dialog coming up on the emitter.
+   if( %ribbon == PE_RibbonParticleEditor.currRibbon )
+      PE_RibbonParticleEditor.setNotDirty();
+   
+   // Add to unlisted.
+   PE_RibbonParticleEditor.unlistedSet.add( %ribbon );
+   
+   // Remove it from in the dropdown and select prev emitter.
+   %popup = PE_RibbonParticleEditor-->popupMenu;
+      
+   if( isObject( %this.prevRibbon ) )
+   {
+      PE_RibbonParticleEditor.selectedObject(%this.prevRibbon);
+   }
+   else
+   {
+      PE_RibbonParticleEditor-->popupMenu.text = "";
+      PE_RibbonParticleEditor-->inspector.inspect();
+   }
+
+   // Unassign name.
+   %this.ribbonName = %ribbon.name;
+   %ribbon.name = "";
+
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionDeleteRibbon.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteRibbon::redo( %this )
+{
+   %ribbon = %this.ribbon;
+      
+   // Unassign name.
+   %this.ribbonName = %ribbon.name;
+   %ribbon.name = "";
+
+   // Add to unlisted.
+   PE_RibbonParticleEditor.unlistedSet.add( %ribbon );
+   
+   // Remove from file.
+   if(    %ribbon.getFileName() !$= ""
+       && %ribbon.getFilename() !$= "tools/particleEditor/scripts/particleRibbonEditor.ed." @ $TorqueScriptFileExtension )
+      PE_RibbonParticleEditor.saver.removeObjectFromFile( %ribbon );
+      
+   // Select DefaultRibbon or first in list.
+   
+   %popup = PE_RibbonParticleEditor-->PopUpMenu.text = "";
+
+   PE_RibbonParticleEditor-->inspector.inspect();
+
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteRibbon::undo( %this )
+{
+   %ribbon = %this.ribbon;
+      
+   // Re-assign name.
+   %ribbon.name = %this.ribbonName;
+
+   // Remove from unlisted.
+   
+   PE_RibbonParticleEditor.unlistedSet.remove( %ribbon );
+   
+   // Resave to file.
+   
+   if(    %ribbon.getFilename() !$= ""
+       && %ribbon.getFilename() !$= "tools/particleEditor/scripts/particleRibbonEditor.ed." @ $TorqueScriptFileExtension )
+   {
+      PE_RibbonParticleEditor.saver.setDirty( %ribbon, %ribbon.getFilename() );
+      PE_RibbonParticleEditor.saver.saveDirty();
+   }
+
+   // Add it to the dropdown and selet it.
+   PE_RibbonParticleEditor.selectedObject(%ribbon);
+   
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveRibbon.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveRibbon::redo( %this )
+{
+   %ribbon = %this.ribbon;
+   %ribbon.setFieldValue( %this.field, %this.newValue );
+   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveRibbon::undo( %this )
+{
+   %ribbon = %this.ribbon;
+   %ribbon.setFieldValue( %this.field, %this.oldValue );
+   
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionCreateNewChoreography.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewChoreography::redo( %this )
+{
+   %choreography = %this.choreography;
+   
+   // Assign name.
+   %choreography.name = %this.choreographyName;
+   
+   // Remove from unlisted.
+   PE_AFXChoreoEditor.unlistedSet.remove( %choreography );
+   
+   // Drop it in the dropdown and select it.
+   PE_AFXChoreoEditor.selectObject(%choreography);
+   
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionCreateNewChoreography::undo( %this )
+{
+   %choreography = %this.choreography;
+      
+   // Prevent a save dialog coming up on the emitter.
+   if( %choreography == PE_AFXChoreoEditor.currChoreography )
+      PE_AFXChoreoEditor.setNotDirty();
+   
+   // Add to unlisted.
+   PE_AFXChoreoEditor.unlistedSet.add( %choreography );
+   
+   // Remove it from in the dropdown and select prev emitter.
+   %popup = PE_AFXChoreoEditor-->popupMenu;
+      
+   if( isObject( %this.prevChoreography ) )
+   {
+      PE_AFXChoreoEditor.selectedObject(%this.prevChoreography);
+   }
+   else
+   {
+      PE_AFXChoreoEditor-->popupMenu.text = "";
+      PE_AFXChoreoEditor-->inspector.inspect();
+   }
+
+   // Unassign name.
+   %this.choreographyName = %choreography.name;
+   %choreography.name = "";
+
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionDeleteChoreography.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteChoreography::redo( %this )
+{
+   %choreography = %this.choreography;
+      
+   // Unassign name.
+   %this.choreographyName = %choreography.name;
+   %choreography.name = "";
+
+   // Add to unlisted.
+   PE_AFXChoreoEditor.unlistedSet.add( %choreography );
+   
+   // Remove from file.
+   if(    %choreography.getFileName() !$= ""
+       && %choreography.getFilename() !$= "tools/particleEditor/scripts/afxChoreoEditor.ed." @ $TorqueScriptFileExtension )
+      PE_AFXChoreoEditor.saver.removeObjectFromFile( %choreography );
+      
+   // Select DefaultChoreography or first in list.
+   
+   %popup = PE_AFXChoreoEditor-->PopUpMenu.text = "";
+
+   PE_AFXChoreoEditor-->inspector.inspect();
+
+   // Sync up.
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionDeleteChoreography::undo( %this )
+{
+   %choreography = %this.choreography;
+      
+   // Re-assign name.
+   %choreography.name = %this.choreographyName;
+
+   // Remove from unlisted.
+   
+   PE_AFXChoreoEditor.unlistedSet.remove( %choreography );
+   
+   // Resave to file.
+   
+   if(    %choreography.getFilename() !$= ""
+       && %choreography.getFilename() !$= "tools/particleEditor/scripts/afxChoreoEditor.ed." @ $TorqueScriptFileExtension )
+   {
+      PE_AFXChoreoEditor.saver.setDirty( %choreography, %choreography.getFilename() );
+      PE_AFXChoreoEditor.saver.saveDirty();
+   }
+
+   // Add it to the dropdown and selet it.
+   PE_AFXChoreoEditor.selectedObject(%choreography);
+   
+   // Sync up.
+   Parent::undo( %this );
+}
+
+//=============================================================================================
+//    ActionUpdateActiveChoreography.
+//=============================================================================================
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveChoreography::redo( %this )
+{
+   %choreography = %this.choreography;
+   %choreography.setFieldValue( %this.field, %this.newValue );
+   
+   Parent::redo( %this );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function ActionUpdateActiveChoreography::undo( %this )
+{
+   %choreography = %this.choreography;
+   %choreography.setFieldValue( %this.field, %this.oldValue );
+   
+   Parent::undo( %this );
+}

+ 605 - 0
Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript

@@ -0,0 +1,605 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+$PE_EMITTEREDITOR_DEFAULT_FILENAME = "data/managedParticleEmitterData." @ $TorqueScriptFileExtension;
+
+
+//=============================================================================================
+//    PE_EmitterEditor.
+//=============================================================================================
+function PE_EmitterEditor::init(%this)
+{
+   datablock ParticleEmitterData(PE_EmitterEditor_NotDirtyEmitter)
+   {
+      particles = "DefaultParticle";
+   };
+   
+   %this.unlistedSet.add(PE_EmitterEditor_NotDirtyEmitter);
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_EmitterEditor::openEditorTab(%this)
+{
+   PE_Window.text = ":: Particle Editor - Emitters";
+   %this.guiSync();
+   ParticleEditor.activeEditor = %this;
+
+   if( !%this.dirty )
+      %this.setNotDirty();
+}
+
+function PE_EmitterEditor::closeEditorTab(%this)
+{
+   if( isObject( $ParticleEditor::emitterNode) )
+      $ParticleEditor::emitterNode.delete();
+}
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::guiSync( %this )
+{
+   %this-->inspector.refresh();
+}
+
+function PE_EmitterEditor::resetVizNode(%this, %tform)
+{
+   if( !isObject( $ParticleEditor::emitterNode ) )
+   {
+      if( !isObject( TestEmitterNodeData ) )
+      {
+         datablock ParticleEmitterNodeData( TestEmitterNodeData )
+         {
+            timeMultiple = 1;
+         };
+      }
+
+      $ParticleEditor::emitterNode = new ParticleEmitterNode()
+      {
+         emitter = $ThisControl.currEmitter;
+         velocity = 1;
+         position = getWords( %tform, 0, 2 );
+         rotation = getWords( %tform, 3, 6 );
+         datablock = TestEmitterNodeData;
+         parentGroup = MissionCleanup;
+      };
+   }
+   else
+   {
+      $ParticleEditor::emitterNode.setTransform( %tform );
+      
+      %clientObject = $ParticleEditor::emitterNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.setTransform( %tform );
+      
+      %this.updateVizNode();
+   }
+   if (EWorldEditor.getSelectionSize()>0)
+   {
+        %obj = EWorldEditor.getSelectedObject(0);
+        if (%obj.isMemberOfClass("ParticleEmitterNode"))
+            $ParticleEditor::emitterNode.sethidden(true);
+   }  
+}
+
+function PE_EmitterEditor::updateVizNode(%this)
+{
+   if( isObject( $ParticleEditor::emitterNode ) )
+   {
+      %id = %this-->PopupMenu.getText();
+      
+      %clientObject = $ParticleEditor::emitterNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.setEmitterDataBlock( %id );
+   }
+   else
+      %this.resetVizNode();  
+}
+
+//------------------------------------------------------------------------------
+
+function PE_EmitterEditor::selectObject(%this, %obj)
+{
+   if( isObject(%obj )
+       && %obj.getName() $= %this-->popupMenu.text )
+      return;
+      
+   //FIXME: disregards particle tab dirty state
+   if( %this.dirty )
+   {   
+      if( PE_ParticleEditor.dirty )
+      {         
+         toolsMessageBoxYesNo("Save Existing Emitter?", 
+            "Do you want to save changes to <br><br>" @ %this.currParticle.getName(), 
+            "PE_ParticleEditor.saveParticle(" @ %this.currParticle @ ");"
+         );
+      }
+            
+      %savedEmitter = %this.currEmitter;
+      toolsMessageBoxYesNoCancel("Save Existing Emitter?", 
+         "Do you want to save changes to <br><br>" @ %savedEmitter.getName(), 
+         "PE_EmitterEditor.saveEmitter(" @ %savedEmitter@ "); PE_EmitterEditor.loadNewEmitter(" @ %obj @ ");", 
+         "PE_EmitterEditor.saveEmitterDialogDontSave(" @ %savedEmitter @ "); PE_EmitterEditor.loadNewEmitter(" @ %obj @ ");"
+      );
+   }
+   else
+   {
+      %this.loadNewEmitter(%obj);
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::loadNewEmitter( %this, %emitter )
+{
+   %this-->popupMenu.setText(%emitter.getName());
+   %this-->inspector.inspect(%emitter);
+   
+   if( isObject( %emitter ) )
+      %current = %emitter.getId();
+   else
+      %current = %this-->popupMenu.text;
+   
+   %this.currEmitter = %current;
+   PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %current );
+   PE_EmitterEditor_NotDirtyEmitter.originalName = %current.name;
+   
+   %this.guiSync();
+   %this.setNotDirty();
+      
+   //PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) );
+
+   %this.guiSync();
+   
+   ParticleEditor.updateEmitterNode();
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_EmitterEditor::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Update Active Emitter");
+   %action.emitter = %object;
+   %action.field = %fieldName;
+   %action.isSlider = false;
+   %action.onMouseUp = true;
+   %action.newValue = %newValue;
+   %action.oldValue = %oldValue;
+   
+   ParticleEditor.submitUndo( %action );
+}
+
+// Generic updateEmitter method
+function PE_EmitterEditor::updateEmitter( %this, %propertyField, %value, %isSlider, %onMouseUp )
+{
+   PE_EmitterEditor.setDirty();
+         
+   %emitter = %this.currEmitter;
+      
+   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
+   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
+   {
+      %last.field = %propertyField;
+      %last.isSlider = %isSlider;
+      %last.onMouseUp = %onMouseUp;
+      %last.newValue = %value;
+   }
+   else
+   {
+      %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Update Active Emitter");
+      %action.emitter = %emitter;
+      %action.field = %propertyField;
+      %action.isSlider = %isSlider;
+      %action.onMouseUp = %onMouseUp;
+      %action.newValue = %value;
+      %action.oldValue = %emitter.getFieldValue( %propertyField );
+      
+      ParticleEditor.submitUndo( %action );
+   }
+   	
+	%emitter.setFieldValue( %propertyField, %value );
+	%emitter.reload();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::updateParticlesFields( %this )
+{
+   %particles = "";
+   for( %i = 1; %i < 5; %i ++ )
+   {
+      %emitterParticle = "PEE_EmitterParticle" @ %i;
+      %popup = %emitterParticle-->PopUpMenu;
+      %text = %popup.getText();
+      
+      if( %text $= "" || %text $= "None" )
+         continue;
+         
+      if( %particles $= "" )
+         %particles = %text;
+      else
+         %particles = %particles SPC %text;
+   }
+   
+   %changedEditParticle = 1;
+   %currParticle = PE_ParticleEditor.currParticle.getName();
+
+   foreach$( %particleName in %particles )
+   {
+      if( %particleName $= %currParticle )
+      {
+         %changedEditParticle = 0; 
+         break;
+      }
+   }
+   
+   // True only if the currently edited particle has not been found and the 
+   // ParticleEditor is dirty.
+   
+   if( %changedEditParticle && PE_ParticleEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save Particle Changes?", 
+         "Do you wish to save the changes made to the <br>current particle before changing the particle?", 
+         "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", 
+         "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", 
+         "PE_EmitterEditor.guiSync();" );
+   }
+   else
+   {
+      PE_EmitterEditor.updateEmitter( "particles", %particles );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::setDirty( %this )
+{
+   %this.text = "*Emitter";
+   %this.dirty = true;
+   
+   if(!startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = "*" @ %this-->PopupMenu.text;
+   }
+   
+   %emitter = %this.currEmitter;
+   %filename = %emitter.getFilename();
+   %editorFilename = "tools/particleEditor/scripts/particleEmitterEditor.ed." @ $TorqueScriptFileExtension;
+   
+   if( %filename $= "" || %filename $= %editorFilename )
+      %this.saver.setDirty( %emitter, $PE_EMITTEREDITOR_DEFAULT_FILENAME );
+   else
+      %this.saver.setDirty( %emitter );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::setNotDirty( %this )
+{   
+   PE_EmitterEditor.text = "Emitter";
+   PE_EmitterEditor.dirty = false;
+   
+   if(startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = stripChars(%this-->PopupMenu.text, "*");
+   }
+   
+   %this.saver.clearAll();
+}
+
+//---------------------------------------------------------------------------------------------
+
+// Create Functionality
+function PE_EmitterEditor::showNewDialog( %this )
+{
+   // Open a dialog if the current emitter is dirty.
+   if( PE_ParticleEditor.dirty )
+   {         
+      toolsMessageBoxYesNo("Save Existing Particle?", 
+         "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), 
+         "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");"
+      );
+   }   
+   
+   if( PE_EmitterEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save Emitter Changes?", 
+         "Do you wish to save the changes made to the <br>current emitter before changing the emitter?", 
+         "PE_EmitterEditor.saveEmitter( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();", 
+         "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();"
+      );
+   }
+   else
+   {
+      PE_EmitterEditor.createEmitter();
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::createEmitter( %this )
+{
+   AssetBrowser_SelectModule.showDialog("PE_EmitterEditor.pickedNewEmitterTargetModule");
+   AssetBrowser_SelectModuleWindow.selectWindow();
+}
+
+function PE_EmitterEditor::pickedNewEmitterTargetModule( %this, %module )
+{
+   ParticleEditorCreatePrompt.show("Emitter", "ParticleEmitterData", "PE_EMitterEditor.doCreateNewEmitter(\"" @ %module @ "\");" );
+}
+
+function PE_EmitterEditor::doCreateNewEmitter( %this, %module )
+{
+   //Sanity checks
+   %newName = ParticleEditorCreatePrompt-->nameText.getText();
+   if(%newName $= "")
+   {
+      toolsMessageBoxOK("Error", "New Emitter requires a name!");
+      return;
+   }
+   
+   Canvas.popDialog(ParticleEditorCreatePrompt);
+   
+   %sourceDB = ParticleEditorCreatePrompt-->CopySourceDropdown.getText();
+   
+   if(%sourceDB $= "")
+      %sourceDB = DefaultEmitter;
+   
+   %moduleDef = ModuleDatabase.findModule(%module);
+   PE_EmitterEditor.targetModule = %module;
+   $PE_EMITTEREDITOR_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedParticleEmitterData." @ $TorqueScriptFileExtension;
+   
+   if(!isDirectory(filePath($PE_EMITTEREDITOR_DEFAULT_FILENAME)))
+   {
+      AssetBrowser.dirHandler.createFolder(filePath($PE_EMITTEREDITOR_DEFAULT_FILENAME));
+   }
+   
+   // Create a new emitter.
+   %emitter = getUniqueName( %newName );
+   eval("datablock ParticleEmitterData( " @ %emitter @ " : " @ %sourceDB @ " ){};");
+   
+   // Submit undo.
+   
+   %action = ParticleEditor.createUndo( ActionCreateNewEmitter, "Create New Emitter" );
+   %action.prevEmitter = PE_EmitterEditor.currEmitter;
+   %action.emitter = %emitter.getId();
+   %action.emitterName = %emitter;
+
+   ParticleEditor.submitUndo( %action );
+
+   // Execute action.
+   %action.redo();
+   
+   %this.saver.setDirty(%emitter, $PE_EMITTEREDITOR_DEFAULT_FILENAME);
+   
+   %this.loadNewEmitter(%emitter);
+   %this.setDirty();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::showDeleteDialog( %this )
+{
+   if( PE_EmitterEditor.currEmitter.getName() $= "DefaultEmitter" )
+   {
+      toolsMessageBoxOK( "Error", "Cannot delete DefaultEmitter");
+      return;
+   }
+   
+   if( isObject( PE_EmitterEditor.currEmitter ) )
+   {
+      toolsMessageBoxYesNoCancel("Delete Emitter?", 
+         "Are you sure you want to delete<br><br>" @ PE_EmitterEditor.currEmitter.getName() @ "<br><br> Emitter deletion won't take affect until the level is exited.", 
+         "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.deleteEmitter();"
+      );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::deleteEmitter( %this )
+{  
+   %emitter = PE_EmitterEditor.currEmitter;
+   
+   // Create undo.
+   
+   %action = ParticleEditor.createUndo( ActionDeleteEmitter, "Delete Emitter" );
+   %action.emitter = %emitter;
+   %action.emitterFname = %emitter.getFilename();
+
+   ParticleEditor.submitUndo( %action );
+   
+   // Execute action.
+
+   %action.redo();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::saveEmitter( %this, %emitter )
+{   
+   if ( %emitter $= "" )
+   {
+      %emitter = %this.currEmitter;
+      %newName = %this.currEmitter.getName();
+   }
+   else
+   {
+      %newName = %emitter.getName();
+   }
+   
+   %this.currEmitter.setName( %newName );
+   PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %emitter );
+   PE_EmitterEditor_NotDirtyEmitter.originalName = %newName;
+   
+   %this.saver.saveDirty(); 
+   
+   %this.loadNewEmitter(%newName.getId());
+
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_EmitterEditor::saveEmitterDialogDontSave( %this, %emitter)
+{  
+   %emitter.setName( PE_EmitterEditor_NotDirtyEmitter.originalName );
+   %emitter.assignFieldsFrom( PE_EmitterEditor_NotDirtyEmitter );
+   PE_EmitterEditor.setNotDirty();
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+function ParticleEditor::addParticleSlot(%this, %field, %emitterObj)
+{
+   if(getWordCount(%emitterObj.particles) >= 4)
+   {
+      toolsMessageBoxOK("Error", "Cannot add more than 4 particle slots to this emitter.");
+      return;  
+   }
+   
+   %updatedParticlesList = %emitterObj.particles SPC "DefaultParticle";
+   
+   %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Add new Emitter Particle Slot");
+   %action.emitter = %emitterObj;
+   %action.field = "particles";
+   %action.newValue = %updatedParticlesList;
+   %action.oldValue = %emitterObj.particles;
+   
+   ParticleEditor.submitUndo( %action );
+}
+
+function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx)
+{
+   %groupIdx = PE_ParticleDataTypes.getIndexFromKey("Particle");
+   %typesList = getField(PE_ParticleDataTypes.getValue(%groupIdx), 0);
+   %editorName = getField(PE_ParticleDataTypes.getValue(%groupIdx), 1);
+
+   %listSet = new SimSet(){ internalName = "Particles[" @ %slotIdx @ "]"; };
+   
+   foreach( %obj in DatablockGroup )
+   {
+      echo(%typesList);
+      %typesListCount = getWordCount(%typesList);
+      for(%i=0; %i < %typesListCount; %i++)
+      {
+         %type = getWord(%typesList, %i);
+         
+         if( %obj.isMemberOfClass( %type ) )
+         {
+            // Filter out emitters on the PE_ParticleEditor.unlistedSet list.
+            
+            %unlistedFound = false;
+            foreach( %unlisted in PE_ParticleEditor.unlistedSet ){
+               if( %unlisted.getId() == %obj.getId() )
+               {
+                  %unlistedFound = true;
+                  break;
+               }
+            }
+         
+            if( %unlistedFound )
+               continue;
+               
+            // To prevent our default emitters from getting changed,
+            // prevent them from populating the list. Default emitters
+            // should only be used as a template for creating new ones.
+            if ( %obj.getName() $= "DefaultParticle")
+               continue;
+               
+            if(%slotIdx > 0)
+            {
+               //Confirm our options to the particle in slot 0's image to maintain batching
+               %slot0ParticleDB = getWord(%emitterObj.particles, 0);
+               %textureAsset = %slot0ParticleDB.textureAsset;
+               if(%textureAsset !$= %obj.textureAsset)
+                  continue;
+            }
+               
+            if(%typesListCount > 1)
+            {
+               %typeSet = %listSet.findObjectByInternalName(%type);
+               if(!isObject(%typeSet))
+               {
+                  %typeSet = new SimSet(){ internalName = %type; };
+                  %listSet.add(%typeSet);
+               }
+               
+               %typeSet.add(%obj);
+            }
+            else
+            {
+               %listSet.add(%obj);
+            }
+            %listCount++;
+         }
+      }
+   }
+   
+   ContextedDropdownListGui.show(%listSet, "Edit Particle Slot[" @ %slotIdx @ "]", "ParticleEditor.editSlot = " @ %slotIdx @ ";ParticleEditor.updateParticleSlot", %field);
+   %particleData = getWord(%emitterObj.particles, %slotIdx);
+   if(%particleData !$= "")
+   {
+      ContextedDropdownListGui.seekItemObject(%particleData.getId());
+   }
+}
+
+function ParticleEditor::updateParticleSlot(%this, %newParticle)
+{
+   if(ParticleEditor.editSlot $= "")
+      return;
+      
+   %updatedParticlesList = setWord(PE_EmitterEditor.currEmitter.particles, ParticleEditor.editSlot, %newParticle);
+   
+   %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Edit Active Emitter Particle Slot");
+   %action.emitter = PE_EmitterEditor.currEmitter;
+   %action.field = "particles";
+   %action.newValue = %updatedParticlesList;
+   %action.oldValue = PE_EmitterEditor.currEmitter.particles;
+   
+   ParticleEditor.submitUndo( %action );
+   
+   ParticleEditor.editSlot = "";
+   
+   //%field.apply(%updatedParticlesList, %slotIdx);
+   //%this-->inspector.refresh();
+}
+
+function ParticleEditor::editParticleSlot(%this, %field, %emitterObj, %slotIdx)
+{
+   %particleName = getWord(%emitterObj.particles, %slotIdx);
+   
+   ParticleEditor.open(%particleName);
+}
+
+function ParticleEditor::clearParticleSlot(%this, %field, %emitterObj, %slotIdx)
+{
+   %updatedParticlesList = removeWord(%emitterObj.particles, %slotIdx);
+   
+   %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Clear Active Emitter Particle Slot");
+   %action.emitter = %emitterObj;
+   %action.field = "particles";
+   %action.newValue = %updatedParticlesList;
+   %action.oldValue = %emitterObj.particles;
+   
+   ParticleEditor.submitUndo( %action );
+   
+   //%field.apply(%updatedParticlesList, %slotIdx);
+   //%this-->inspector.refresh();
+}

+ 396 - 0
Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript

@@ -0,0 +1,396 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+$PE_PARTICLEEDITOR_DEFAULT_FILENAME = "data/managedParticleData." @ $TorqueScriptFileExtension;
+
+
+//=============================================================================================
+//    PE_ParticleEditor.
+//=============================================================================================
+function PE_ParticleEditor::init(%this)
+{
+   datablock ParticleData(PE_ParticleEditor_NotDirtyParticle)
+   {
+      textureName = "art/particles/defaultParticle";
+   };  
+   
+   %this.unlistedSet.add(PE_ParticleEditor_NotDirtyParticle);
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_ParticleEditor::openEditorTab(%this)
+{
+   PE_Window.text = ":: Particle Editor - Particles";
+   %this.guiSync();
+   ParticleEditor.activeEditor = %this;
+   
+   if( !%this.dirty )
+      %this.setNotDirty();
+}
+
+function PE_ParticleEditor::closeEditorTab(%this)
+{
+   if( isObject( $ParticleEditor::emitterNode) )
+      $ParticleEditor::emitterNode.delete();
+}
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::guiSync( %this )
+{
+   %this-->inspector.refresh();
+}
+
+function PE_ParticleEditor::resetVizNode(%this, %tform)
+{
+   PE_EmitterEditor.resetVizNode(%tform);
+}
+
+function PE_ParticleEditor::updateVizNode(%this)
+{
+   PE_EmitterEditor.updateVizNode();  
+}
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::selectObject(%this, %obj)
+{
+   // Bail if the user selected the same particle.
+   if( %obj == %this.currParticle )
+      return;
+   
+   // Load new particle if we're not in a dirty state
+   if( %this.dirty )
+   {         
+      toolsMessageBoxYesNoCancel("Save Existing Particle?", 
+         "Do you want to save changes to <br><br>" @ %this.currParticle.getName(), 
+         "PE_ParticleEditor.saveParticle(" @ %this.currParticle @ ");", 
+         "PE_ParticleEditor.saveParticleDialogDontSave(" @ %this.currParticle @ "); PE_ParticleEditor.loadNewParticle(" @ %obj @ ");"
+      );
+   }
+   else
+   {
+      %this.loadNewParticle(%obj);
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::loadNewParticle( %this, %particle )
+{
+   %this-->popupMenu.setText(%particle.getName());
+   %this-->inspector.inspect(%particle);  
+   
+   if( isObject( %particle ) )
+      %current = %particle.getId();
+   else
+      %current = %this-->popupMenu.text;
+      
+   %this.currParticle = %current; 
+   
+   error("PE_ParticleEditor::loadNewParticle() - Loading particle: " @ %current.getName());
+   error("Particle TextureName: " @ %current.getTexture());
+   
+   error("ReloadingParticle...");
+   %current.reload();
+   
+   PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %current );
+   PE_ParticleEditor_NotDirtyParticle.originalName = %current.getName();
+
+   error("Post duplicate Particle TextureName: " @ %current.getTexture());
+   error("Post duplicate PE_ParticleEditor_NotDirtyParticle TextureName: " @ PE_ParticleEditor_NotDirtyParticle.getTexture());
+
+   %this.guiSync();
+   %this.setNotDirty();
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_ParticleEditor::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   %action = ParticleEditor.createUndo(ActionUpdateActiveParticler, "Update Active Particle");
+   %action.particle = %object;
+   %action.field = %fieldName;
+   %action.isSlider = false;
+   %action.onMouseUp = true;
+   %action.newValue = %newValue;
+   %action.oldValue = %oldValue;
+   
+   ParticleEditor.submitUndo( %action );
+
+   %object.reload();
+}
+
+// Generic updateParticle method
+function PE_ParticleEditor::updateParticle(%this, %propertyField, %value, %isSlider, %onMouseUp)
+{
+   PE_ParticleEditor.setDirty();
+   %particle = PE_ParticleEditor.currParticle;
+      
+   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
+   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
+   {
+      %last.field = %propertyField;
+      %last.isSlider = %isSlider;
+      %last.onMouseUp = %onMouseUp;
+      %last.newValue = %value;
+   }
+   else
+   {
+      %action = ParticleEditor.createUndo(ActionUpdateActiveParticle, "Update Active Particle");
+      %action.particle = %particle;
+      %action.field = %propertyField;
+      %action.isSlider = %isSlider;
+      %action.onMouseUp = %onMouseUp;
+      %action.newValue = %value;
+      %action.oldValue = %particle.getFieldValue( %propertyField );
+      
+      ParticleEditor.submitUndo( %action );
+   }
+   
+   %particle.setFieldValue( %propertyField, %value );
+   %particle.reload();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::setDirty( %this )
+{
+   this.text = "*Particle";
+   this.dirty = true;
+
+   if(!startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = "*" @ %this-->PopupMenu.text;
+   }
+   
+   %particle = this.currParticle;
+   %filename = %particle.getFilename();
+   %editorFilename = "tools/particleEditor/scripts/particleParticleEditor.ed." @ $TorqueScriptFileExtension;
+   
+   if( %filename $= "" || %filename $= %editorFilename )
+      %this.saver.setDirty( %particle, $PE_PARTICLEEDITOR_DEFAULT_FILENAME );
+   else
+      %this.saver.setDirty( %particle );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::setNotDirty( %this )
+{
+   PE_ParticleEditor.text = "Particle";
+   PE_ParticleEditor.dirty = false;
+
+   if(startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = stripChars(%this-->PopupMenu.text, "*");
+   }
+   
+   %this.saver.clearAll();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::showNewDialog( %this, %replaceSlot )
+{
+   // Open a dialog if the current Particle is dirty
+   if( this.dirty ) 
+   {
+      toolsMessageBoxYesNoCancel("Save Particle Changes?", 
+         "Do you wish to save the changes made to the <br>current particle before changing the particle?", 
+         "PE_ParticleEditor.saveParticle( " @ this.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );", 
+         "PE_ParticleEditor.saveParticleDialogDontSave( " @ this.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );"
+      );
+   }
+   else
+   {
+      this.createParticle( %replaceSlot );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::createParticle( %this, %replaceSlot )
+{
+   // Make sure we have a spare slot on the current emitter.
+   
+   if( !%replaceSlot )
+   {
+      %numExistingParticles = getWordCount( PE_EmitterEditor.currEmitter.particles );
+      if( %numExistingParticles > 3 )
+      {
+         toolsMessageBoxOK( "Error", "An emitter cannot have more than 4 particles assigned to it." );
+         return;
+      }
+      
+      %particleIndex = %numExistingParticles;
+   }
+   else
+      %particleIndex = %replaceSlot - 1;
+   
+   %this.newParticleSlot = %particleIndex;
+   
+   if(%replaceSlot $= "" || %replaceSlot != 0)
+   {
+      AssetBrowser_SelectModule.showDialog("PE_ParticleEditor.pickedNewParticleTargetModule");
+      AssetBrowser_SelectModuleWindow.selectWindow();
+   }
+   else
+   {
+      %this.pickedNewParticleTargetModule(PE_EmitterEditor.targetModule);
+   }
+}
+
+function PE_ParticleEditor::pickedNewParticleTargetModule( %this, %module )
+{
+   ParticleEditorCreatePrompt.show("Particle", "ParticleData", "PE_ParticleEditor.doCreateNewParticle(\"" @ %module @ "\");" );
+}
+
+function PE_ParticleEditor::doCreateNewEmitter(%this, %module)
+{
+   //Sanity checks
+   %newName = ParticleEditorCreatePrompt-->nameText.getText();
+   if(%newName $= "")
+   {
+      toolsMessageBoxOK("Error", "New Particle requires a name!");
+      return;
+   }
+   
+   Canvas.popDialog(ParticleEditorCreatePrompt);
+   
+   %sourceDB = ParticleEditorCreatePrompt-->CopySourceDropdown.getText();
+   
+   if(%sourceDB $= "")
+      %sourceDB = DefaultParticle;
+
+   %moduleDef = ModuleDatabase.findModule(%module);
+   $PE_PARTICLEEDITOR_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedParticleData." @ $TorqueScriptFileExtension;
+   
+   if(!isDirectory(filePath($PE_PARTICLEEDITOR_DEFAULT_FILENAME)))
+   {
+      AssetBrowser.dirHandler.createFolder(filePath($PE_PARTICLEEDITOR_DEFAULT_FILENAME));
+   }
+   
+   // Create the particle datablock and add to the emitter.
+   %particle = getUniqueName( %newName );
+   eval("datablock ParticleData( " @ %particle @ " : " @ %sourceDB @ " ){};");
+   
+   // Submit undo.
+   %action = ParticleEditor.createUndo( ActionCreateNewParticle, "Create New Particle" );
+   %action.particle = %particle.getId();
+   %action.particleIndex = %this.newParticleSlot;
+   %action.prevParticle = ( "PEE_EmitterParticleSelector" @ ( PE_ParticleEditor.newParticleSlot + 1 ) ).getSelected();
+   %action.emitter = PE_EmitterEditor.currEmitter;
+   
+   ParticleEditor.submitUndo( %action );
+   
+   // Execute action.
+   %action.redo();
+
+   %this.saver.setDirty(%particle, $PE_PARTICLEEDITOR_DEFAULT_FILENAME);
+   
+   %this.loadNewParticle(%particle);
+   %this.setDirty();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::showDeleteDialog( %this )
+{
+   // Don't allow deleting DefaultParticle.
+   
+   if( PE_ParticleEditor.currParticle.getName() $= "DefaultParticle" )
+   {
+      toolsMessageBoxOK( "Error", "Cannot delete DefaultParticle");
+      return;
+   }
+   
+   // Check to see if the particle emitter has more than 1 particle on it.
+   
+   if( getWordCount( PE_EmitterEditor.currEmitter.particles ) == 1 )
+   {
+      toolsMessageBoxOK( "Error", "At least one particle must remain on the particle emitter.");
+      return;
+   }
+   
+   // Bring up requester for confirmation.
+   
+   if( isObject( PE_ParticleEditor.currParticle ) )
+   {
+      toolsMessageBoxYesNoCancel( "Delete Particle?", 
+         "Are you sure you want to delete<br><br>" @ %this.currParticle.getName() @ "<br><br> Particle deletion won't take affect until the engine is quit.", 
+         "PE_ParticleEditor.saveParticleDialogDontSave( " @ %this.currParticle.getName() @ " ); PE_ParticleEditor.deleteParticle();", 
+         "", 
+         ""
+      );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::deleteParticle( %this )
+{
+   %particle = %this.currParticle;
+   
+   // Submit undo.
+   
+   %action = ParticleEditor.createUndo( ActionDeleteParticle, "Delete Particle" );
+   %action.particle = %particle;
+   %action.emitter = PE_EmitterEditor.currEmitter;
+
+   ParticleEditor.submitUndo( %action );
+   
+   // Execute action.
+   
+   %action.redo();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::saveParticle( %this, %particle )
+{
+   if ( %particle $= "" )
+   {
+      %particle = %this.currParticle;
+      %newName = %this.currParticle.getName();
+   }
+   else
+   {
+      %newName = %particle.getName();
+   }
+   
+   %this.currParticle.setName( %newName );
+   PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %particle );
+   PE_ParticleEditor_NotDirtyParticle.originalName = %newName;
+   
+   %this.saver.saveDirty(); 
+   
+   %this.loadNewParticle(%newName.getId()); 
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_ParticleEditor::saveParticleDialogDontSave( %this, %particle )
+{
+   %particle.setName( PE_ParticleEditor_NotDirtyParticle.originalName );
+   %particle.assignFieldsFrom( PE_ParticleEditor_NotDirtyParticle );
+   
+   %this.setNotDirty();
+}

+ 469 - 0
Templates/BaseGame/game/tools/particleEditor/scripts/particleRibbonEditor.ed.tscript

@@ -0,0 +1,469 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+$PE_RibbonParticleEditor_DEFAULT_FILENAME = "data/managedParticleData." @ $TorqueScriptFileExtension;
+
+
+//=============================================================================================
+//    PE_RibbonParticleEditor.
+//=============================================================================================
+function PE_RibbonParticleEditor::init(%this)
+{
+   datablock RibbonData(PE_RibbonParticleEditor_NotDirtyEmitter)
+   {
+   };
+   
+   %this.unlistedSet.add(PE_RibbonParticleEditor_NotDirtyEmitter);
+}
+
+function PE_RibbonParticleEditor::openEditorTab(%this)
+{
+   PE_Window.text = ":: Particle Editor - Ribbons";
+   %this.guiSync();
+   ParticleEditor.activeEditor = %this;
+
+   if( !%this.dirty )
+      %this.setNotDirty();
+     
+   if( isObject( $ParticleEditor::ribbonNode ) )
+      $ParticleEditor::ribbonNode.setHidden(false);
+}
+
+function PE_RibbonParticleEditor::closeEditorTab(%this)
+{
+   if( isObject( $ParticleEditor::ribbonNode) )
+      $ParticleEditor::ribbonNode.delete();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::guiSync( %this )
+{
+   %this-->inspector.refresh();
+}
+
+function PE_RibbonParticleEditor::resetVizNode(%this, %tform)
+{
+   if( !isObject( $ParticleEditor::ribbonNode ) )
+   {
+      if( !isObject( TestRibbonEmitterNodeData ) )
+      {
+         datablock RibbonNodeData( TestRibbonEmitterNodeData )
+         {
+            timeMultiple = 1;
+         };
+      }
+
+      $ParticleEditor::ribbonNode = new RibbonNode()
+      {
+         ribbon = $ThisControl.currRibbon;
+         position = getWords( %tform, 0, 2 );
+         rotation = getWords( %tform, 3, 6 );
+         datablock = TestRibbonEmitterNodeData;
+         parentGroup = MissionCleanup;
+      };
+   }
+   else
+   {
+      $ParticleEditor::ribbonNode.setTransform( %tform );
+      
+      %clientObject = $ParticleEditor::ribbonNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.setTransform( %tform );
+      
+      %this.updateVizNode();
+   }
+   if (EWorldEditor.getSelectionSize()>0)
+   {
+        %obj = EWorldEditor.getSelectedObject(0);
+        if (%obj.isMemberOfClass("RibbonNodeData"))
+            $ParticleEditor::ribbonNode.sethidden(true);
+   }  
+}
+
+function PE_RibbonParticleEditor::updateVizNode(%this)
+{
+   if( isObject( $ParticleEditor::ribbonNode ) )
+   {
+      %id = %this-->PopupMenu.getText();
+      
+      %clientObject = $ParticleEditor::ribbonNode.getClientObject();
+      if( isObject( %clientObject ) )
+         %clientObject.setRibbonDataBlock( %id );
+   }
+   else
+      %this.resetVizNode();   
+}
+
+//------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::selectObject(%this, %obj)
+{
+   if( isObject(%obj )
+       && %obj.getName() $= %this-->popupMenu.text )
+      return;
+      
+   //FIXME: disregards particle tab dirty state
+   if( %this.dirty )
+   {   
+      if( PE_ParticleEditor.dirty )
+      {         
+         toolsMessageBoxYesNo("Save Existing Ribbon?", 
+            "Do you want to save changes to <br><br>" @ %this.currParticle.getName(), 
+            "PE_ParticleEditor.saveParticle(" @ %this.currParticle @ ");"
+         );
+      }
+            
+      %savedRibbon = %this.currRibbon;
+      toolsMessageBoxYesNoCancel("Save Existing Ribbon?", 
+         "Do you want to save changes to <br><br>" @ %savedRibbon.getName(), 
+         "PE_RibbonParticleEditor.saveRibbon(" @ %savedRibbon@ "); PE_RibbonParticleEditor.loadNewRibbon(" @ %obj @ ");", 
+         "PE_RibbonParticleEditor.saveRibbonDialogDontSave(" @ %savedRibbon @ "); PE_RibbonParticleEditor.loadNewRibbon(" @ %obj @ ");"
+      );
+   }
+   else
+   {
+      %this.loadNewRibbon(%obj);
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::loadNewRibbon( %this, %ribbon )
+{
+   %this-->popupMenu.setText(%ribbon.getName());
+   %this-->inspector.inspect(%ribbon);
+   
+   if( isObject( %ribbon ) )
+      %current = %ribbon.getId();
+   else
+      %current = %this-->popupMenu.text;
+   
+   %this.currRibbon = %current;
+   PE_RibbonParticleEditor_NotDirtyRibbon.assignFieldsFrom( %current );
+   PE_RibbonParticleEditor_NotDirtyRibbon.originalName = %current.name;
+   
+   %this.guiSync();
+   %this.setNotDirty();
+      
+   //PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) );
+
+   %this.guiSync();
+   
+   PE_RibbonParticleEditor.updateVizNode();
+}
+
+//---------------------------------------------------------------------------------------------
+function PE_RibbonParticleEditor::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   %action = ParticleEditor.createUndo(ActionUpdateActiveRibbon, "Update Active Ribbon");
+   %action.ribbon = %object;
+   %action.field = %fieldName;
+   %action.isSlider = false;
+   %action.onMouseUp = true;
+   %action.newValue = %newValue;
+   %action.oldValue = %oldValue;
+   
+   ParticleEditor.submitUndo( %action );
+}
+
+// Generic updateRibbon method
+function PE_RibbonParticleEditor::updateRibbon( %this, %propertyField, %value, %isSlider, %onMouseUp )
+{
+   PE_RibbonParticleEditor.setDirty();
+         
+   %ribbon = %this.currRibbon;
+      
+   %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1);
+   if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) )
+   {
+      %last.field = %propertyField;
+      %last.isSlider = %isSlider;
+      %last.onMouseUp = %onMouseUp;
+      %last.newValue = %value;
+   }
+   else
+   {
+      %action = ParticleEditor.createUndo(ActionUpdateActiveRibbon, "Update Active Ribbon");
+      %action.ribbon = %ribbon;
+      %action.field = %propertyField;
+      %action.isSlider = %isSlider;
+      %action.onMouseUp = %onMouseUp;
+      %action.newValue = %value;
+      %action.oldValue = %ribbon.getFieldValue( %propertyField );
+      
+      ParticleEditor.submitUndo( %action );
+   }
+   	
+	%ribbon.setFieldValue( %propertyField, %value );
+	%ribbon.reload();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::updateParticlesFields( %this )
+{
+   %particles = "";
+   for( %i = 1; %i < 5; %i ++ )
+   {
+      %ribbonParticle = "PEE_RibbonParticle" @ %i;
+      %popup = %ribbonParticle-->PopUpMenu;
+      %text = %popup.getText();
+      
+      if( %text $= "" || %text $= "None" )
+         continue;
+         
+      if( %particles $= "" )
+         %particles = %text;
+      else
+         %particles = %particles SPC %text;
+   }
+   
+   %changedEditParticle = 1;
+   %currParticle = PE_ParticleEditor.currParticle.getName();
+
+   foreach$( %particleName in %particles )
+   {
+      if( %particleName $= %currParticle )
+      {
+         %changedEditParticle = 0; 
+         break;
+      }
+   }
+   
+   // True only if the currently edited particle has not been found and the 
+   // ParticleEditor is dirty.
+   
+   if( %changedEditParticle && PE_ParticleEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save Particle Changes?", 
+         "Do you wish to save the changes made to the <br>current particle before changing the particle?", 
+         "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_RibbonParticleEditor.updateRibbon( \"particles\"," @ %particles @ ");", 
+         "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_RibbonParticleEditor.updateRibbon( \"particles\"," @ %particles @ ");", 
+         "PE_RibbonParticleEditor.guiSync();" );
+   }
+   else
+   {
+      PE_RibbonParticleEditor.updateRibbon( "particles", %particles );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::setDirty( %this )
+{
+   %this.text = "*Ribbon";
+   %this.dirty = true;
+   
+   if(!startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = "*" @ %this-->PopupMenu.text;
+   }
+   
+   %ribbon = %this.currRibbon;
+   %filename = %ribbon.getFilename();
+   %editorFilename = "tools/particleEditor/scripts/particleRibbonEditor.ed." @ $TorqueScriptFileExtension;
+   
+   if( %filename $= "" || %filename $= %editorFilename )
+      %this.saver.setDirty( %ribbon, $PE_RibbonParticleEditor_DEFAULT_FILENAME );
+   else
+      %this.saver.setDirty( %ribbon );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::setNotDirty( %this )
+{   
+   PE_RibbonParticleEditor.text = "Ribbon";
+   PE_RibbonParticleEditor.dirty = false;
+   
+   if(startsWith(%this-->PopupMenu.text, "*"))
+   {
+      %this-->PopupMenu.text = stripChars(%this-->PopupMenu.text, "*");
+   }
+   
+   %this.saver.clearAll();
+}
+
+//---------------------------------------------------------------------------------------------
+
+// Create Functionality
+function PE_RibbonParticleEditor::showNewDialog( %this )
+{
+   //FIXME: disregards particle tab dirty state
+
+   // Open a dialog if the current ribbon is dirty.
+   
+   if( PE_ParticleEditor.dirty )
+   {         
+      toolsMessageBoxYesNo("Save Existing Ribbon?", 
+         "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), 
+         "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");"
+      );
+   }   
+   
+   if( PE_RibbonParticleEditor.dirty )
+   {
+      toolsMessageBoxYesNoCancel("Save Ribbon Changes?", 
+         "Do you wish to save the changes made to the <br>current ribbon before changing the ribbon?", 
+         "PE_RibbonParticleEditor.saveRibbon( " @ PE_RibbonParticleEditor.currRibbon.getName() @ " ); PE_RibbonParticleEditor.createRibbon();", 
+         "PE_RibbonParticleEditor.saveRibbonDialogDontSave( " @ PE_RibbonParticleEditor.currRibbon.getName() @ " ); PE_RibbonParticleEditor.createRibbon();"
+      );
+   }
+   else
+   {
+      PE_RibbonParticleEditor.createRibbon();
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::createRibbon( %this )
+{
+   AssetBrowser_SelectModule.showDialog("PE_RibbonParticleEditor.pickedNewRibbonTargetModule");
+   AssetBrowser_SelectModuleWindow.selectWindow();
+}
+
+function PE_RibbonParticleEditor::pickedNewRibbonTargetModule( %this, %module )
+{
+   ParticleEditorCreatePrompt.show("Ribbon", "RibbonData", "PE_RibbonParticleEditor.doCreateNewRibbon(\"" @ %module @ "\");" );
+}
+
+function PE_RibbonParticleEditor::doCreateNewRibbon( %this, %module )
+{
+   //Sanity checks
+   %newName = ParticleEditorCreatePrompt-->nameText.getText();
+   if(%newName $= "")
+   {
+      toolsMessageBoxOK("Error", "New Ribbon requires a name!");
+      return;
+   }
+   
+   Canvas.popDialog(ParticleEditorCreatePrompt);
+   
+   %sourceDB = ParticleEditorCreatePrompt-->CopySourceDropdown.getText();
+   
+   if(%sourceDB $= "")
+      %sourceDB = DefaultRibbon;
+   
+   %moduleDef = ModuleDatabase.findModule(%module);
+   PE_RibbonParticleEditor.targetModule = %module;
+   $PE_RibbonParticleEditor_DEFAULT_FILENAME = %moduleDef.ModulePath @ "/scripts/managedData/managedRibbonData." @ $TorqueScriptFileExtension;
+   
+   if(!isDirectory(filePath($PE_RibbonParticleEditor_DEFAULT_FILENAME)))
+   {
+      AssetBrowser.dirHandler.createFolder(filePath($PE_RibbonParticleEditor_DEFAULT_FILENAME));
+   }
+   
+   // Create a new ribbon.
+   %ribbon = getUniqueName( %newName );
+   eval("datablock RibbonData( " @ %ribbon @ " : " @ %sourceDB @ " ){};");
+   
+   // Submit undo.
+   
+   %action = ParticleEditor.createUndo( ActionCreateNewRibbon, "Create New Ribbon" );
+   %action.prevRibbon = PE_RibbonParticleEditor.currRibbon;
+   %action.ribbon = %ribbon.getId();
+   %action.ribbonName = %ribbon;
+
+   ParticleEditor.submitUndo( %action );
+
+   // Execute action.
+   %action.redo();
+   
+   %this.saver.setDirty(%ribbon, $PE_RibbonParticleEditor_DEFAULT_FILENAME);
+   
+   %this.loadNewRibbon(%ribbon);
+   %this.setDirty();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::showDeleteDialog( %this )
+{
+   if( PE_RibbonParticleEditor.currRibbon.getName() $= "BasicRibbon" )
+   {
+      toolsMessageBoxOK( "Error", "Cannot delete BasicRibbon");
+      return;
+   }
+   
+   if( isObject( PE_RibbonParticleEditor.currRibbon ) )
+   {
+      toolsMessageBoxYesNoCancel("Delete Ribbon?", 
+         "Are you sure you want to delete<br><br>" @ PE_RibbonParticleEditor.currRibbon.getName() @ "<br><br> Ribbon deletion won't take affect until the level is exited.", 
+         "PE_RibbonParticleEditor.saveRibbonDialogDontSave( " @ PE_RibbonParticleEditor.currRibbon.getName() @ " ); PE_RibbonParticleEditor.deleteRibbon();"
+      );
+   }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::deleteRibbon( %this )
+{  
+   %ribbon = PE_RibbonParticleEditor.currRibbon;
+   
+   // Create undo.
+   
+   %action = ParticleEditor.createUndo( ActionDeleteRibbon, "Delete Ribbon" );
+   %action.ribbon = %ribbon;
+   %action.ribbonFname = %ribbon.getFilename();
+
+   ParticleEditor.submitUndo( %action );
+   
+   // Execute action.
+
+   %action.redo();
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::saveRibbon( %this, %ribbon )
+{   
+   if ( %ribbon $= "" )
+   {
+      %ribbon = %this.currRibbon;
+      %newName = %this.currRibbon.getName();
+   }
+   else
+   {
+      %newName = %ribbon.getName();
+   }
+   
+   %this.currRibbon.setName( %newName );
+   PE_RibbonParticleEditor_NotDirtyRibbon.assignFieldsFrom( %ribbon );
+   PE_RibbonParticleEditor_NotDirtyRibbon.originalName = %newName;
+   
+   %this.saver.saveDirty(); 
+   
+   %this.loadNewRibbon(%newName.getId());
+
+}
+
+//---------------------------------------------------------------------------------------------
+
+function PE_RibbonParticleEditor::saveRibbonDialogDontSave( %this, %ribbon)
+{  
+   %ribbon.setName( PE_RibbonParticleEditor_NotDirtyRibbon.originalName );
+   %ribbon.assignFieldsFrom( PE_RibbonParticleEditor_NotDirtyRibbon );
+   PE_RibbonParticleEditor.setNotDirty();
+}

+ 3 - 0
Templates/BaseGame/game/tools/worldEditor/main.tscript

@@ -50,6 +50,9 @@ function initializeWorldEditor()
    exec("tools/gui/compositeTextureEditor.gui" );
    exec("tools/gui/postFxEditor.gui" );
    
+   exec("tools/gui/contextedDropdownList.tscript");
+   exec("tools/gui/contextedDropdownList.gui");
+   
    // Load Scripts.
    exec("./scripts/menus.ed." @ $TorqueScriptFileExtension);
    exec("./scripts/menuHandlers.ed." @ $TorqueScriptFileExtension);