Skip to content

Commit 49eee2d

Browse files
Merge branch 'develop'
2 parents 2b09307 + af847bc commit 49eee2d

25 files changed

+356
-62
lines changed

CHANGELOG.MD

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Change Log
22

3+
## v3.66.0 - Jan 11, 2024
4+
5+
* Allows to set a display name to game objects.
6+
* The display name formatting expression #{x} expands to "x".
7+
* The display name formatting shows prepends the `TargetActionComp.target` value, if present.
8+
* Fixes name collision when copying a game objects tree.
9+
* Fixes duplicating children objects on a tree copy/paste.
10+
* Fixes getting user components of nested prefabs.
11+
* Allows user component object formatting.
12+
* Allow read-only editors.
13+
* Set read-only to editors of node_module files.
14+
315
## v3.65.0 - Dec 13, 2024
416

517
* Allows using prefabs and user components from node modules.

source/editor/plugins/colibri/src/ui/controls/TabPane.ts

+12
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,18 @@ namespace colibri.ui.controls {
509509
}
510510
}
511511

512+
setTabReadOnly(labelElement: HTMLElement, readOnly: boolean) {
513+
514+
if (readOnly) {
515+
516+
labelElement.classList.add("ReadOnly");
517+
518+
} else {
519+
520+
labelElement.classList.remove("ReadOnly");
521+
}
522+
}
523+
512524
closeTab(content: controls.Control) {
513525

514526
const label = this.getLabelFromContent(content);

source/editor/plugins/colibri/src/ui/ide/EditorPart.ts

+26
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace colibri.ui.ide {
66

77
private _input: IEditorInput;
88
private _dirty: boolean;
9+
private _readOnly: boolean;
910
private _embeddedMode: boolean;
1011
private _editorFactory: EditorFactory;
1112

@@ -21,6 +22,24 @@ namespace colibri.ui.ide {
2122
this._editorFactory = factory;
2223
}
2324

25+
setReadOnly(readOnly: boolean) {
26+
27+
this._readOnly = readOnly;
28+
29+
if (this.isInEditorArea()) {
30+
31+
const folder = this.getPartFolder();
32+
const label = folder.getLabelFromContent(this);
33+
34+
folder.setTabReadOnly(label, this._readOnly);
35+
}
36+
}
37+
38+
isReadOnly() {
39+
40+
return this._readOnly;
41+
}
42+
2443
getEditorFactory() {
2544

2645
return this._editorFactory;
@@ -66,6 +85,13 @@ namespace colibri.ui.ide {
6685

6786
async save() {
6887

88+
if (this.isReadOnly()) {
89+
90+
alert("Cannot save, the editor is in read-only mode.'");
91+
92+
return;
93+
}
94+
6995
await this.doSave();
7096
}
7197

source/editor/plugins/colibri/src/ui/ide/FileEditorInputExtension.ts

+2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ namespace colibri.ui.ide {
1818
}
1919

2020
createEditorInput(state: any): IEditorInput {
21+
2122
return colibri.ui.ide.FileUtils.getFileFromPath(state.filePath);
2223
}
2324

2425
getEditorInputId(input: core.io.FilePath): string {
26+
2527
return input.getFullName();
2628
}
2729
}

source/editor/plugins/colibri/styles/controls.css

+3
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@
137137
padding-bottom: 5px;
138138
}
139139

140+
.TabPaneLabel.ReadOnly span {
141+
opacity: 0.5;
142+
}
140143

141144
.TabPaneLabel span {
142145
margin: 3px 0px 0px 3px;

source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts

+10
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ namespace phasereditor2d.ide {
7777
reg.addExtension(new ui.viewers.LibraryFileStyledLabelProviderExtension());
7878

7979
phasereditor2d.files.FilesPlugin.getInstance().setOpenFileAction(file => this.openFileFromFilesView(file));
80+
81+
colibri.Platform.getWorkbench().eventEditorActivated.addListener(editor => {
82+
83+
const file = editor.getInput();
84+
85+
if (file instanceof colibri.core.io.FilePath) {
86+
87+
editor.setReadOnly(ide.core.code.isNodeLibraryFile(file));
88+
}
89+
});
8090
}
8191

8292
async compileProject() {

source/editor/plugins/phasereditor2d.scene/src/core/json/IObjectData.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace phasereditor2d.scene.core.json {
66
prefabId?: string;
77
components?: string[],
88
label: string;
9+
displayName?: string;
910
unlock?: string[];
1011
scope?: ui.sceneobjects.ObjectScope;
1112
private_np?: boolean;

source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,10 @@ namespace phasereditor2d.scene.core.json {
480480

481481
if (file) {
482482

483-
result.push(file);
483+
if (!this.isNestedPrefab(prefabId)) {
484+
485+
result.push(file);
486+
}
484487

485488
const objData = this.getPrefabData(prefabId);
486489

source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ namespace phasereditor2d.scene.ui {
8080
const selection = alternativeSelection
8181
|| this._editorScene.getEditor().getSelectedGameObjects();
8282

83-
const areDropingScriptNodes = dropObjects.filter(obj => obj instanceof sceneobjects.ScriptNode).length === dropObjects.length;
83+
const areDroppingScriptNodes = dropObjects.filter(obj => obj instanceof sceneobjects.ScriptNode).length === dropObjects.length;
8484

8585
for (const sprite of selection) {
8686

87-
const dropTarget = areDropingScriptNodes ? this.findDropScriptTargetParent(sprite) : this.findDropTargetParent(sprite);
87+
const dropTarget = areDroppingScriptNodes ? this.findDropScriptTargetParent(sprite) : this.findDropTargetParent(sprite);
8888

8989
if (dropTarget) {
9090

91-
if (areDropingScriptNodes) {
91+
if (areDroppingScriptNodes) {
9292

9393
dropInObj = dropTarget;
9494

source/editor/plugins/phasereditor2d.scene/src/ui/editor/ClipboardManager.ts

+34-3
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,38 @@ namespace phasereditor2d.scene.ui.editor {
9191

9292
const p = new Phaser.Math.Vector2();
9393

94-
const gameObjects = this._editor.getSelectedGameObjects();
94+
const selection = new Set(this._editor.getSelectedGameObjects());
9595

96-
for (const obj of gameObjects) {
96+
const copyObjects: sceneobjects.ISceneGameObject[] = [];
97+
98+
// filter off the children of selected parents
99+
100+
for(const obj of selection) {
101+
102+
let include = true;
103+
104+
const objES = obj.getEditorSupport();
105+
106+
const parents = objES.getAllParents();
107+
108+
for(const parent of parents) {
109+
110+
if (selection.has(parent)) {
111+
112+
include = false;
113+
break;
114+
}
115+
}
116+
117+
if (include) {
118+
119+
copyObjects.push(obj);
120+
}
121+
}
122+
123+
// record game objects positions
124+
125+
for (const obj of copyObjects) {
97126

98127
const sprite = obj as unknown as Phaser.GameObjects.Sprite;
99128

@@ -111,7 +140,9 @@ namespace phasereditor2d.scene.ui.editor {
111140
minY = Math.min(minY, p.y);
112141
}
113142

114-
for (const obj of gameObjects) {
143+
// serialize objects
144+
145+
for (const obj of copyObjects) {
115146

116147
const objData = {} as any;
117148

source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,15 @@ namespace phasereditor2d.scene.ui.editor {
7171

7272
const selection = this._editor.getSelection();
7373

74-
const gameObjectsSet = new Set(selection.filter(obj => sceneobjects.isGameObject(obj)));
75-
7674
for (const obj of selection) {
7775

7876
ctx.save();
7977

8078
const isGameObject = sceneobjects.isGameObject(obj);
8179

82-
const isUserCompNode = obj instanceof sceneobjects.UserComponentNode
83-
&& !gameObjectsSet.has(obj.getObject());
80+
const isUserCompNode = obj instanceof sceneobjects.UserComponentNode;
8481

85-
const isScriptNode = obj instanceof sceneobjects.ScriptNode && !gameObjectsSet.has(obj.getParentDisplayObject());
82+
const isScriptNode = obj instanceof sceneobjects.ScriptNode;
8683

8784
const isNonDisplayObject = isUserCompNode || isScriptNode;
8885

source/editor/plugins/phasereditor2d.scene/src/ui/editor/properties/DynamicUserSectionExtension.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace phasereditor2d.scene.ui.editor.properties {
99

1010
const result: GetPropertySection[] = [];
1111

12-
const visitedPrefabs = new Set<io.FilePath>();
12+
const visitedPrefabs = new Set<string>();
1313
const visitedComps = new Set<string>();
1414

1515
const finder = ScenePlugin.getInstance().getSceneFinder();
@@ -35,6 +35,7 @@ namespace phasereditor2d.scene.ui.editor.properties {
3535
}
3636
}
3737

38+
// add properties from prefab
3839

3940
for (const obj of editor.getSelectedGameObjects()) {
4041

@@ -45,14 +46,14 @@ namespace phasereditor2d.scene.ui.editor.properties {
4546
continue;
4647
}
4748

48-
const prefabFile = objES.getPrefabFile();
49+
const prefabId = objES.getPrefabId();
4950

50-
if (visitedPrefabs.has(prefabFile)) {
51+
if (visitedPrefabs.has(prefabId)) {
5152

5253
continue;
5354
}
5455

55-
visitedPrefabs.add(prefabFile);
56+
visitedPrefabs.add(prefabId);
5657

5758
const prefabUserProps = objES.getComponent(sceneobjects.PrefabUserPropertyComponent) as sceneobjects.PrefabUserPropertyComponent;
5859
const prefabInfoList = prefabUserProps.getPropertiesByPrefab();

source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/PasteOperation.ts

+20-8
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace phasereditor2d.scene.ui.editor.undo {
3535

3636
await this.pastePlainObjects(items, sel);
3737

38-
this.pastePrefaProperties(items, sel);
38+
this.pastePrefabProperties(items, sel);
3939

4040
this._editor.setSelection(sel);
4141
}
@@ -56,7 +56,7 @@ namespace phasereditor2d.scene.ui.editor.undo {
5656

5757
this.setNewObjectId(data);
5858

59-
const obj =scene.readPlainObject(data);
59+
const obj = scene.readPlainObject(data);
6060

6161
if (obj) {
6262

@@ -76,7 +76,7 @@ namespace phasereditor2d.scene.ui.editor.undo {
7676
}
7777
}
7878

79-
private pastePrefaProperties(clipboardItems: IClipboardItem[], sel: any[]) {
79+
private pastePrefabProperties(clipboardItems: IClipboardItem[], sel: any[]) {
8080

8181
const scene = this._editor.getScene();
8282

@@ -169,16 +169,28 @@ namespace phasereditor2d.scene.ui.editor.undo {
169169

170170
for (const newObj of sprites) {
171171

172-
const oldLabel = newObj.getEditorSupport().getLabel();
173-
174-
const newLabel = nameMaker.makeName(oldLabel);
175-
176-
newObj.getEditorSupport().setLabel(newLabel);
172+
this.updateGameObjectName(newObj, nameMaker);
177173
}
178174

179175
maker.afterDropObjects(prefabObj, sprites);
180176
}
181177

178+
private updateGameObjectName(obj: sceneobjects.ISceneGameObject, nameMaker: colibri.ui.ide.utils.NameMaker) {
179+
180+
const objES = obj.getEditorSupport();
181+
182+
const oldLabel = objES.getLabel();
183+
184+
const newLabel = nameMaker.makeName(oldLabel);
185+
186+
objES.setLabel(newLabel);
187+
188+
for(const child of objES.getAppendedChildren()) {
189+
190+
this.updateGameObjectName(child, nameMaker);
191+
}
192+
}
193+
182194
private setNewObjectId(data: json.IObjectData) {
183195

184196
data.id = Phaser.Utils.String.UUID();

source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponent.ts

+14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent {
66

77
private _name: string;
88
private _displayName: string;
9+
private _objectDisplayFormat: string;
910
private _baseClass: string;
1011
private _gameObjectType: string;
1112
private _properties: sceneobjects.UserPropertiesManager;
@@ -15,6 +16,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent {
1516
this._name = name;
1617
this._baseClass = "";
1718
this._displayName = "";
19+
this._objectDisplayFormat = "";
1820
this._gameObjectType = "Phaser.GameObjects.Image";
1921
this._properties = new UserComponentProperties(this);
2022
}
@@ -27,6 +29,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent {
2729
const data = {
2830
name: this._name,
2931
displayName: this._displayName,
32+
objectDisplayFormat: this._objectDisplayFormat,
3033
baseClass: this._baseClass,
3134
gameObjectType: this._gameObjectType,
3235
properties: propsData
@@ -39,6 +42,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent {
3942

4043
this._name = data.name;
4144
this._displayName = read(data, "displayName", "");
45+
this._objectDisplayFormat = read(data, "objectDisplayFormat", "");
4246
this._baseClass = read(data, "baseClass", "");
4347
this._gameObjectType = read(data, "gameObjectType", "Phaser.GameObjects.Image");
4448
this._properties.readJSON(data.properties);
@@ -54,6 +58,16 @@ namespace phasereditor2d.scene.ui.editor.usercomponent {
5458
this._name = name;
5559
}
5660

61+
getObjectDisplayFormat() {
62+
63+
return this._objectDisplayFormat;
64+
}
65+
66+
setObjectDisplayFormat(objectDisplayFormat: string) {
67+
68+
this._objectDisplayFormat = objectDisplayFormat;
69+
}
70+
5771
getDisplayName() {
5872

5973
return this._displayName;

source/editor/plugins/phasereditor2d.scene/src/ui/editor/usercomponent/UserComponentSection.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ namespace phasereditor2d.scene.ui.editor.usercomponent {
4141
this.stringProp(comp, "BaseClass", "Super Class", "Name of the super class of the component. It is optional.", () => this.createSuperClassOptions());
4242

4343
this.stringProp(comp, "DisplayName", "Display Name", "The display name of the component.");
44+
45+
this.stringProp(comp, "ObjectDisplayFormat", "Object Display Format", "The display name format to show in prefab instances.");
4446

4547
const op = (
4648
action: editor.properties.TUserPropertiesAction) => {
@@ -119,7 +121,7 @@ namespace phasereditor2d.scene.ui.editor.usercomponent {
119121
this.addUpdater(() => {
120122

121123
text.value = this.flatValues_StringOneOrNothing(
122-
this.getSelection().map(c => c["get" + prop]()));
124+
this.getSelection().map(c => c["get" + prop]() || ""));
123125
});
124126

125127
if (options) {

0 commit comments

Comments
 (0)