From c74a7b1bc28fd57d4ab0f719d64052b2bca15ee3 Mon Sep 17 00:00:00 2001 From: Areloch Date: Sun, 3 Dec 2017 01:21:30 -0600 Subject: [PATCH] Fixes the inspector/component editor to display the components attached to an entity correctly in the inspector. --- Engine/source/gui/editor/guiInspector.cpp | 45 ++- Engine/source/gui/editor/guiInspector.h | 5 + .../gui/editor/inspector/componentGroup.cpp | 294 +++++++++++++++++- .../gui/editor/inspector/componentGroup.h | 8 +- .../gui/worldEditor/worldEditorSelection.cpp | 40 ++- Templates/BaseGame/game/core/main.cs | 6 + .../scripts/server/connectionToClient.cs | 17 + .../scripts/server/levelDownload.cs | 18 +- .../scripts/componentEditor.ed.cs | 98 +++++- .../tools/worldEditor/scripts/EditorGui.ed.cs | 26 ++ 10 files changed, 513 insertions(+), 44 deletions(-) diff --git a/Engine/source/gui/editor/guiInspector.cpp b/Engine/source/gui/editor/guiInspector.cpp index 086995529..63e112c9e 100644 --- a/Engine/source/gui/editor/guiInspector.cpp +++ b/Engine/source/gui/editor/guiInspector.cpp @@ -32,6 +32,7 @@ #include "gui/editor/inspector/entityGroup.h" #include "gui/editor/inspector/mountingGroup.h" #include "gui/editor/inspector/componentGroup.h" +#include "T3D/components/component.h" IMPLEMENT_CONOBJECT(GuiInspector); @@ -590,6 +591,13 @@ void GuiInspector::refresh() //Entity inspector group if (mTargets.first()->getClassRep()->isSubclassOf("Entity")) { + //Put the GameObject group before everything that'd be gameobject-effecting, for orginazational purposes + GuiInspectorGroup *gameObject = new GuiInspectorGroup("GameObject", this); + + gameObject->registerObject(); + mGroups.push_back(gameObject); + addObject(gameObject); + GuiInspectorEntityGroup *components = new GuiInspectorEntityGroup("Components", this); if (components != NULL) { @@ -598,6 +606,29 @@ void GuiInspector::refresh() addObject(components); } + Entity* selectedEntity = dynamic_cast(mTargets.first().getObject()); + + U32 compCount = selectedEntity->getComponentCount(); + //Now, add the component groups + for (U32 c = 0; c < compCount; ++c) + { + Component* comp = selectedEntity->getComponent(c); + + String compName; + if (comp->getFriendlyName() != StringTable->EmptyString()) + compName = comp->getFriendlyName(); + else + compName = comp->getComponentName(); + + GuiInspectorGroup *compGroup = new GuiInspectorComponentGroup(compName, this, comp); + if (compGroup != NULL) + { + compGroup->registerObject(); + mGroups.push_back(compGroup); + addObject(compGroup); + } + } + //Mounting group override GuiInspectorGroup *mounting = new GuiInspectorMountingGroup("Mounting", this); if (mounting != NULL) @@ -608,20 +639,6 @@ void GuiInspector::refresh() } } - if (mTargets.first()->getClassRep()->isSubclassOf("Component")) - { - //Build the component field groups as the component describes it - Component* comp = dynamic_cast(mTargets.first().getPointer()); - - if (comp->getComponentFieldCount() > 0) - { - GuiInspectorComponentGroup *compGroup = new GuiInspectorComponentGroup("Component Fields", this); - compGroup->registerObject(); - mGroups.push_back(compGroup); - addObject(compGroup); - } - } - // Create the inspector groups for static fields. for( TargetVector::iterator iter = mTargets.begin(); iter != mTargets.end(); ++ iter ) diff --git a/Engine/source/gui/editor/guiInspector.h b/Engine/source/gui/editor/guiInspector.h index f5b00a796..1896b55dc 100644 --- a/Engine/source/gui/editor/guiInspector.h +++ b/Engine/source/gui/editor/guiInspector.h @@ -89,6 +89,9 @@ public: else return nullptr; } + + S32 getComponentGroupTargetId() { return mComponentGroupTargetId; } + void setComponentGroupTargetId(S32 compId) { mComponentGroupTargetId = compId; } /// Return the number of objects being inspected by this GuiInspector. U32 getNumInspectObjects() const { return mTargets.size(); } @@ -146,6 +149,8 @@ protected: /// Objects being inspected by this GuiInspector. TargetVector mTargets; + + S32 mComponentGroupTargetId; F32 mDividerPos; S32 mDividerMargin; diff --git a/Engine/source/gui/editor/inspector/componentGroup.cpp b/Engine/source/gui/editor/inspector/componentGroup.cpp index 7d6d30eaa..6e16db173 100644 --- a/Engine/source/gui/editor/inspector/componentGroup.cpp +++ b/Engine/source/gui/editor/inspector/componentGroup.cpp @@ -38,10 +38,11 @@ ConsoleDocClass(GuiInspectorComponentGroup, "@internal" ); -GuiInspectorComponentGroup::GuiInspectorComponentGroup(StringTableEntry groupName, SimObjectPtr parent) +GuiInspectorComponentGroup::GuiInspectorComponentGroup(StringTableEntry groupName, SimObjectPtr parent, Component* targetComponent) : GuiInspectorGroup(groupName, parent) { /*mNeedScroll=false;*/ + mTargetComponent = targetComponent; }; bool GuiInspectorComponentGroup::onAdd() @@ -89,15 +90,277 @@ bool GuiInspectorComponentGroup::inspectGroup() GuiRolloutCtrl *pArrayRollout = NULL; bool bGrabItems = false; - Component* comp = dynamic_cast(getInspector()->getInspectObject(0)); - //if this isn't a component, what are we even doing here? - if (!comp) + if (!mTargetComponent) return false; - for (U32 i = 0; i < comp->getComponentFieldCount(); i++) + mParent->setComponentGroupTargetId(mTargetComponent->getId()); + + //first, relevent static fields + AbstractClassRep::FieldList& fieldList = mTargetComponent->getClassRep()->mFieldList; + for (AbstractClassRep::FieldList::iterator itr = fieldList.begin(); + itr != fieldList.end(); ++itr) { - ComponentField* field = comp->getComponentField(i); + AbstractClassRep::Field* field = &(*itr); + if (field->type == AbstractClassRep::StartGroupFieldType) + { + // If we're dealing with general fields, always set grabItems to true (to skip them) + if (bNoGroup == true) + bGrabItems = true; + else if (dStricmp(field->pGroupname, mCaption) == 0) + bGrabItems = true; + continue; + } + else if (field->type == AbstractClassRep::EndGroupFieldType) + { + // If we're dealing with general fields, always set grabItems to false (to grab them) + if (bNoGroup == true) + bGrabItems = false; + else if (dStricmp(field->pGroupname, mCaption) == 0) + bGrabItems = false; + continue; + } + + // Skip field if it has the HideInInspectors flag set. + if (field->flag.test(AbstractClassRep::FIELD_HideInInspectors)) + continue; + + if (field->pFieldname == StringTable->insert("locked") || field->pFieldname == StringTable->insert("class") + || field->pFieldname == StringTable->insert("internalName")) + continue; + + if (/*(bGrabItems == true || (bNoGroup == true && bGrabItems == false)) &&*/ itr->type != AbstractClassRep::DeprecatedFieldType) + { + if (bNoGroup == true && bGrabItems == true) + continue; + + if (field->type == AbstractClassRep::StartArrayFieldType) + { +#ifdef DEBUG_SPEW + Platform::outputDebugString("[GuiInspectorGroup] Beginning array '%s'", + field->pFieldname); +#endif + + // Starting an array... + // Create a rollout for the Array, give it the array's name. + GuiRolloutCtrl *arrayRollout = new GuiRolloutCtrl(); + GuiControlProfile *arrayRolloutProfile = dynamic_cast(Sim::findObject("GuiInspectorRolloutProfile0")); + + arrayRollout->setControlProfile(arrayRolloutProfile); + //arrayRollout->mCaption = StringTable->insert( String::ToString( "%s (%i)", field->pGroupname, field->elementCount ) ); + arrayRollout->setCaption(field->pGroupname); + //arrayRollout->setMargin( 14, 0, 0, 0 ); + arrayRollout->registerObject(); + + GuiStackControl *arrayStack = new GuiStackControl(); + arrayStack->registerObject(); + arrayStack->freeze(true); + arrayRollout->addObject(arrayStack); + + // Allocate a rollout for each element-count in the array + // Give it the element count name. + for (U32 i = 0; i < field->elementCount; i++) + { + GuiRolloutCtrl *elementRollout = new GuiRolloutCtrl(); + GuiControlProfile *elementRolloutProfile = dynamic_cast(Sim::findObject("GuiInspectorRolloutProfile0")); + + char buf[256]; + dSprintf(buf, 256, " [%i]", i); + + elementRollout->setControlProfile(elementRolloutProfile); + elementRollout->setCaption(buf); + //elementRollout->setMargin( 14, 0, 0, 0 ); + elementRollout->registerObject(); + + GuiStackControl *elementStack = new GuiStackControl(); + elementStack->registerObject(); + elementRollout->addObject(elementStack); + elementRollout->instantCollapse(); + + arrayStack->addObject(elementRollout); + } + + pArrayRollout = arrayRollout; + pArrayStack = arrayStack; + arrayStack->freeze(false); + pArrayRollout->instantCollapse(); + mStack->addObject(arrayRollout); + + bMakingArray = true; + continue; + } + else if (field->type == AbstractClassRep::EndArrayFieldType) + { +#ifdef DEBUG_SPEW + Platform::outputDebugString("[GuiInspectorGroup] Ending array '%s'", + field->pFieldname); +#endif + + bMakingArray = false; + continue; + } + + if (bMakingArray) + { + // Add a GuiInspectorField for this field, + // for every element in the array... + for (U32 i = 0; i < pArrayStack->size(); i++) + { + FrameTemp intToStr(64); + dSprintf(intToStr, 64, "%d", i); + + // The array stack should have a rollout for each element + // as children... + GuiRolloutCtrl *pRollout = dynamic_cast(pArrayStack->at(i)); + // And the each of those rollouts should have a stack for + // fields... + GuiStackControl *pStack = dynamic_cast(pRollout->at(0)); + + // And we add a new GuiInspectorField to each of those stacks... + GuiInspectorField *fieldGui = constructField(field->type); + if (fieldGui == NULL) + fieldGui = new GuiInspectorField(); + + fieldGui->init(mParent, this); + StringTableEntry caption = field->pFieldname; + fieldGui->setInspectorField(field, caption, intToStr); + + if (fieldGui->registerObject()) + { +#ifdef DEBUG_SPEW + Platform::outputDebugString("[GuiInspectorGroup] Adding array element '%s[%i]'", + field->pFieldname, i); +#endif + + mChildren.push_back(fieldGui); + pStack->addObject(fieldGui); + } + else + delete fieldGui; + } + + continue; + } + + // This is weird, but it should work for now. - JDD + // We are going to check to see if this item is an array + // if so, we're going to construct a field for each array element + if (field->elementCount > 1) + { + // Make a rollout control for this array + // + GuiRolloutCtrl *rollout = new GuiRolloutCtrl(); + rollout->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorRolloutProfile0"); + rollout->setCaption(String::ToString("%s (%i)", field->pFieldname, field->elementCount)); + rollout->setMargin(14, 0, 0, 0); + rollout->registerObject(); + mArrayCtrls.push_back(rollout); + + // Put a stack control within the rollout + // + GuiStackControl *stack = new GuiStackControl(); + stack->setDataField(StringTable->insert("profile"), NULL, "GuiInspectorStackProfile"); + stack->registerObject(); + stack->freeze(true); + rollout->addObject(stack); + + mStack->addObject(rollout); + + // Create each field and add it to the stack. + // + for (S32 nI = 0; nI < field->elementCount; nI++) + { + FrameTemp intToStr(64); + dSprintf(intToStr, 64, "%d", nI); + + // Construct proper ValueName[nI] format which is "ValueName0" for index 0, etc. + + String fieldName = String::ToString("%s%d", field->pFieldname, nI); + + // If the field already exists, just update it + GuiInspectorField *fieldGui = findField(fieldName); + if (fieldGui != NULL) + { + fieldGui->updateValue(); + continue; + } + + bNewItems = true; + + fieldGui = constructField(field->type); + if (fieldGui == NULL) + fieldGui = new GuiInspectorField(); + + fieldGui->init(mParent, this); + StringTableEntry caption = StringTable->insert(String::ToString(" [%i]", nI)); + fieldGui->setInspectorField(field, caption, intToStr); + + fieldGui->setTargetObject(mTargetComponent); + + if (fieldGui->registerObject()) + { + mChildren.push_back(fieldGui); + stack->addObject(fieldGui); + } + else + delete fieldGui; + } + + stack->freeze(false); + stack->updatePanes(); + rollout->instantCollapse(); + } + else + { + // If the field already exists, just update it + GuiInspectorField *fieldGui = findField(field->pFieldname); + if (fieldGui != NULL) + { + fieldGui->updateValue(); + continue; + } + + bNewItems = true; + + fieldGui = constructField(field->type); + if (fieldGui == NULL) + fieldGui = new GuiInspectorField(); + + fieldGui->init(mParent, this); + fieldGui->setInspectorField(field); + + fieldGui->setTargetObject(mTargetComponent); + + if (fieldGui->registerObject()) + { +#ifdef DEBUG_SPEW + Platform::outputDebugString("[GuiInspectorGroup] Adding field '%s'", + field->pFieldname); +#endif + fieldGui->setValue(mTargetComponent->getDataField(field->pFieldname, NULL)); + + mChildren.push_back(fieldGui); + mStack->addObject(fieldGui); + } + else + { + SAFE_DELETE(fieldGui); + } + } + } + } + + for (U32 i = 0; i < mTargetComponent->getComponentFieldCount(); i++) + { + ComponentField* field = mTargetComponent->getComponentField(i); + + //first and foremost, nab the field type and check if it's a custom field or not. + //If it's not a custom field, proceed below, if it is, hand it off to script to be handled by the component + if (field->mFieldType == -1) + { + Con::executef(this, "onConstructComponentField", mTargetComponent, field->mFieldName); + continue; + } bNewItems = true; @@ -107,10 +370,12 @@ bool GuiInspectorComponentGroup::inspectGroup() fieldGui->init(mParent, this); - AbstractClassRep::Field *refField; + fieldGui->setTargetObject(mTargetComponent); + + AbstractClassRep::Field *refField = NULL; //check dynamics - SimFieldDictionary* fieldDictionary = comp->getFieldDictionary(); + SimFieldDictionary* fieldDictionary = mTargetComponent->getFieldDictionary(); SimFieldDictionaryIterator itr(fieldDictionary); while (*itr) @@ -196,6 +461,14 @@ void GuiInspectorComponentGroup::onMouseMove(const GuiEvent &event) { //mParent->mOverDivider = false; } + +void GuiInspectorComponentGroup::onRightMouseUp(const GuiEvent &event) +{ + //mParent->mOverDivider = false; + if (isMethod("onRightMouseUp")) + Con::executef(this, "onRightMouseUp", event.mousePoint); +} + ConsoleMethod(GuiInspectorComponentGroup, inspectGroup, bool, 2, 2, "Refreshes the dynamic fields in the inspector.") { return object->inspectGroup(); @@ -250,3 +523,8 @@ ConsoleMethod(GuiInspectorComponentGroup, addDynamicField, void, 2, 2, "obj.addD ConsoleMethod(GuiInspectorComponentGroup, removeDynamicField, void, 3, 3, "") { } + +DefineConsoleMethod(GuiInspectorComponentGroup, getComponent, S32, (), ,"") +{ + return object->getComponent()->getId(); +} diff --git a/Engine/source/gui/editor/inspector/componentGroup.h b/Engine/source/gui/editor/inspector/componentGroup.h index 34b748c98..f41c11b09 100644 --- a/Engine/source/gui/editor/inspector/componentGroup.h +++ b/Engine/source/gui/editor/inspector/componentGroup.h @@ -34,12 +34,14 @@ private: typedef GuiInspectorGroup Parent; GuiControl* mAddCtrl; + Component* mTargetComponent; + Vector tempFields; public: DECLARE_CONOBJECT(GuiInspectorComponentGroup); GuiInspectorComponentGroup() { /*mNeedScroll=false;*/ }; - GuiInspectorComponentGroup(StringTableEntry groupName, SimObjectPtr parent); + GuiInspectorComponentGroup(StringTableEntry groupName, SimObjectPtr parent, Component* targetComponent); //----------------------------------------------------------------------------- // inspectGroup is overridden in GuiInspectorComponentGroup to inspect an @@ -50,6 +52,7 @@ public: virtual void updateAllFields(); void onMouseMove(const GuiEvent &event); + virtual void onRightMouseUp(const GuiEvent &event); // For scriptable dynamic field additions void addDynamicField(); @@ -61,6 +64,9 @@ public: virtual SimFieldDictionary::Entry* findDynamicFieldInDictionary(StringTableEntry fieldName); AbstractClassRep::Field* findObjectBehaviorField(Component* target, String fieldName); + + Component* getComponent() { return mTargetComponent; } + protected: // create our inner controls when we add virtual bool createContent(); diff --git a/Engine/source/gui/worldEditor/worldEditorSelection.cpp b/Engine/source/gui/worldEditor/worldEditorSelection.cpp index eaaeb4c43..00311adea 100644 --- a/Engine/source/gui/worldEditor/worldEditorSelection.cpp +++ b/Engine/source/gui/worldEditor/worldEditorSelection.cpp @@ -23,7 +23,7 @@ #include "gui/worldEditor/worldEditorSelection.h" #include "gui/worldEditor/worldEditor.h" #include "scene/sceneObject.h" - +#include "T3D/entity.h" IMPLEMENT_CONOBJECT( WorldEditorSelection ); @@ -410,26 +410,34 @@ void WorldEditorSelection::rotate(const EulerF & rot, const Point3F & center) // single selections will rotate around own axis, multiple about world if(size() == 1) { - SceneObject* object = dynamic_cast< SceneObject* >( at( 0 ) ); - if( object ) + Entity* eO = dynamic_cast< Entity* >(at(0)); + if (eO) { - MatrixF mat = object->getTransform(); + eO->setTransform(eO->getPosition(), eO->getRotation() + RotationF(rot)); + } + else + { + SceneObject* object = dynamic_cast(at(0)); + if (object) + { + MatrixF mat = object->getTransform(); - Point3F pos; - mat.getColumn(3, &pos); + Point3F pos; + mat.getColumn(3, &pos); - // get offset in obj space - Point3F offset = pos - center; - MatrixF wMat = object->getWorldTransform(); - wMat.mulV(offset); + // get offset in obj space + Point3F offset = pos - center; + MatrixF wMat = object->getWorldTransform(); + wMat.mulV(offset); - // - MatrixF transform(EulerF(0,0,0), -offset); - transform.mul(MatrixF(rot)); - transform.mul(MatrixF(EulerF(0,0,0), offset)); - mat.mul(transform); + // + MatrixF transform(EulerF(0, 0, 0), -offset); + transform.mul(MatrixF(rot)); + transform.mul(MatrixF(EulerF(0, 0, 0), offset)); + mat.mul(transform); - object->setTransform(mat); + object->setTransform(mat); + } } } else diff --git a/Templates/BaseGame/game/core/main.cs b/Templates/BaseGame/game/core/main.cs index a8a396f41..8058c1f90 100644 --- a/Templates/BaseGame/game/core/main.cs +++ b/Templates/BaseGame/game/core/main.cs @@ -41,6 +41,12 @@ $Core::UnAvailableTexturePath = "core/images/unavailable"; $Core::WarningTexturePath = "core/images/warnMat"; $Core::CommonShaderPath = "core/shaders"; +ModuleDatabase.setModuleExtension("module"); + +//Core components +ModuleDatabase.scanModules( "core", false ); +ModuleDatabase.LoadExplicit( "CoreComponentsModule" ); + exec("./helperFunctions.cs"); // We need some of the default GUI profiles in order to get the canvas and diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/connectionToClient.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/connectionToClient.cs index c3a4a3e26..38709c971 100644 --- a/Templates/BaseGame/game/data/clientServer/scripts/server/connectionToClient.cs +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/connectionToClient.cs @@ -132,6 +132,23 @@ function isNameUnique(%name) // function GameConnection::onDrop(%client, %reason) { + %entityIds = parseMissionGroupForIds("Entity", ""); + %entityCount = getWordCount(%entityIds); + + for(%i=0; %i < %entityCount; %i++) + { + %entity = getWord(%entityIds, %i); + + for(%e=0; %e < %entity.getCount(); %e++) + { + %child = %entity.getObject(%e); + if(%child.getClassName() $= "Entity") + %entityIds = %entityIds SPC %child.getID(); + } + + %entity.notify("onClientDisconnect", %client); + } + if($missionRunning) theLevelInfo.onClientLeaveGame(); diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/levelDownload.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/levelDownload.cs index a598ee04f..e33f80711 100644 --- a/Templates/BaseGame/game/data/clientServer/scripts/server/levelDownload.cs +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/levelDownload.cs @@ -131,6 +131,22 @@ function serverCmdMissionStartPhase3Ack(%client, %seq) %client.currentPhase = 3; // Server is ready to drop into the game + %entityIds = parseMissionGroupForIds("Entity", ""); + %entityCount = getWordCount(%entityIds); + + for(%i=0; %i < %entityCount; %i++) + { + %entity = getWord(%entityIds, %i); + + for(%e=0; %e < %entity.getCount(); %e++) + { + %child = %entity.getObject(%e); + if(%child.getCLassName() $= "Entity") + %entityIds = %entityIds SPC %child.getID(); + } + + %entity.notify("onClientConnect", %client); + } //Have any special game-play handling here if(theLevelInfo.isMethod("onClientEnterGame")) @@ -151,7 +167,7 @@ function serverCmdMissionStartPhase3Ack(%client, %seq) }; } - if (isDefined("$Game::DefaultCameraClass")) + //if (isDefined("$Game::DefaultCameraClass")) %client.camera = spawnObject("Camera", Observer); } diff --git a/Templates/BaseGame/game/tools/componentEditor/scripts/componentEditor.ed.cs b/Templates/BaseGame/game/tools/componentEditor/scripts/componentEditor.ed.cs index 9a9ce33d6..a2a62b08a 100644 --- a/Templates/BaseGame/game/tools/componentEditor/scripts/componentEditor.ed.cs +++ b/Templates/BaseGame/game/tools/componentEditor/scripts/componentEditor.ed.cs @@ -154,13 +154,13 @@ function QuickEditComponentList::onHotTrackItem( %this, %itemID ) SuperTooltipDlg.setTitle(%componentObj.friendlyName); SuperTooltipDlg.addParam("", %componentObj.description @ "\n"); - %fieldCount = %componentObj.getComponentFieldCount(); + /*%fieldCount = %componentObj.getComponentFieldCount(); for (%i = 0; %i < %fieldCount; %i++) { %name = getField(%componentObj.getComponentField(%i), 0); SuperTooltipDlg.addParam(%name, %description @ "\n"); - } + }*/ %position = %this.getGlobalPosition(); SuperTooltipDlg.processTooltip( %position,0,1 ); %this.opened = true; @@ -219,7 +219,7 @@ function AddComponentQuickEditButton::onClick(%this) %instance.owner = Inspector.getInspectObject(0); %instance.owner.add(%instance); - Inspector.schedule( 50, "refresh" ); + schedule( 50, 0, "refreshInspector", Inspector.getInspectObject(0) ); EWorldEditor.isDirty = true; } @@ -227,7 +227,97 @@ function addComponent(%obj, %instance) { echo("Adding the component!"); %obj.addComponent(%instance); - Inspector.schedule( 50, "refresh" ); + //Inspector.schedule( 50, "refresh" ); + schedule( 50, 0, "refreshInspector", Inspector.getInspectObject(0) ); EWorldEditor.isDirty = true; } +function refreshInspector(%entity) +{ + inspector.removeInspect(%entity); + inspector.addInspect(%entity); +} + +function GuiInspectorComponentGroup::onConstructComponentField(%this, %component, %fieldName) +{ + //echo("Tried to make a component field for component:" @ %component @ " for the " @ %fieldName @ " field."); + + %fieldType = %component.getComponentFieldType(%fieldName); + %makeCommand = %this @ ".build" @ %fieldType @ "Field("@ %component @ "," @ %fieldName @ ");"; + eval(%makeCommand); +} + +function GuiInspectorComponentGroup::onRightMouseUp(%this, %point) +{ + if( !isObject( InspectComponentPopup ) ) + new PopupMenu( InspectComponentPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "View in Asset Browser" TAB "" TAB "AssetBrowser.editAsset();"; + item[ 1 ] = "Delete Component" TAB "" TAB "schedule(10, 0, ComponentEditorRemoveComponent, InspectComponentPopup.componentOwner, InspectComponentPopup.component);"; + item[ 2 ] = "Edit Script" TAB "" TAB "AssetBrowser.editAsset();"; + item[ 3 ] = ""; + }; + + %comp = %this.getComponent(); + InspectComponentPopup.componentOwner = %comp.owner; + InspectComponentPopup.component = %comp; + + //Find out our asset! + %componentName = %this.caption; + + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "ComponentAsset")) + return; //if we didn't find ANY, just exit + + EditAssetPopup.assetId = ""; + + // Find all the types. + %count = %assetQuery.getCount(); + + %categories = ""; + for (%i = 0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %friendlyName = %componentAsset.friendlyName; + + if(%friendlyName !$= "" && %friendlyName $= %componentName) + { + EditAssetPopup.assetId = %assetId; + break; + } + + %compName = %componentAsset.componentName; + + if(%compName !$= "" && %compName $= %componentName) + { + EditAssetPopup.assetId = %assetId; + break; + } + } + + if(EditAssetPopup.assetId $= "") + { + //didn't find it + InspectComponentPopup.enableItem(0, false); + InspectComponentPopup.enableItem(2, false); + } + else + { + InspectComponentPopup.enableItem(0, true); + InspectComponentPopup.enableItem(2, true); + } + + InspectComponentPopup.showPopup(Canvas); +} + +function ComponentEditorRemoveComponent(%entity, %component) +{ + %entity.removeComponent(%component, true); + inspector.removeInspect(%entity); + inspector.addInspect(%entity); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs index bc1905292..f6e88eece 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -1302,6 +1302,7 @@ function VisibilityDropdownToggle() { EVisibility.setVisible(true); visibilityToggleBtn.setStateOn(1); + EVisibility.setExtent("200 540"); } } @@ -1641,6 +1642,31 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) object = -1; }; + + if(%obj.isMemberOfClass("Entity")) + { + if( !isObject( GameObjectPopup ) ) + %popup = new PopupMenu( GameObjectPopup : ETSimGroupContextPopup ) + { + //item[ 12 ] = "-"; + item[ 12 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; + item[ 13 ] = "Duplicate Game Object" TAB "" TAB "EWorldEditor.duplicateGameObject( %this.object );"; + item[ 14 ] = "Show in Asset Browser" TAB "" TAB "EWorldEditor.showGameObjectInAssetBrowser( %this.object );"; + }; + + if(!isObject(AssetDatabase.acquireAsset(%obj.gameObjectAsset))) + { + GameObjectPopup.enableItem(12, true); + GameObjectPopup.enableItem(13, false); + GameObjectPopup.enableItem(14, false); + } + else + { + GameObjectPopup.enableItem(12, false); + GameObjectPopup.enableItem(13, true); + GameObjectPopup.enableItem(14, true); + } + } %popup.object = %obj;