@node-projects/web-component-designer-visualization-addons 0.1.144 → 0.1.146
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/EventAssignment.d.ts +3 -1
- package/dist/components/EventAssignment.js +7 -2
- package/dist/components/SimpleScriptCommandPicker.d.ts +25 -0
- package/dist/components/SimpleScriptCommandPicker.js +271 -0
- package/dist/components/SimpleScriptEditor.d.ts +21 -5
- package/dist/components/SimpleScriptEditor.js +533 -137
- package/dist/components/SimpleScriptEditorHelp.d.ts +1 -0
- package/dist/components/SimpleScriptEditorHelp.js +151 -0
- package/dist/helpers/BindingsHelper.js +9 -1
- package/dist/index-min.js +577 -57
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/interfaces/VisualizationShell.d.ts +11 -0
- package/dist/scripting/JsonSnippetHighlighter.d.ts +3 -0
- package/dist/scripting/JsonSnippetHighlighter.js +16 -0
- package/dist/scripting/ScriptCommandsDescriptions.d.ts +9 -0
- package/dist/scripting/ScriptCommandsDescriptions.js +154 -0
- package/package.json +3 -3
|
@@ -1,80 +1,341 @@
|
|
|
1
|
-
import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
|
|
2
|
-
import { ContextMenu } from "@node-projects/web-component-designer";
|
|
3
|
-
import { typeInfoFromJsonSchema } from "@node-projects/propertygrid.webcomponent";
|
|
1
|
+
import { BaseCustomWebComponentConstructorAppend, TypedEvent, css, html, } from "@node-projects/base-custom-webcomponent";
|
|
2
|
+
import { ContextMenu, assetsPath, } from "@node-projects/web-component-designer";
|
|
3
|
+
import { typeInfoFromJsonSchema, } from "@node-projects/propertygrid.webcomponent";
|
|
4
4
|
import { defaultOptions } from "@node-projects/web-component-designer-widgets-wunderbaum";
|
|
5
|
-
import { Wunderbaum } from
|
|
5
|
+
import { Wunderbaum } from "wunderbaum";
|
|
6
6
|
//@ts-ignore
|
|
7
|
-
import wunderbaumStyle from
|
|
7
|
+
import wunderbaumStyle from "wunderbaum/dist/wunderbaum.css" with { type: "css" };
|
|
8
8
|
import { VisualizationPropertyGrid } from "./VisualizationPropertyGrid.js";
|
|
9
|
-
import
|
|
9
|
+
import { SimpleScriptCommandPicker } from "./SimpleScriptCommandPicker.js";
|
|
10
|
+
import { simpleScriptEditorHelpHtml } from "./SimpleScriptEditorHelp.js";
|
|
11
|
+
import { nativeScriptCommandDescriptions, } from "../scripting/ScriptCommandsDescriptions.js";
|
|
12
|
+
import "@node-projects/splitview.webcomponent";
|
|
10
13
|
import { ScriptUpgrades } from "../scripting/ScriptUpgrader.js";
|
|
14
|
+
const SAME_TREE_MOVE_MIME = "application/x-simple-script-move";
|
|
11
15
|
export class SimpleScriptEditor extends BaseCustomWebComponentConstructorAppend {
|
|
12
16
|
static style = css `
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.list{
|
|
17
|
-
display: grid;
|
|
18
|
-
grid-template-columns: 1fr 40px;
|
|
19
|
-
width: calc(100% - 6px);
|
|
20
|
-
box-sizing: border-box;
|
|
21
|
-
margin: 3px;
|
|
22
|
-
}
|
|
17
|
+
:host {
|
|
18
|
+
background: white;
|
|
19
|
+
}
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
.root {
|
|
22
|
+
width: 100%;
|
|
23
|
+
height: 100%;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
}
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
.content {
|
|
31
|
+
flex: 1 1 auto;
|
|
32
|
+
min-height: 0;
|
|
33
|
+
position: relative;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.split-view {
|
|
37
|
+
height: calc(100% - 4px);
|
|
38
|
+
width: calc(100% - 4px);
|
|
39
|
+
position: relative;
|
|
40
|
+
margin: 2px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.list-pane {
|
|
44
|
+
width: 48%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
position: relative;
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
display: flex;
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.list-content {
|
|
53
|
+
flex: 1 1 auto;
|
|
54
|
+
min-height: 0;
|
|
55
|
+
position: relative;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.grid-pane {
|
|
59
|
+
width: 52%;
|
|
60
|
+
height: 100%;
|
|
61
|
+
position: relative;
|
|
62
|
+
box-sizing: border-box;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.split-view.code-mode .grid-pane {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.split-view.code-mode::part(splitter) {
|
|
70
|
+
display: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#commandList {
|
|
74
|
+
position: absolute;
|
|
75
|
+
inset: 0;
|
|
76
|
+
overflow-x: hidden;
|
|
77
|
+
overflow-y: auto;
|
|
78
|
+
box-sizing: border-box;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#commandList i.wb-expander,
|
|
82
|
+
#commandList i.wb-indent {
|
|
83
|
+
display: none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#commandList.hidden {
|
|
87
|
+
display: none;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.code-view {
|
|
91
|
+
position: absolute;
|
|
92
|
+
inset: 0;
|
|
93
|
+
display: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.code-view.visible {
|
|
97
|
+
display: block;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
node-projects-visualization-property-grid {
|
|
101
|
+
width: 100%;
|
|
102
|
+
height: 100%;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.toolbar {
|
|
106
|
+
display: flex;
|
|
107
|
+
align-items: center;
|
|
108
|
+
gap: 8px;
|
|
109
|
+
box-sizing: border-box;
|
|
110
|
+
flex: 0 0 auto;
|
|
111
|
+
width: 100%;
|
|
112
|
+
height: 36px;
|
|
113
|
+
padding: 4px 8px;
|
|
114
|
+
border-top: 1px solid #ccc;
|
|
115
|
+
background-color: rgb(230, 230, 230);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.toolbar button {
|
|
119
|
+
box-sizing: border-box;
|
|
120
|
+
padding: 6px 16px;
|
|
121
|
+
border-radius: 4px;
|
|
122
|
+
border: 1px solid #b0b0b0;
|
|
123
|
+
background: white;
|
|
124
|
+
font-size: 12px;
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.toolbar button:hover:not(:disabled) {
|
|
129
|
+
background: #f0f0f0;
|
|
130
|
+
border-color: #909090;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.toolbar button:active:not(:disabled) {
|
|
134
|
+
background: #e2e2e2;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.toolbar button:disabled {
|
|
138
|
+
opacity: 0.5;
|
|
139
|
+
cursor: not-allowed;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.toolbar button.primary {
|
|
143
|
+
background: #2c6e9b;
|
|
144
|
+
border-color: #2c6e9b;
|
|
145
|
+
color: white;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.toolbar button.primary:hover:not(:disabled) {
|
|
149
|
+
background: #255d83;
|
|
150
|
+
border-color: #255d83;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.toolbar button.primary:active:not(:disabled) {
|
|
154
|
+
background: #1e4d6b;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.toolbar .spacer {
|
|
158
|
+
flex: 1 1 auto;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.toolbar .icon-btn {
|
|
162
|
+
display: flex;
|
|
163
|
+
align-items: center;
|
|
164
|
+
justify-content: center;
|
|
165
|
+
width: 22px;
|
|
166
|
+
height: 22px;
|
|
167
|
+
padding: 0;
|
|
168
|
+
box-sizing: border-box;
|
|
169
|
+
border: none;
|
|
170
|
+
background: transparent;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.toolbar .icon-btn:hover {
|
|
175
|
+
background: #eee;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.drag-handle {
|
|
179
|
+
position: absolute;
|
|
180
|
+
left: 0;
|
|
181
|
+
top: 0;
|
|
182
|
+
height: 100%;
|
|
183
|
+
width: 24px;
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
justify-content: center;
|
|
187
|
+
color: #888;
|
|
188
|
+
cursor: grab;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.cmd {
|
|
192
|
+
position: absolute;
|
|
193
|
+
right: 0;
|
|
194
|
+
top: 0;
|
|
195
|
+
height: 100%;
|
|
196
|
+
display: flex;
|
|
197
|
+
align-items: center;
|
|
198
|
+
gap: 2px;
|
|
199
|
+
padding: 0 2px;
|
|
200
|
+
background: white;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.cmd img {
|
|
204
|
+
width: 12px;
|
|
205
|
+
height: 12px;
|
|
206
|
+
cursor: pointer;
|
|
207
|
+
}
|
|
208
|
+
`;
|
|
38
209
|
static template = html `
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
210
|
+
<div class="root">
|
|
211
|
+
<div class="content">
|
|
212
|
+
<node-projects-split-view
|
|
213
|
+
id="splitView"
|
|
214
|
+
class="split-view"
|
|
215
|
+
orientation="horizontal"
|
|
216
|
+
>
|
|
217
|
+
<div id="listPane" class="list-pane">
|
|
218
|
+
<div id="listContent" class="list-content">
|
|
219
|
+
<div id="commandList"></div>
|
|
220
|
+
<node-projects-code-view-monaco
|
|
221
|
+
id="codeView"
|
|
222
|
+
class="code-view"
|
|
223
|
+
language="json"
|
|
224
|
+
></node-projects-code-view-monaco>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="toolbar">
|
|
227
|
+
<button
|
|
228
|
+
id="addCommandBtn"
|
|
229
|
+
class="primary"
|
|
230
|
+
@click="[[this.addCommand()]]"
|
|
231
|
+
>
|
|
232
|
+
Add Command
|
|
233
|
+
</button>
|
|
234
|
+
<button id="codeToggleBtn" @click="[[this.toggleCodeView()]]">
|
|
235
|
+
Code
|
|
236
|
+
</button>
|
|
237
|
+
<span class="spacer"></span>
|
|
238
|
+
<button
|
|
239
|
+
class="icon-btn"
|
|
240
|
+
title="Help"
|
|
241
|
+
@click="[[this.helpClicked()]]"
|
|
242
|
+
>
|
|
243
|
+
<svg viewBox="0 0 512 512" width="16" height="16">
|
|
244
|
+
<path
|
|
245
|
+
d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"
|
|
246
|
+
/>
|
|
247
|
+
</svg>
|
|
248
|
+
</button>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
<div class="grid-pane">
|
|
252
|
+
<node-projects-visualization-property-grid
|
|
253
|
+
id="propertygrid"
|
|
254
|
+
></node-projects-visualization-property-grid>
|
|
255
|
+
</div>
|
|
256
|
+
</node-projects-split-view>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
`;
|
|
260
|
+
static is = "node-projects-visualization-simple-script-editor";
|
|
261
|
+
_title;
|
|
262
|
+
get title() {
|
|
263
|
+
return this._title;
|
|
264
|
+
}
|
|
265
|
+
set title(value) {
|
|
266
|
+
this._title = value;
|
|
267
|
+
}
|
|
57
268
|
serviceContainer;
|
|
58
269
|
instanceServiceContainer;
|
|
59
270
|
visualizationHandler;
|
|
60
271
|
visualizationShell;
|
|
61
272
|
scriptCommandsTypeInfo;
|
|
62
273
|
propertiesTypeInfo;
|
|
274
|
+
helpRequested = new TypedEvent();
|
|
275
|
+
commandDescriptions = {
|
|
276
|
+
...nativeScriptCommandDescriptions,
|
|
277
|
+
};
|
|
63
278
|
_script;
|
|
64
279
|
_commandListDiv;
|
|
65
280
|
_commandListFancyTree;
|
|
66
|
-
_possibleCommands;
|
|
67
281
|
_propertygrid;
|
|
282
|
+
_splitView;
|
|
283
|
+
_codeView;
|
|
284
|
+
_codeToggleBtn;
|
|
285
|
+
_addCommandBtn;
|
|
286
|
+
_showingCode = false;
|
|
287
|
+
_dragFromHandle = false;
|
|
288
|
+
_draggedNode = null;
|
|
68
289
|
constructor() {
|
|
69
290
|
super();
|
|
70
291
|
this._restoreCachedInititalValues();
|
|
71
|
-
this._commandListDiv = this._getDomElement(
|
|
72
|
-
this.
|
|
73
|
-
|
|
74
|
-
this.
|
|
292
|
+
this._commandListDiv = this._getDomElement("commandList");
|
|
293
|
+
this._propertygrid =
|
|
294
|
+
this._getDomElement("propertygrid");
|
|
295
|
+
this._splitView = this._getDomElement("splitView");
|
|
296
|
+
this._codeView = this._getDomElement("codeView");
|
|
297
|
+
this._codeToggleBtn =
|
|
298
|
+
this._getDomElement("codeToggleBtn");
|
|
299
|
+
this._addCommandBtn =
|
|
300
|
+
this._getDomElement("addCommandBtn");
|
|
301
|
+
const listContent = this._getDomElement("listContent");
|
|
302
|
+
listContent.addEventListener("mousedown", (ev) => {
|
|
303
|
+
this._dragFromHandle = !!ev.target?.closest(".drag-handle");
|
|
304
|
+
});
|
|
305
|
+
document.addEventListener("dragend", () => {
|
|
306
|
+
this._draggedNode = null;
|
|
307
|
+
}, true);
|
|
308
|
+
listContent.addEventListener("dragover", (ev) => {
|
|
309
|
+
ev.preventDefault();
|
|
310
|
+
if (ev.dataTransfer) {
|
|
311
|
+
const isMove = ev.dataTransfer.types.includes(SAME_TREE_MOVE_MIME);
|
|
312
|
+
ev.dataTransfer.dropEffect = isMove ? "move" : "copy";
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
listContent.addEventListener("drop", (ev) => {
|
|
316
|
+
ev.preventDefault();
|
|
317
|
+
const isMove = ev.dataTransfer?.types.includes(SAME_TREE_MOVE_MIME);
|
|
318
|
+
if (isMove && this._draggedNode) {
|
|
319
|
+
const children = this._commandListFancyTree.root.children;
|
|
320
|
+
const last = children?.[children.length - 1];
|
|
321
|
+
if (last)
|
|
322
|
+
this._draggedNode.moveTo(last, "after");
|
|
323
|
+
this._draggedNode.setClass("wb-drag-source", false);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
const type = ev.dataTransfer?.getData("text/plain");
|
|
327
|
+
if (type) {
|
|
328
|
+
const command = { type };
|
|
329
|
+
this._commandListFancyTree.root.addChildren(this.createTreeItem(command));
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
this.shadowRoot.adoptedStyleSheets = [
|
|
334
|
+
wunderbaumStyle,
|
|
335
|
+
SimpleScriptEditor.style,
|
|
336
|
+
];
|
|
75
337
|
}
|
|
76
338
|
async ready() {
|
|
77
|
-
this.addPossibleCommands();
|
|
78
339
|
this._parseAttributesToProperties();
|
|
79
340
|
this._bindingsParse(null, true);
|
|
80
341
|
this._assignEvents();
|
|
@@ -84,29 +345,35 @@ export class SimpleScriptEditor extends BaseCustomWebComponentConstructorAppend
|
|
|
84
345
|
pg.visualizationShell = this.visualizationShell;
|
|
85
346
|
pg.serviceContainer = this.serviceContainer;
|
|
86
347
|
pg.instanceServiceContainer = this.instanceServiceContainer;
|
|
87
|
-
pg.bindableObjectsTarget =
|
|
348
|
+
pg.bindableObjectsTarget = "script";
|
|
88
349
|
pg.getTypeInfo = (obj, type) => typeInfoFromJsonSchema(this.propertiesTypeInfo, obj, type);
|
|
89
350
|
pg.showHead = false;
|
|
90
|
-
pg.typeName =
|
|
351
|
+
pg.typeName = "IScriptMultiplexValue";
|
|
91
352
|
pg.title = 'Complex for "' + data.propertyPath + '"';
|
|
92
|
-
if (typeof data.value ===
|
|
353
|
+
if (typeof data.value === "object")
|
|
93
354
|
pg.selectedObject = data.value ?? {};
|
|
94
355
|
else
|
|
95
356
|
pg.selectedObject = {};
|
|
96
357
|
pg.bindingDoubleClicked = (b) => {
|
|
97
|
-
if (b.bindabletype ==
|
|
98
|
-
pg.setPropertyValue(
|
|
358
|
+
if (b.bindabletype == "property") {
|
|
359
|
+
pg.setPropertyValue("source", "property");
|
|
99
360
|
}
|
|
100
|
-
else if (b.bindabletype ==
|
|
101
|
-
pg.setPropertyValue(
|
|
361
|
+
else if (b.bindabletype == "context") {
|
|
362
|
+
pg.setPropertyValue("source", "context");
|
|
102
363
|
}
|
|
103
364
|
else {
|
|
104
|
-
pg.setPropertyValue(
|
|
365
|
+
pg.setPropertyValue("source", "signal");
|
|
105
366
|
}
|
|
106
|
-
pg.setPropertyValue(
|
|
367
|
+
pg.setPropertyValue("name", b.fullName);
|
|
107
368
|
pg.refresh();
|
|
108
369
|
};
|
|
109
|
-
let res = await this.visualizationShell.openConfirmation(pg, {
|
|
370
|
+
let res = await this.visualizationShell.openConfirmation(pg, {
|
|
371
|
+
x: 100,
|
|
372
|
+
y: 100,
|
|
373
|
+
width: 400,
|
|
374
|
+
height: 500,
|
|
375
|
+
parent: this,
|
|
376
|
+
});
|
|
110
377
|
if (res) {
|
|
111
378
|
this._propertygrid.setPropertyValue(data.propertyPath, pg.selectedObject);
|
|
112
379
|
this._propertygrid.refresh();
|
|
@@ -116,117 +383,167 @@ export class SimpleScriptEditor extends BaseCustomWebComponentConstructorAppend
|
|
|
116
383
|
this._propertygrid.visualizationShell = this.visualizationShell;
|
|
117
384
|
this._propertygrid.serviceContainer = this.serviceContainer;
|
|
118
385
|
this._propertygrid.instanceServiceContainer = this.instanceServiceContainer;
|
|
119
|
-
this._propertygrid.bindableObjectsTarget =
|
|
386
|
+
this._propertygrid.bindableObjectsTarget = "script";
|
|
120
387
|
this._propertygrid.getTypeInfo = (obj, type) => typeInfoFromJsonSchema(this.scriptCommandsTypeInfo, obj, type);
|
|
121
388
|
this._propertygrid.getSpecialEditorForType = async (property, currentValue, propertyPath, wbRender, additionalInfo) => {
|
|
122
389
|
//@ts-ignore
|
|
123
390
|
if (!property.specialAllreadyAdded) {
|
|
124
391
|
//@ts-ignore
|
|
125
392
|
property.specialAllreadyAdded = true;
|
|
126
|
-
if (property.format ===
|
|
393
|
+
if (property.format === "collection") {
|
|
127
394
|
//TODO: create a collection edt. in property grid control used
|
|
128
395
|
}
|
|
129
|
-
else if ((typeof currentValue ===
|
|
130
|
-
|
|
131
|
-
rB
|
|
132
|
-
rB.style.
|
|
133
|
-
rB.style.
|
|
134
|
-
rB.style.
|
|
135
|
-
rB.style.
|
|
136
|
-
rB.style.
|
|
137
|
-
rB.
|
|
396
|
+
else if ((typeof currentValue === "object" && currentValue !== null) ||
|
|
397
|
+
property.format === "complex") {
|
|
398
|
+
let rB = document.createElement("button");
|
|
399
|
+
rB.style.height = "calc(100% - 6px)";
|
|
400
|
+
rB.style.position = "relative";
|
|
401
|
+
rB.style.display = "flex";
|
|
402
|
+
rB.style.justifyContent = "center";
|
|
403
|
+
rB.style.width = "20px";
|
|
404
|
+
rB.style.boxSizing = "content-box";
|
|
405
|
+
rB.innerText = "del";
|
|
138
406
|
rB.onclick = () => {
|
|
139
407
|
this._propertygrid.setPropertyValue(propertyPath, undefined);
|
|
140
408
|
this._propertygrid.refresh();
|
|
141
409
|
};
|
|
142
|
-
wbRender.nodeElem.insertAdjacentElement(
|
|
143
|
-
let d = document.createElement(
|
|
144
|
-
d.style.display =
|
|
145
|
-
let sp = document.createElement(
|
|
410
|
+
wbRender.nodeElem.insertAdjacentElement("afterbegin", rB);
|
|
411
|
+
let d = document.createElement("div");
|
|
412
|
+
d.style.display = "flex";
|
|
413
|
+
let sp = document.createElement("span");
|
|
146
414
|
if (currentValue)
|
|
147
|
-
sp.innerText =
|
|
415
|
+
sp.innerText =
|
|
416
|
+
(currentValue.source ?? "") + ": " + (currentValue.name ?? "");
|
|
148
417
|
else
|
|
149
|
-
sp.innerText =
|
|
150
|
-
sp.style.overflow =
|
|
151
|
-
sp.style.whiteSpace =
|
|
152
|
-
sp.style.textOverflow =
|
|
153
|
-
sp.style.flexGrow =
|
|
418
|
+
sp.innerText = "";
|
|
419
|
+
sp.style.overflow = "hidden";
|
|
420
|
+
sp.style.whiteSpace = "nowrap";
|
|
421
|
+
sp.style.textOverflow = "ellipsis";
|
|
422
|
+
sp.style.flexGrow = "1";
|
|
154
423
|
sp.title = JSON.stringify(currentValue);
|
|
155
424
|
d.appendChild(sp);
|
|
156
|
-
let b = document.createElement(
|
|
157
|
-
b.innerText =
|
|
425
|
+
let b = document.createElement("button");
|
|
426
|
+
b.innerText = "...";
|
|
158
427
|
b.onclick = () => {
|
|
159
428
|
editComplex({ value: currentValue, propertyPath });
|
|
160
429
|
};
|
|
161
430
|
d.appendChild(b);
|
|
162
|
-
wbRender.nodeElem.style.display =
|
|
431
|
+
wbRender.nodeElem.style.display = "flex";
|
|
163
432
|
return d;
|
|
164
433
|
}
|
|
165
434
|
else {
|
|
166
|
-
let b = document.createElement(
|
|
167
|
-
b.style.height =
|
|
168
|
-
b.style.position =
|
|
169
|
-
b.style.display =
|
|
170
|
-
b.style.justifyContent =
|
|
171
|
-
b.style.width =
|
|
172
|
-
b.style.boxSizing =
|
|
173
|
-
b.title =
|
|
174
|
-
b.style.opacity =
|
|
175
|
-
b.innerText =
|
|
435
|
+
let b = document.createElement("button");
|
|
436
|
+
b.style.height = "calc(100% - 6px)";
|
|
437
|
+
b.style.position = "relative";
|
|
438
|
+
b.style.display = "flex";
|
|
439
|
+
b.style.justifyContent = "center";
|
|
440
|
+
b.style.width = "20px";
|
|
441
|
+
b.style.boxSizing = "content-box";
|
|
442
|
+
b.title = "complex property value";
|
|
443
|
+
b.style.opacity = "0.2";
|
|
444
|
+
b.innerText = "...";
|
|
176
445
|
b.onclick = () => {
|
|
177
446
|
editComplex({ value: currentValue, propertyPath });
|
|
178
447
|
};
|
|
179
|
-
wbRender.nodeElem.insertAdjacentElement(
|
|
180
|
-
wbRender.nodeElem.style.display =
|
|
448
|
+
wbRender.nodeElem.insertAdjacentElement("afterbegin", b);
|
|
449
|
+
wbRender.nodeElem.style.display = "flex";
|
|
181
450
|
}
|
|
182
451
|
}
|
|
183
452
|
return null;
|
|
184
453
|
};
|
|
185
454
|
this._propertygrid.propertyNodeContextMenu.on((data) => {
|
|
186
|
-
ContextMenu.show([
|
|
187
|
-
|
|
455
|
+
ContextMenu.show([
|
|
456
|
+
{
|
|
457
|
+
title: "edit complex value",
|
|
188
458
|
action: async () => {
|
|
189
459
|
editComplex(data);
|
|
190
|
-
}
|
|
460
|
+
},
|
|
191
461
|
},
|
|
192
462
|
{
|
|
193
|
-
title:
|
|
463
|
+
title: "edit string",
|
|
194
464
|
action: async () => {
|
|
195
465
|
const v = prompt("enter value:");
|
|
196
466
|
if (v) {
|
|
197
467
|
this._propertygrid.setPropertyValue(data.propertyPath, v);
|
|
198
468
|
this._propertygrid.refresh();
|
|
199
469
|
}
|
|
200
|
-
}
|
|
470
|
+
},
|
|
201
471
|
},
|
|
202
472
|
{
|
|
203
|
-
title:
|
|
473
|
+
title: "remove complex value",
|
|
204
474
|
action: async () => {
|
|
205
475
|
this._propertygrid.setPropertyValue(data.propertyPath, undefined);
|
|
206
476
|
this._propertygrid.refresh();
|
|
207
|
-
}
|
|
208
|
-
}
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
], data.event);
|
|
209
480
|
});
|
|
210
481
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
482
|
+
helpClicked() {
|
|
483
|
+
const iframe = document.createElement("iframe");
|
|
484
|
+
iframe.srcdoc = simpleScriptEditorHelpHtml;
|
|
485
|
+
iframe.style.cssText =
|
|
486
|
+
"width:100%; height:100%; border:none; display:block;";
|
|
487
|
+
this.visualizationShell.openModal(iframe, {
|
|
488
|
+
title: "Simple Script Editor Help",
|
|
489
|
+
parent: this,
|
|
490
|
+
x: -650,
|
|
491
|
+
y: -100,
|
|
492
|
+
width: 620,
|
|
493
|
+
height: 620,
|
|
494
|
+
});
|
|
495
|
+
this.helpRequested.emit();
|
|
496
|
+
}
|
|
497
|
+
toggleCodeView() {
|
|
498
|
+
if (!this._showingCode) {
|
|
499
|
+
const json = JSON.stringify({ commands: this.getScriptCommands() }, null, 2);
|
|
500
|
+
this._codeView.update(json);
|
|
501
|
+
this._showCodeView(true);
|
|
502
|
+
return;
|
|
220
503
|
}
|
|
504
|
+
const parsed = this._parseCodeViewScript();
|
|
505
|
+
if (!parsed)
|
|
506
|
+
return;
|
|
507
|
+
this._showCodeView(false);
|
|
508
|
+
this.loadScript(parsed);
|
|
509
|
+
}
|
|
510
|
+
_showCodeView(show) {
|
|
511
|
+
this._codeView.classList.toggle("visible", show);
|
|
512
|
+
this._commandListDiv.classList.toggle("hidden", show);
|
|
513
|
+
this._splitView.classList.toggle("code-mode", show);
|
|
514
|
+
this._addCommandBtn.disabled = show;
|
|
515
|
+
this._codeToggleBtn.innerText = show ? "Visual" : "Code";
|
|
516
|
+
this._showingCode = show;
|
|
517
|
+
if (show)
|
|
518
|
+
requestAnimationFrame(() => this._codeView.activated());
|
|
519
|
+
}
|
|
520
|
+
/** Parses+validates the code view's JSON. Returns null (and alerts) on invalid JSON. */
|
|
521
|
+
_parseCodeViewScript() {
|
|
522
|
+
let parsed;
|
|
523
|
+
try {
|
|
524
|
+
parsed = JSON.parse(this._codeView.getText());
|
|
525
|
+
}
|
|
526
|
+
catch (e) {
|
|
527
|
+
alert("Invalid JSON:\n" + e.message);
|
|
528
|
+
return null;
|
|
529
|
+
}
|
|
530
|
+
if (!Array.isArray(parsed?.commands)) {
|
|
531
|
+
alert('The JSON must have a "commands" array.');
|
|
532
|
+
return null;
|
|
533
|
+
}
|
|
534
|
+
return parsed;
|
|
221
535
|
}
|
|
222
536
|
loadScript(script) {
|
|
223
537
|
this._script = script;
|
|
538
|
+
if (this._commandListFancyTree) {
|
|
539
|
+
this._commandListFancyTree.destroy();
|
|
540
|
+
this._commandListDiv = this._getDomElement("commandList");
|
|
541
|
+
}
|
|
224
542
|
let commandListTreeItems = [];
|
|
225
543
|
for (let c of this._script.commands) {
|
|
226
544
|
c = ScriptUpgrades.upgradeScriptCommand(c);
|
|
227
545
|
commandListTreeItems.push(this.createTreeItem(c));
|
|
228
546
|
}
|
|
229
|
-
;
|
|
230
547
|
this._commandListFancyTree = new Wunderbaum({
|
|
231
548
|
...defaultOptions,
|
|
232
549
|
element: this._commandListDiv,
|
|
@@ -237,15 +554,51 @@ export class SimpleScriptEditor extends BaseCustomWebComponentConstructorAppend
|
|
|
237
554
|
},
|
|
238
555
|
render: (e) => {
|
|
239
556
|
if (e.isNew) {
|
|
240
|
-
|
|
241
|
-
span.oncontextmenu = (ev) => {
|
|
242
|
-
e.node.setActive();
|
|
243
|
-
if (e.node.data.contextMenu) {
|
|
244
|
-
e.node.data.contextMenu(ev, e.node.data, e.node);
|
|
245
|
-
}
|
|
557
|
+
e.nodeElem.oncontextmenu = (ev) => {
|
|
246
558
|
ev.preventDefault();
|
|
247
559
|
return false;
|
|
248
560
|
};
|
|
561
|
+
const handle = document.createElement("div");
|
|
562
|
+
handle.className = "drag-handle";
|
|
563
|
+
handle.title = "Drag to reorder";
|
|
564
|
+
handle.innerHTML =
|
|
565
|
+
'<svg viewBox="0 0 24 24" width="14" height="14"><path d="M4 6h16M4 12h16M4 18h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
|
|
566
|
+
const leadingSpacer = document.createElement("span");
|
|
567
|
+
leadingSpacer.style.cssText = "display:inline-block; width:24px;";
|
|
568
|
+
e.nodeElem.prepend(leadingSpacer, handle);
|
|
569
|
+
const rowElem = e.nodeElem.parentElement;
|
|
570
|
+
const spacer = document.createElement("span");
|
|
571
|
+
spacer.style.cssText = "display:inline-block; width:32px;";
|
|
572
|
+
e.nodeElem.appendChild(spacer);
|
|
573
|
+
const cmd = document.createElement("div");
|
|
574
|
+
cmd.className = "cmd";
|
|
575
|
+
const copyImg = document.createElement("img");
|
|
576
|
+
copyImg.src = assetsPath + "icons/copy.svg";
|
|
577
|
+
copyImg.title = "Duplicate";
|
|
578
|
+
copyImg.onclick = () => {
|
|
579
|
+
const clone = structuredClone(e.node.data.data.item);
|
|
580
|
+
const newNode = e.node.parent.addChildren(this.createTreeItem(clone));
|
|
581
|
+
newNode.moveTo(e.node, "after");
|
|
582
|
+
};
|
|
583
|
+
const delImg = document.createElement("img");
|
|
584
|
+
delImg.src = assetsPath + "icons/delete.svg";
|
|
585
|
+
delImg.title = "Remove";
|
|
586
|
+
delImg.onclick = () => e.node.remove();
|
|
587
|
+
cmd.append(copyImg, delImg);
|
|
588
|
+
rowElem.appendChild(cmd);
|
|
589
|
+
//@ts-ignore
|
|
590
|
+
e.nodeElem._reservedRowWidth =
|
|
591
|
+
leadingSpacer.offsetWidth + spacer.offsetWidth;
|
|
592
|
+
}
|
|
593
|
+
//@ts-ignore
|
|
594
|
+
const reserved = e.nodeElem._reservedRowWidth ?? 0;
|
|
595
|
+
if (reserved) {
|
|
596
|
+
const titleSpan = e.nodeElem.querySelector("span.wb-title");
|
|
597
|
+
if (titleSpan) {
|
|
598
|
+
const w = parseFloat(titleSpan.style.width);
|
|
599
|
+
if (!isNaN(w))
|
|
600
|
+
titleSpan.style.width = Math.max(0, w - reserved) + "px";
|
|
601
|
+
}
|
|
249
602
|
}
|
|
250
603
|
},
|
|
251
604
|
dnd: {
|
|
@@ -254,42 +607,85 @@ export class SimpleScriptEditor extends BaseCustomWebComponentConstructorAppend
|
|
|
254
607
|
preventVoidMoves: false,
|
|
255
608
|
serializeClipboardData: false,
|
|
256
609
|
dragStart: (e) => {
|
|
610
|
+
if (!this._dragFromHandle)
|
|
611
|
+
return false;
|
|
612
|
+
this._draggedNode = e.node;
|
|
257
613
|
e.event.dataTransfer.effectAllowed = "move";
|
|
258
614
|
e.event.dataTransfer.dropEffect = "move";
|
|
615
|
+
e.event.dataTransfer.setData(SAME_TREE_MOVE_MIME, "1");
|
|
259
616
|
return true;
|
|
260
617
|
},
|
|
618
|
+
dragEnd: () => {
|
|
619
|
+
this._draggedNode = null;
|
|
620
|
+
},
|
|
261
621
|
dragEnter: (e) => {
|
|
262
|
-
e.event.dataTransfer.
|
|
622
|
+
const isMove = e.event.dataTransfer?.types.includes(SAME_TREE_MOVE_MIME);
|
|
623
|
+
e.event.dataTransfer.dropEffect = isMove ? "move" : "copy";
|
|
263
624
|
return true;
|
|
264
625
|
},
|
|
265
626
|
dragOver: (e) => {
|
|
266
|
-
e.event.dataTransfer.
|
|
627
|
+
const isMove = e.event.dataTransfer?.types.includes(SAME_TREE_MOVE_MIME);
|
|
628
|
+
e.event.dataTransfer.dropEffect = isMove ? "move" : "copy";
|
|
267
629
|
},
|
|
268
630
|
drop: async (e) => {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
631
|
+
const region = e.region == "before" ? "before" : "after";
|
|
632
|
+
const isMove = e.event.dataTransfer?.types.includes(SAME_TREE_MOVE_MIME);
|
|
633
|
+
if (isMove && this._draggedNode) {
|
|
634
|
+
this._draggedNode.moveTo(e.node, region);
|
|
635
|
+
this._draggedNode.setClass("wb-drag-source", false);
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
const type = e.event.dataTransfer?.getData("text/plain");
|
|
639
|
+
if (type) {
|
|
640
|
+
const command = { type };
|
|
641
|
+
const ti = this.createTreeItem(command);
|
|
642
|
+
const newNode = e.node.parent.addChildren(ti);
|
|
643
|
+
newNode.moveTo(e.node, region);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
},
|
|
272
648
|
});
|
|
649
|
+
this._commandListFancyTree.root.children?.[0]?.setActive();
|
|
273
650
|
}
|
|
274
651
|
createTreeItem(currentItem) {
|
|
275
652
|
let cti = {
|
|
276
653
|
title: currentItem.type,
|
|
277
654
|
data: { item: currentItem },
|
|
278
|
-
contextMenu: (e, data, node) => {
|
|
279
|
-
ContextMenu.show([{ title: 'Remove Item', action: (e) => node.remove() }], e);
|
|
280
|
-
}
|
|
281
655
|
};
|
|
282
656
|
return cti;
|
|
283
657
|
}
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
658
|
+
async addCommand() {
|
|
659
|
+
const picker = new SimpleScriptCommandPicker();
|
|
660
|
+
picker.loadCommands(this.scriptCommandsTypeInfo, this.commandDescriptions);
|
|
661
|
+
picker.title = "Add Script Command";
|
|
662
|
+
picker.commandTypeChosen.on(() => {
|
|
663
|
+
if (picker.selectedType) {
|
|
664
|
+
const command = { type: picker.selectedType };
|
|
665
|
+
const ti = this.createTreeItem(command);
|
|
666
|
+
this._commandListFancyTree.addChildren(ti);
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
const abortController = new AbortController();
|
|
670
|
+
picker.closeRequested.on(() => abortController.abort());
|
|
671
|
+
await this.visualizationShell.openModal(picker, {
|
|
672
|
+
title: "Add Script Command",
|
|
673
|
+
x: 300,
|
|
674
|
+
y: 50,
|
|
675
|
+
width: 620,
|
|
676
|
+
height: 400,
|
|
677
|
+
parent: this,
|
|
678
|
+
abortSignal: abortController.signal,
|
|
679
|
+
});
|
|
289
680
|
}
|
|
290
681
|
getScriptCommands() {
|
|
682
|
+
if (this._showingCode) {
|
|
683
|
+
const parsed = this._parseCodeViewScript();
|
|
684
|
+
if (parsed)
|
|
685
|
+
this.loadScript(parsed);
|
|
686
|
+
}
|
|
291
687
|
let children = this._commandListFancyTree.root.children;
|
|
292
|
-
return children.map(x => x.data.data.item);
|
|
688
|
+
return children.map((x) => x.data.data.item);
|
|
293
689
|
}
|
|
294
690
|
}
|
|
295
691
|
customElements.define(SimpleScriptEditor.is, SimpleScriptEditor);
|