diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d1b65b183..dd8cab3b0 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,17 @@ # Change Log +## v3.66.0 - Jan 11, 2024 + +* Allows to set a display name to game objects. +* The display name formatting expression #{x} expands to "x". +* The display name formatting shows prepends the `TargetActionComp.target` value, if present. +* Fixes name collision when copying a game objects tree. +* Fixes duplicating children objects on a tree copy/paste. +* Fixes getting user components of nested prefabs. +* Allows user component object formatting. +* Allow read-only editors. +* Set read-only to editors of node_module files. + ## v3.65.0 - Dec 13, 2024 * Allows using prefabs and user components from node modules. diff --git a/source/editor/plugins/colibri/src/ui/controls/TabPane.ts b/source/editor/plugins/colibri/src/ui/controls/TabPane.ts index cee1ea58e..754bb91cc 100644 --- a/source/editor/plugins/colibri/src/ui/controls/TabPane.ts +++ b/source/editor/plugins/colibri/src/ui/controls/TabPane.ts @@ -509,6 +509,18 @@ namespace colibri.ui.controls { } } + setTabReadOnly(labelElement: HTMLElement, readOnly: boolean) { + + if (readOnly) { + + labelElement.classList.add("ReadOnly"); + + } else { + + labelElement.classList.remove("ReadOnly"); + } + } + closeTab(content: controls.Control) { const label = this.getLabelFromContent(content); diff --git a/source/editor/plugins/colibri/src/ui/ide/EditorPart.ts b/source/editor/plugins/colibri/src/ui/ide/EditorPart.ts index e21a4a653..3d253b89a 100644 --- a/source/editor/plugins/colibri/src/ui/ide/EditorPart.ts +++ b/source/editor/plugins/colibri/src/ui/ide/EditorPart.ts @@ -6,6 +6,7 @@ namespace colibri.ui.ide { private _input: IEditorInput; private _dirty: boolean; + private _readOnly: boolean; private _embeddedMode: boolean; private _editorFactory: EditorFactory; @@ -21,6 +22,24 @@ namespace colibri.ui.ide { this._editorFactory = factory; } + setReadOnly(readOnly: boolean) { + + this._readOnly = readOnly; + + if (this.isInEditorArea()) { + + const folder = this.getPartFolder(); + const label = folder.getLabelFromContent(this); + + folder.setTabReadOnly(label, this._readOnly); + } + } + + isReadOnly() { + + return this._readOnly; + } + getEditorFactory() { return this._editorFactory; @@ -66,6 +85,13 @@ namespace colibri.ui.ide { async save() { + if (this.isReadOnly()) { + + alert("Cannot save, the editor is in read-only mode.'"); + + return; + } + await this.doSave(); } diff --git a/source/editor/plugins/colibri/src/ui/ide/FileEditorInputExtension.ts b/source/editor/plugins/colibri/src/ui/ide/FileEditorInputExtension.ts index ea736be18..d17a55f6c 100644 --- a/source/editor/plugins/colibri/src/ui/ide/FileEditorInputExtension.ts +++ b/source/editor/plugins/colibri/src/ui/ide/FileEditorInputExtension.ts @@ -18,10 +18,12 @@ namespace colibri.ui.ide { } createEditorInput(state: any): IEditorInput { + return colibri.ui.ide.FileUtils.getFileFromPath(state.filePath); } getEditorInputId(input: core.io.FilePath): string { + return input.getFullName(); } } diff --git a/source/editor/plugins/colibri/styles/controls.css b/source/editor/plugins/colibri/styles/controls.css index a1de56190..f03fe35c7 100644 --- a/source/editor/plugins/colibri/styles/controls.css +++ b/source/editor/plugins/colibri/styles/controls.css @@ -137,6 +137,9 @@ padding-bottom: 5px; } + .TabPaneLabel.ReadOnly span { + opacity: 0.5; + } .TabPaneLabel span { margin: 3px 0px 0px 3px; diff --git a/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts b/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts index b09a4036c..cafcc9916 100644 --- a/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts +++ b/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts @@ -77,6 +77,16 @@ namespace phasereditor2d.ide { reg.addExtension(new ui.viewers.LibraryFileStyledLabelProviderExtension()); phasereditor2d.files.FilesPlugin.getInstance().setOpenFileAction(file => this.openFileFromFilesView(file)); + + colibri.Platform.getWorkbench().eventEditorActivated.addListener(editor => { + + const file = editor.getInput(); + + if (file instanceof colibri.core.io.FilePath) { + + editor.setReadOnly(ide.core.code.isNodeLibraryFile(file)); + } + }); } async compileProject() { diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/json/IObjectData.ts b/source/editor/plugins/phasereditor2d.scene/src/core/json/IObjectData.ts index cbe2dea5c..890a3a9e7 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/json/IObjectData.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/json/IObjectData.ts @@ -6,6 +6,7 @@ namespace phasereditor2d.scene.core.json { prefabId?: string; components?: string[], label: string; + displayName?: string; unlock?: string[]; scope?: ui.sceneobjects.ObjectScope; private_np?: boolean; diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts index bda924be4..a59d1b40d 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts @@ -480,7 +480,10 @@ namespace phasereditor2d.scene.core.json { if (file) { - result.push(file); + if (!this.isNestedPrefab(prefabId)) { + + result.push(file); + } const objData = this.getPrefabData(prefabId); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts index 59bbd3f2a..5486ea756 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts @@ -80,15 +80,15 @@ namespace phasereditor2d.scene.ui { const selection = alternativeSelection || this._editorScene.getEditor().getSelectedGameObjects(); - const areDropingScriptNodes = dropObjects.filter(obj => obj instanceof sceneobjects.ScriptNode).length === dropObjects.length; + const areDroppingScriptNodes = dropObjects.filter(obj => obj instanceof sceneobjects.ScriptNode).length === dropObjects.length; for (const sprite of selection) { - const dropTarget = areDropingScriptNodes ? this.findDropScriptTargetParent(sprite) : this.findDropTargetParent(sprite); + const dropTarget = areDroppingScriptNodes ? this.findDropScriptTargetParent(sprite) : this.findDropTargetParent(sprite); if (dropTarget) { - if (areDropingScriptNodes) { + if (areDroppingScriptNodes) { dropInObj = dropTarget; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ClipboardManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ClipboardManager.ts index 2670fc6b6..0ffafd9b8 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ClipboardManager.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ClipboardManager.ts @@ -91,9 +91,38 @@ namespace phasereditor2d.scene.ui.editor { const p = new Phaser.Math.Vector2(); - const gameObjects = this._editor.getSelectedGameObjects(); + const selection = new Set(this._editor.getSelectedGameObjects()); - for (const obj of gameObjects) { + const copyObjects: sceneobjects.ISceneGameObject[] = []; + + // filter off the children of selected parents + + for(const obj of selection) { + + let include = true; + + const objES = obj.getEditorSupport(); + + const parents = objES.getAllParents(); + + for(const parent of parents) { + + if (selection.has(parent)) { + + include = false; + break; + } + } + + if (include) { + + copyObjects.push(obj); + } + } + + // record game objects positions + + for (const obj of copyObjects) { const sprite = obj as unknown as Phaser.GameObjects.Sprite; @@ -111,7 +140,9 @@ namespace phasereditor2d.scene.ui.editor { minY = Math.min(minY, p.y); } - for (const obj of gameObjects) { + // serialize objects + + for (const obj of copyObjects) { const objData = {} as any; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts index 9e1a76629..63972935e 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts @@ -71,18 +71,15 @@ namespace phasereditor2d.scene.ui.editor { const selection = this._editor.getSelection(); - const gameObjectsSet = new Set(selection.filter(obj => sceneobjects.isGameObject(obj))); - for (const obj of selection) { ctx.save(); const isGameObject = sceneobjects.isGameObject(obj); - const isUserCompNode = obj instanceof sceneobjects.UserComponentNode - && !gameObjectsSet.has(obj.getObject()); + const isUserCompNode = obj instanceof sceneobjects.UserComponentNode; - const isScriptNode = obj instanceof sceneobjects.ScriptNode && !gameObjectsSet.has(obj.getParentDisplayObject()); + const isScriptNode = obj instanceof sceneobjects.ScriptNode; const isNonDisplayObject = isUserCompNode || isScriptNode; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/properties/DynamicUserSectionExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/properties/DynamicUserSectionExtension.ts index 5137c82ac..4a7111fbd 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/properties/DynamicUserSectionExtension.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/properties/DynamicUserSectionExtension.ts @@ -9,7 +9,7 @@ namespace phasereditor2d.scene.ui.editor.properties { const result: GetPropertySection[] = []; - const visitedPrefabs = new Set(); + const visitedPrefabs = new Set(); const visitedComps = new Set(); const finder = ScenePlugin.getInstance().getSceneFinder(); @@ -35,6 +35,7 @@ namespace phasereditor2d.scene.ui.editor.properties { } } + // add properties from prefab for (const obj of editor.getSelectedGameObjects()) { @@ -45,14 +46,14 @@ namespace phasereditor2d.scene.ui.editor.properties { continue; } - const prefabFile = objES.getPrefabFile(); + const prefabId = objES.getPrefabId(); - if (visitedPrefabs.has(prefabFile)) { + if (visitedPrefabs.has(prefabId)) { continue; } - visitedPrefabs.add(prefabFile); + visitedPrefabs.add(prefabId); const prefabUserProps = objES.getComponent(sceneobjects.PrefabUserPropertyComponent) as sceneobjects.PrefabUserPropertyComponent; const prefabInfoList = prefabUserProps.getPropertiesByPrefab(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/PasteOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/PasteOperation.ts index 984a8d940..f87807b78 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/PasteOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/PasteOperation.ts @@ -35,7 +35,7 @@ namespace phasereditor2d.scene.ui.editor.undo { await this.pastePlainObjects(items, sel); - this.pastePrefaProperties(items, sel); + this.pastePrefabProperties(items, sel); this._editor.setSelection(sel); } @@ -56,7 +56,7 @@ namespace phasereditor2d.scene.ui.editor.undo { this.setNewObjectId(data); - const obj =scene.readPlainObject(data); + const obj = scene.readPlainObject(data); if (obj) { @@ -76,7 +76,7 @@ namespace phasereditor2d.scene.ui.editor.undo { } } - private pastePrefaProperties(clipboardItems: IClipboardItem[], sel: any[]) { + private pastePrefabProperties(clipboardItems: IClipboardItem[], sel: any[]) { const scene = this._editor.getScene(); @@ -169,16 +169,28 @@ namespace phasereditor2d.scene.ui.editor.undo { for (const newObj of sprites) { - const oldLabel = newObj.getEditorSupport().getLabel(); - - const newLabel = nameMaker.makeName(oldLabel); - - newObj.getEditorSupport().setLabel(newLabel); + this.updateGameObjectName(newObj, nameMaker); } maker.afterDropObjects(prefabObj, sprites); } + private updateGameObjectName(obj: sceneobjects.ISceneGameObject, nameMaker: colibri.ui.ide.utils.NameMaker) { + + const objES = obj.getEditorSupport(); + + const oldLabel = objES.getLabel(); + + const newLabel = nameMaker.makeName(oldLabel); + + objES.setLabel(newLabel); + + for(const child of objES.getAppendedChildren()) { + + this.updateGameObjectName(child, nameMaker); + } + } + private setNewObjectId(data: json.IObjectData) { data.id = Phaser.Utils.String.UUID(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponent.ts index 549ea99c6..b6adc3c0a 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponent.ts @@ -6,6 +6,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent { private _name: string; private _displayName: string; + private _objectDisplayFormat: string; private _baseClass: string; private _gameObjectType: string; private _properties: sceneobjects.UserPropertiesManager; @@ -15,6 +16,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent { this._name = name; this._baseClass = ""; this._displayName = ""; + this._objectDisplayFormat = ""; this._gameObjectType = "Phaser.GameObjects.Image"; this._properties = new UserComponentProperties(this); } @@ -27,6 +29,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent { const data = { name: this._name, displayName: this._displayName, + objectDisplayFormat: this._objectDisplayFormat, baseClass: this._baseClass, gameObjectType: this._gameObjectType, properties: propsData @@ -39,6 +42,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent { this._name = data.name; this._displayName = read(data, "displayName", ""); + this._objectDisplayFormat = read(data, "objectDisplayFormat", ""); this._baseClass = read(data, "baseClass", ""); this._gameObjectType = read(data, "gameObjectType", "Phaser.GameObjects.Image"); this._properties.readJSON(data.properties); @@ -54,6 +58,16 @@ namespace phasereditor2d.scene.ui.editor.usercomponent { this._name = name; } + getObjectDisplayFormat() { + + return this._objectDisplayFormat; + } + + setObjectDisplayFormat(objectDisplayFormat: string) { + + this._objectDisplayFormat = objectDisplayFormat; + } + getDisplayName() { return this._displayName; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponentSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponentSection.ts index 69ce454e3..8751cdd3e 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponentSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponentSection.ts @@ -41,6 +41,8 @@ namespace phasereditor2d.scene.ui.editor.usercomponent { this.stringProp(comp, "BaseClass", "Super Class", "Name of the super class of the component. It is optional.", () => this.createSuperClassOptions()); this.stringProp(comp, "DisplayName", "Display Name", "The display name of the component."); + + this.stringProp(comp, "ObjectDisplayFormat", "Object Display Format", "The display name format to show in prefab instances."); const op = ( action: editor.properties.TUserPropertiesAction) => { @@ -119,7 +121,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent { this.addUpdater(() => { text.value = this.flatValues_StringOneOrNothing( - this.getSelection().map(c => c["get" + prop]())); + this.getSelection().map(c => c["get" + prop]() || "")); }); if (options) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/EditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/EditorSupport.ts index 84a9f3cc0..012482689 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/EditorSupport.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/EditorSupport.ts @@ -6,6 +6,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { private _object: T; private _label: string; + private _displayName: string; private _useGameObjectName: boolean; private _scope: ObjectScope; private _scene: Scene; @@ -15,6 +16,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { this._object = obj; this._scene = scene; this._label = label; + this._displayName = ""; this._useGameObjectName = false; this._scope = ObjectScope.LOCAL; @@ -36,7 +38,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { return null; } - abstract destroy(); + abstract destroy(): void; abstract buildDependencyHash(args: IBuildDependencyHashArgs): Promise; @@ -98,6 +100,16 @@ namespace phasereditor2d.scene.ui.sceneobjects { this._label = label; } + getDisplayName() { + + return this._displayName; + } + + setDisplayName(displayName: string) { + + this._displayName = displayName; + } + isUseGameObjectName() { return this._useGameObjectName; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Utils.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Utils.ts index 4f2d3c546..0c60c2dcc 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Utils.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Utils.ts @@ -22,17 +22,17 @@ namespace phasereditor2d.scene.ui.sceneobjects { const finder = ScenePlugin.getInstance().getSceneFinder(); - if (objES.isPrefabInstance() && !objES.isNestedPrefabDefined()) { + if (objES.isPrefabInstance()) { - const hierarchy = finder.getPrefabHierarchy(objES.getPrefabId()); + let hierarchy = finder.getPrefabHierarchy(objES.getPrefabId()); for (const prefabFile of hierarchy) { - const { prefabObjDisplayFmt: displayFormat } = finder.getSceneSettings(prefabFile); + const { prefabObjDisplayFmt } = finder.getSceneSettings(prefabFile); - if (displayFormat !== undefined && displayFormat.trim().length > 0) { + if (prefabObjDisplayFmt !== undefined && prefabObjDisplayFmt.trim().length > 0) { - return displayFormat; + return prefabObjDisplayFmt; } } } @@ -40,20 +40,105 @@ namespace phasereditor2d.scene.ui.sceneobjects { return undefined; } + function getNestedPrefabDisplayName(prefabId: string) { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const data = finder.getPrefabData(prefabId); + + if (data) { + + if (data.displayName) { + + return data.displayName; + } + + if (finder.isNestedPrefab(data.prefabId)) { + + return getNestedPrefabDisplayName(data.prefabId); + } + } + + return undefined; + } + export function formatObjectDisplayText(obj: ISceneGameObject): string { + const objES = obj.getEditorSupport(); + + if (objES.getDisplayName()) { + + return objES.getDisplayName(); + } + + if (objES.isNestedPrefabInstance()) { + + const displayName = getNestedPrefabDisplayName(objES.getPrefabId()); + + if (displayName) { + + return displayName; + } + } + const displayFormat = findObjectDisplayFormat(obj); if (displayFormat) { - return applyFormat(obj, displayFormat); - } + let prefix = getTargetActionDisplayNamePrefix(objES, obj); - const objES = obj.getEditorSupport(); + return prefix + applyFormat(obj, displayFormat); + } return objES.getLabel(); } + function getTargetActionDisplayNamePrefix(objES: GameObjectEditorSupport, obj: ISceneGameObject) { + + let prefix = ""; + + const targetActionComp = objES.getUserComponentsComponent() + .getUserComponentNodes() + .find(n => n.getComponentName() === "ActionTargetComp"); + + if (targetActionComp) { + + const props = targetActionComp.getUserComponent() + .getUserProperties(); + + const targetProp = props.findPropertyByName("target"); + const targetNameProp = props.findPropertyByName("targetName"); + + let value = ""; + + if (targetProp) { + + const target = targetProp.getComponentProperty().getValue(obj); + + if (target) { + + value = target; + } + } + + if (targetNameProp) { + + const name = targetNameProp.getComponentProperty().getValue(obj); + + if (name) { + + value += " " + name; + } + } + + if (value) { + + prefix = value + " → "; + } + } + return prefix; + } + function applyFormat(obj: ISceneGameObject, displayFormat: string) { const objES = obj.getEditorSupport(); @@ -62,30 +147,60 @@ namespace phasereditor2d.scene.ui.sceneobjects { label: objES.getLabel() }; - // from user components + // from prefabs { - const comp = objES.getUserComponentsComponent(); + const comp = objES.getComponent(PrefabUserPropertyComponent) as PrefabUserPropertyComponent; const props = comp.getProperties(); for (const prop of props) { - data[prop.codeName] = prop.getValue(obj); + data[prop.name] = prop.getValue(obj); } } - // from prefabs + // from user components + let componentsSuffix = ""; { - const comp = objES.getComponent(PrefabUserPropertyComponent) as PrefabUserPropertyComponent; + const components = objES.getUserComponentsComponent(); - const props = comp.getProperties(); + const props = components.getProperties(); for (const prop of props) { - data[prop.name] = prop.getValue(obj); + data[prop.codeName] = prop.getValue(obj); + } + + for(const node of components.getUserComponentNodes()) { + + const comp = node.getUserComponent(); + + const format = comp.getObjectDisplayFormat(); + + if (format) { + + const compData = {}; + + for(const userProp of comp.getUserProperties().getProperties()) { + + const prop = userProp.getComponentProperty(); + + const value = prop.getValue(obj); + + compData[prop.codeName] = value; + } + + componentsSuffix += ", " + formatString(format, compData); + } } } + const output = formatString(displayFormat, data) + componentsSuffix; + + return output; + } + + function formatString(displayFormat: string, data: any) { let output = displayFormat.replace(/\${(.*?)}/g, (match, p1) => { const variableValue = data[p1.trim()]; @@ -99,11 +214,10 @@ namespace phasereditor2d.scene.ui.sceneobjects { const variableValue = data[k]; - return Boolean(variableValue) ? "#" + k : ""; + return Boolean(variableValue) ? `"${k}"` : ""; }); output = output.replace(/ +/g, " ").trim(); - return output; } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts index e63e54a40..f148902a4 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts @@ -43,6 +43,15 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (objES.isPrefabInstance()) { + // get all from the nested prefabs chain + + if (objES.isNestedPrefabInstance()) { + + this.getNestedPrefabProperties(propertiesInObject, objES.getPrefabId()); + } + + // get all from non-nested prefab hierarchy + const nextPrefabId = finder.getFirstNonNestedPrefabId(objES.getPrefabId()); if (nextPrefabId) { @@ -59,6 +68,28 @@ namespace phasereditor2d.scene.ui.sceneobjects { return propertiesInObject; } + private getNestedPrefabProperties(propertiesInObject: IUserPropertiesInObject[], + nestedPrefabId: string) { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const prefabFile = finder.getPrefabFile(nestedPrefabId); + + propertiesInObject.push({ + prefabFile, + properties: [] + }); + + const data = finder.getPrefabData(nestedPrefabId); + + nestedPrefabId = data.prefabId; + + if (nestedPrefabId && finder.isNestedPrefab(nestedPrefabId)) { + + this.getNestedPrefabProperties(propertiesInObject, data.prefabId); + } + } + private getPrefabProperties(propertiesInObject: IUserPropertiesInObject[], prefabFile: io.FilePath) { const finder = ScenePlugin.getInstance().getSceneFinder(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/UserComponentsEditorComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/UserComponentsEditorComponent.ts index 0e0e86e65..019528218 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/UserComponentsEditorComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/UserComponentsEditorComponent.ts @@ -282,23 +282,13 @@ namespace phasereditor2d.scene.ui.sceneobjects { getPrefabUserComponents(): IUserComponentAndPrefab[] { - const finder = ScenePlugin.getInstance().getSceneFinder(); - const result: IUserComponentAndPrefab[] = []; - const support = this.getObject().getEditorSupport(); - - if (support.isPrefabInstance()) { - - const objData = finder.getPrefabData(support.getPrefabId()); + const objES = this.getObject().getEditorSupport(); - if (objData) { - - if (objData.components) { + if (objES.isPrefabInstance()) { - this.getUserComponentsOfPrefab(support.getPrefabId(), result); - } - } + this.getUserComponentsOfPrefab(objES.getPrefabId(), result); } return result; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/VariableComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/VariableComponent.ts index 795ab3c72..c7f661b06 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/VariableComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/VariableComponent.ts @@ -14,6 +14,15 @@ namespace phasereditor2d.scene.ui.sceneobjects { setValue: (obj, value) => obj.getEditorSupport().setLabel(value) }; + static displayName: IProperty = { + name: "displayName", + tooltip: "The name to show in the UI.", + defValue: "", + local: true, + getValue: obj => obj.getEditorSupport().getDisplayName(), + setValue: (obj, value) => obj.getEditorSupport().setDisplayName(value) + }; + static useGameObjectName: IProperty = { name: "useGameObjectName", label: "GO Name", @@ -38,6 +47,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { constructor(obj: ISceneGameObject) { super(obj, [ VariableComponent.label, + VariableComponent.displayName, VariableComponent.useGameObjectName, VariableComponent.scope ]); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/DynamicPrefabInstanceSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/DynamicPrefabInstanceSection.ts index ef24f063d..2a45b536f 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/DynamicPrefabInstanceSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/DynamicPrefabInstanceSection.ts @@ -63,11 +63,11 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (GameObjectEditorSupport.hasEditorSupport(obj2)) { - const editorSupport = GameObjectEditorSupport.getEditorSupport(obj2); + const objES = GameObjectEditorSupport.getEditorSupport(obj2); - if (editorSupport.isPrefabInstance()) { + if (objES.isPrefabInstance()) { - const prefabFiles = finder.getPrefabHierarchy(editorSupport.getPrefabId()); + const prefabFiles = finder.getPrefabHierarchy(objES.getPrefabId()); if (prefabFiles.indexOf(this._prefabFile) >= 0) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts index b542d97f5..540e6d669 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts @@ -42,6 +42,14 @@ namespace phasereditor2d.scene.ui.sceneobjects { this.createStringField(comp, VariableComponent.label, false, true); } + { + // Display Name + + this.createLabel(comp, "Display Name", "The name to display in the UI."); + + this.createStringField(comp, VariableComponent.displayName, false, true); + } + { // GameObject name diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts index 7406a1ef7..9e599b639 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/AbstractDialogPropertyType.ts @@ -226,8 +226,6 @@ namespace phasereditor2d.scene.ui.sceneobjects { formBuilder.createButton(comp, resources.getIcon(resources.ICON_PLAY), () => { - console.log("here"); - previewAction(); }); } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/UserPropertiesManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/UserPropertiesManager.ts index fb0993100..17b3246b3 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/UserPropertiesManager.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/UserPropertiesManager.ts @@ -11,6 +11,11 @@ namespace phasereditor2d.scene.ui.sceneobjects { this._properties = []; } + findPropertyByName(name: string) { + + return this._properties.find(p => p.getName() === name); + } + getProperties() { return this._properties; diff --git a/source/editor/product.json b/source/editor/product.json index 2fb2caf84..647decb4e 100644 --- a/source/editor/product.json +++ b/source/editor/product.json @@ -1,4 +1,4 @@ { "title": "Phaser Editor 2D", - "version": "3.65.0" + "version": "3.66.0" } \ No newline at end of file