diff --git a/Engine/source/T3D/fx/particle.cpp b/Engine/source/T3D/fx/particle.cpp index 8186853b8..b9d9e874d 100644 --- a/Engine/source/T3D/fx/particle.cpp +++ b/Engine/source/T3D/fx/particle.cpp @@ -907,6 +907,9 @@ GuiControl* GuiInspectorTypeParticleDataList::constructEditControl() mNewParticleBtn->registerObject(); mNewParticleBtn->_setBitmap(StringTable->insert("ToolsModule:iconAdd_image")); mNewParticleBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiDefaultProfile"); + mNewParticleBtn->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + mNewParticleBtn->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + mNewParticleBtn->setDataField(StringTable->insert("tooltip"), NULL, "Add new particle slot"); mNewParticleBtn->setHorizSizing(horizResizeRight); mNewParticleBtn->mMakeIconSquare = true; mNewParticleBtn->mFitBitmapToButton = true; @@ -914,7 +917,7 @@ GuiControl* GuiInspectorTypeParticleDataList::constructEditControl() char szBuffer[512]; dSprintf(szBuffer, sizeof(szBuffer), "ParticleEditor.addParticleSlot(%s, %s);", - mNewParticleBtn->getIdString(), mInspector->getInspectObject()->getIdString()); + this->getIdString(), mInspector->getInspectObject()->getIdString()); mNewParticleBtn->setField("Command", szBuffer); GuiContainer* newBtnCtnr = new GuiContainer(); @@ -924,39 +927,16 @@ GuiControl* GuiInspectorTypeParticleDataList::constructEditControl() 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 != NULL && !String::isEmpty(data)) - { - U32 particlesCount = StringUnit::getUnitCount(data, " "); - for (U32 i=1; i < particlesCount; i++) - { - GuiControl* particleSlotCtrl = _buildParticleEntryField(i); - mStack->addObject(particleSlotCtrl); - } - } + _rebuildParticleEntryList(); _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; + //Now the non-default entries if we already have some + //Parent::updateValue(); + return mStack; } @@ -980,7 +960,7 @@ GuiControl* GuiInspectorTypeParticleDataList::_buildParticleEntryField(const S32 char szBuffer[512]; dSprintf(szBuffer, sizeof(szBuffer), "ParticleEditor.changeParticleSlot(%s, %s, %d);", - listBtn->getIdString(), mInspector->getInspectObject()->getIdString(), index); + this->getIdString(), mInspector->getInspectObject()->getIdString(), index); listBtn->setField("Command", szBuffer); if (mField && index != -1) @@ -1001,6 +981,9 @@ GuiControl* GuiInspectorTypeParticleDataList::_buildParticleEntryField(const S32 editSlotBtn->registerObject(); editSlotBtn->setText(StringTable->insert("...")); editSlotBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiButtonProfile"); + editSlotBtn->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + editSlotBtn->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + editSlotBtn->setDataField(StringTable->insert("tooltip"), NULL, "Edit this particle"); editSlotBtn->setHorizSizing(horizResizeRight); editSlotBtn->setInternalName("editBtn"); editSlotBtn->setPosition(editExtent.x - 40, 0); @@ -1019,6 +1002,9 @@ GuiControl* GuiInspectorTypeParticleDataList::_buildParticleEntryField(const S32 deleteSlotBtn->registerObject(); deleteSlotBtn->_setBitmap(StringTable->insert("ToolsModule:iconCancel_image")); deleteSlotBtn->setDataField(StringTable->insert("profile"), NULL, "ToolsGuiDefaultProfile"); + deleteSlotBtn->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); + deleteSlotBtn->setDataField(StringTable->insert("hovertime"), NULL, "1000"); + deleteSlotBtn->setDataField(StringTable->insert("tooltip"), NULL, "Delete this particle slot"); deleteSlotBtn->setHorizSizing(horizResizeRight); deleteSlotBtn->setInternalName("deleteBtn"); deleteSlotBtn->mMakeIconSquare = true; @@ -1062,6 +1048,38 @@ void GuiInspectorTypeParticleDataList::_populateMenu(GuiPopUpMenuCtrlEx* menu) menu->sort(); } +void GuiInspectorTypeParticleDataList::_rebuildParticleEntryList() +{ + const char* data = getData(); + + //whoops it's misaligned, force a rebuild + mParticleSlot0Ctrl = NULL; + + for (U32 i = 0; i < mParticleSlotList.size(); i++) + { + mStack->removeObject(mParticleSlotList[i]); + mParticleSlotList[i]->deleteObject(); + } + mParticleSlotList.clear(); + + //Particle 0 + mParticleSlot0Ctrl = _buildParticleEntryField(0); + mStack->addObject(mParticleSlot0Ctrl); + mParticleSlotList.push_back(mParticleSlot0Ctrl); + + if (data != NULL && !String::isEmpty(data)) + { + U32 particlesCount = StringUnit::getUnitCount(data, " "); + + for (U32 i = 1; i < particlesCount; i++) + { + GuiControl* particleSlotCtrl = _buildParticleEntryField(i); + mStack->addObject(particleSlotCtrl); + mParticleSlotList.push_back(particleSlotCtrl); + } + } +} + bool GuiInspectorTypeParticleDataList::updateRects() { S32 rowSize = 18; @@ -1109,14 +1127,43 @@ bool GuiInspectorTypeParticleDataList::updateRects() mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); + mUseHeightOverride = true; 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)); + RectI bnds = getBounds(); + setBounds(bnds.point.x, bnds.point.y, bnds.extent.x, mHeightOverride); return true; } +void GuiInspectorTypeParticleDataList::updateValue() +{ + const char* data = getData(); + + if (data != NULL && !String::isEmpty(data)) + { + U32 particlesCount = StringUnit::getUnitCount(data, " "); + + if (particlesCount != mParticleSlotList.size()) + { + _rebuildParticleEntryList(); + } + else + { + for (U32 i = 0; i < particlesCount; i++) + { + GuiButtonCtrl* listBtn = dynamic_cast(mParticleSlotList[i]->getObject(0)); + if (!listBtn) //This *really* shouldn't happen + continue; + + const char* particleName = StringUnit::getUnit(data, i, " "); + listBtn->setText(particleName); + } + } + } + + updateRects(); +} void GuiInspectorTypeParticleDataList::consoleInit() { diff --git a/Engine/source/T3D/fx/particleInspectors.h b/Engine/source/T3D/fx/particleInspectors.h index d6784d0b5..152df20c8 100644 --- a/Engine/source/T3D/fx/particleInspectors.h +++ b/Engine/source/T3D/fx/particleInspectors.h @@ -33,8 +33,10 @@ public: GuiControl* constructEditControl() override; bool updateRects() override; + void updateValue() override; void _populateMenu(GuiPopUpMenuCtrlEx* menu); GuiControl* _buildParticleEntryField(const S32& index); + void _rebuildParticleEntryList(); }; #endif diff --git a/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript index 5e590f34e..07424420b 100644 --- a/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript +++ b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript @@ -111,6 +111,19 @@ function DatablockEditorPlugin::onExitMission( %this ) function DatablockEditorPlugin::openDatablock( %this, %datablock ) { + //We want to do a special-case catch here for any datablock types that have their own unique editor. + //The main culprit is the particle editor, but this could be expanded later + if(%datablock.isMemberOfClass("ParticleData") || + %datablock.isMemberOfClass("ParticleEmitterData") || + %datablock.isMemberOfClass("ExplosionData") || + %datablock.isMemberOfClass("RibbonData") || + %datablock.isMemberOfClass("afxZodiacData") || + %datablock.isMemberOfClass("afxChoreographerData")) + { + EditorGui.setEditor( ParticleEditorPlugin ); + return; + } + EditorGui.setEditor( DatablockEditorPlugin ); %this.selectDatablock( %datablock ); DatablockEditorTreeTabBook.selectedPage = 0; @@ -631,6 +644,21 @@ function DatablockEditorPlugin::deleteDatablock( %this ) //--------------------------------------------------------------------------------------------- function DatablockEditorPlugin::createNewDatablockOfType(%this, %class, %inheritFrom) { + //We want to do a special-case catch here for any datablock types that have their own unique editor. + //The main culprit is the particle editor, but this could be expanded later + if(%class.isMemberOfClass("ParticleData") || + %class.isMemberOfClass("ParticleEmitterData") || + %class.isMemberOfClass("ExplosionData") || + %class.isMemberOfClass("RibbonData") || + %class.isMemberOfClass("afxZodiacData") || + %class.isMemberOfClass("afxChoreographerData")) + { + EditorGui.setEditor( ParticleEditorPlugin ); + + ParticleEditorPlugin::createNewDatablockOfType(%class, %inheritFrom); + return; + } + $DATABLOCK_EDITOR_NEWDB_CLASS = %class; $DATABLOCK_EDITOR_NEWDB_INHERITFROM = %inheritFrom; diff --git a/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript b/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript index c8faf01e1..f9a2f2961 100644 --- a/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/guis/particleEditor.ed.tscript @@ -51,8 +51,6 @@ function ParticleEditor::initEditor( %this ) if(exec("./PETabTemplate.gui")) { - echo("MADE A NEW TAB PAGE: " @ $guiContent); - $guiContent.text = %groupName; $guiContent.typesList = %typesList; $guiContent.setName(%editorName); @@ -199,7 +197,7 @@ function ParticleEditor::open(%this, %datablock) for(%t=0; %t < %typesListCount; %t++) { %type = getWord(%typesList, %t); - + if( %datablock.isMemberOfClass( %type ) ) { PE_TabBook.selectPage(%i); diff --git a/Templates/BaseGame/game/tools/particleEditor/main.tscript b/Templates/BaseGame/game/tools/particleEditor/main.tscript index 00f89bbe0..9494ae604 100644 --- a/Templates/BaseGame/game/tools/particleEditor/main.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/main.tscript @@ -113,6 +113,19 @@ function ParticleEditorPlugin::onActivated( %this ) EditorGuiStatusBar.setInfo( "Particle editor." ); EditorGuiStatusBar.setSelection( "" ); + // Try to start with the object selected in the world editor + %count = EWorldEditor.getSelectionSize(); + for (%i = 0; %i < %count; %i++) + { + %obj = EWorldEditor.getSelectedObject(%i); + %datablock = ParticleEditor.getObjectParticleData(%obj); + if (%datablock !$= "" && isObject(%datablock)) + { + ParticleEditor.open(%datablock); + break; + } + } + Parent::onActivated( %this ); } @@ -213,3 +226,12 @@ function ParticleEditor::registerParticleEdType(%this, %groupName, %typesList, % PE_ParticleDataTypes.add(%groupName, %typesList TAB %editorName); } +//------------------------------------------------------------------------------ +function ParticleEditor::getObjectParticleData( %this, %obj ) +{ + %datablock = ""; + if ( %obj.isMemberOfClass( "ParticleEmitterNode" ) ) + %datablock = %obj.emitter; + + return %datablock; +} diff --git a/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript b/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript index 7ab62ac70..c5555f9af 100644 --- a/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/scripts/particleEmitterEditor.ed.tscript @@ -122,7 +122,6 @@ function PE_EmitterEditor::selectObject(%this, %obj) && %obj.getName() $= %this-->popupMenu.text ) return; - //FIXME: disregards particle tab dirty state if( %this.dirty ) { if( PE_ParticleEditor.dirty ) @@ -483,6 +482,8 @@ function ParticleEditor::addParticleSlot(%this, %field, %emitterObj) %action.oldValue = %emitterObj.particles; ParticleEditor.submitUndo( %action ); + + %field.apply(%action.newValue); } function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx) @@ -495,7 +496,6 @@ function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx foreach( %obj in DatablockGroup ) { - echo(%typesList); %typesListCount = getWordCount(%typesList); for(%i=0; %i < %typesListCount; %i++) { @@ -552,7 +552,7 @@ function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx } } - ContextedDropdownListGui.show(%listSet, "Edit Particle Slot[" @ %slotIdx @ "]", "ParticleEditor.editSlot = " @ %slotIdx @ ";ParticleEditor.updateParticleSlot", %field); + ContextedDropdownListGui.show(%listSet, "Edit Particle Slot[" @ %slotIdx @ "]", "ParticleEditor.fieldObj = " @ %field @ ";ParticleEditor.editSlot = " @ %slotIdx @ ";ParticleEditor.updateParticleSlot", %field); %particleData = getWord(%emitterObj.particles, %slotIdx); if(%particleData !$= "") { @@ -562,10 +562,10 @@ function ParticleEditor::changeParticleSlot(%this, %field, %emitterObj, %slotIdx function ParticleEditor::updateParticleSlot(%this, %newParticle) { - if(ParticleEditor.editSlot $= "") + if(ParticleEditor.editSlot $= "" || !isObject(%newParticle)) return; - %updatedParticlesList = setWord(PE_EmitterEditor.currEmitter.particles, ParticleEditor.editSlot, %newParticle); + %updatedParticlesList = setWord(PE_EmitterEditor.currEmitter.particles, ParticleEditor.editSlot, %newParticle.getName()); %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Edit Active Emitter Particle Slot"); %action.emitter = PE_EmitterEditor.currEmitter; @@ -575,16 +575,19 @@ function ParticleEditor::updateParticleSlot(%this, %newParticle) ParticleEditor.submitUndo( %action ); - ParticleEditor.editSlot = ""; + ParticleEditor.fieldObj.apply(%action.newValue); - //%field.apply(%updatedParticlesList, %slotIdx); - //%this-->inspector.refresh(); + ParticleEditor.editSlot = ""; + ParticleEditor.fieldObj = ""; } function ParticleEditor::editParticleSlot(%this, %field, %emitterObj, %slotIdx) { %particleName = getWord(%emitterObj.particles, %slotIdx); + ParticleEditor.editSlot = ""; + ParticleEditor.fieldObj = ""; + ParticleEditor.open(%particleName); } @@ -600,6 +603,5 @@ function ParticleEditor::clearParticleSlot(%this, %field, %emitterObj, %slotIdx) ParticleEditor.submitUndo( %action ); - //%field.apply(%updatedParticlesList, %slotIdx); - //%this-->inspector.refresh(); + %field.apply(%action.newValue); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript b/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript index 43dc020f0..1b950a979 100644 --- a/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/particleEditor/scripts/particleParticleEditor.ed.tscript @@ -74,7 +74,8 @@ function PE_ParticleEditor::updateVizNode(%this) function PE_ParticleEditor::selectObject(%this, %obj) { // Bail if the user selected the same particle. - if( %obj == %this.currParticle ) + if( isObject(%obj ) + && %obj.getName() $= %this-->popupMenu.text ) return; // Load new particle if we're not in a dirty state