sunrize 1.11.1 → 1.11.3
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/package.json +14 -13
- package/src/Application/Dashboard.js +12 -3
- package/src/Application/Document.js +8 -4
- package/src/Application/Hierarchy.js +10 -3
- package/src/Controls/Dialog.js +5 -2
- package/src/Editors/Console.js +252 -17
- package/src/Editors/Library.js +1 -1
- package/src/Editors/MaterialsLibrary.js +5 -3
- package/src/Editors/OutlineEditor.js +340 -222
- package/src/Editors/OutlineView.js +148 -173
- package/src/Editors/Panel.js +55 -1
- package/src/Editors/SceneProperties.js +1 -1
- package/src/Fields/MFStringTextArea.js +13 -11
- package/src/Fields/SFStringInput.js +12 -12
- package/src/Tools/Core/X3DNodeTool.js +1 -1
- package/src/Undo/Editor.js +91 -66
- package/src/assets/X3DUOM.xml +13 -4
- package/src/assets/themes/default.css +166 -40
- package/src/assets/themes/media-template.css +1 -9
- package/src/assets/themes/media.css +1 -9
- package/src/assets/themes/system-colors.css +2 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sunrize",
|
|
3
3
|
"productName": "Sunrize X3D Editor",
|
|
4
|
-
"version": "1.11.
|
|
4
|
+
"version": "1.11.3",
|
|
5
5
|
"description": "A Multi-Platform X3D Editor",
|
|
6
6
|
"main": "src/main.js",
|
|
7
7
|
"bin": {
|
|
@@ -78,19 +78,20 @@
|
|
|
78
78
|
"url": "https://patreon.com/X_ITE"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@electron-forge/cli": "^7.
|
|
82
|
-
"@electron-forge/maker-deb": "^7.
|
|
83
|
-
"@electron-forge/maker-dmg": "^7.
|
|
84
|
-
"@electron-forge/maker-rpm": "^7.
|
|
85
|
-
"@electron-forge/maker-squirrel": "^7.
|
|
86
|
-
"@electron-forge/maker-zip": "^7.
|
|
87
|
-
"@electron-forge/publisher-github": "^7.
|
|
81
|
+
"@electron-forge/cli": "^7.10.2",
|
|
82
|
+
"@electron-forge/maker-deb": "^7.10.2",
|
|
83
|
+
"@electron-forge/maker-dmg": "^7.10.2",
|
|
84
|
+
"@electron-forge/maker-rpm": "^7.10.2",
|
|
85
|
+
"@electron-forge/maker-squirrel": "^7.10.2",
|
|
86
|
+
"@electron-forge/maker-zip": "^7.10.2",
|
|
87
|
+
"@electron-forge/publisher-github": "^7.10.2",
|
|
88
88
|
"shell-tools": "^1.1.9"
|
|
89
89
|
},
|
|
90
90
|
"dependencies": {
|
|
91
|
+
"@vscode/codicons": "^0.0.41",
|
|
91
92
|
"capitalize": "^2.0.4",
|
|
92
93
|
"console": "^0.7.2",
|
|
93
|
-
"electron": "^38.
|
|
94
|
+
"electron": "^38.4.0",
|
|
94
95
|
"electron-prompt": "^1.7.0",
|
|
95
96
|
"electron-squirrel-startup": "^1.0.1",
|
|
96
97
|
"electron-tabs": "^1.0.4",
|
|
@@ -99,17 +100,17 @@
|
|
|
99
100
|
"jquery-ui-dist": "^1.13.3",
|
|
100
101
|
"jstree": "^3.3.17",
|
|
101
102
|
"material-icons": "^1.13.14",
|
|
102
|
-
"material-symbols": "^0.
|
|
103
|
+
"material-symbols": "^0.38.0",
|
|
103
104
|
"md5": "^2.3.0",
|
|
104
105
|
"mime-types": "^3.0.1",
|
|
105
|
-
"monaco-editor": "^0.
|
|
106
|
+
"monaco-editor": "^0.54.0",
|
|
106
107
|
"node-localstorage": "^3.0.5",
|
|
107
108
|
"qtip2": "^3.0.3",
|
|
108
109
|
"spectrum-colorpicker2": "^2.0.10",
|
|
109
110
|
"string-similarity": "^4.0.4",
|
|
110
111
|
"tweakpane": "^3.1.10",
|
|
111
112
|
"update-electron-app": "^3.1.1",
|
|
112
|
-
"x_ite": "^12.1.
|
|
113
|
-
"x3d-traverse": "^1.0.
|
|
113
|
+
"x_ite": "^12.1.3",
|
|
114
|
+
"x3d-traverse": "^1.0.22"
|
|
114
115
|
}
|
|
115
116
|
}
|
|
@@ -180,10 +180,19 @@ module .exports = class Dashboard extends Interface
|
|
|
180
180
|
for (const node of nodes)
|
|
181
181
|
outlineEditor .expandTo (node, { expandObject: true, expandAll: true });
|
|
182
182
|
|
|
183
|
-
const elements = nodes .map (node => outlineEditor .sceneGraph
|
|
183
|
+
const elements = nodes .map (node => outlineEditor .sceneGraph
|
|
184
|
+
.find (`:is(.node, .imported-node.proxy)[node-id="${node .getId ()}"]`));
|
|
184
185
|
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
outlineEditor .deselectAll ({ target: false });
|
|
187
|
+
|
|
188
|
+
for (const element of elements)
|
|
189
|
+
{
|
|
190
|
+
if (element .is (".node"))
|
|
191
|
+
outlineEditor .selectNodeElement (element, { add: true });
|
|
192
|
+
|
|
193
|
+
else if (element .is (".imported-node.proxy"))
|
|
194
|
+
outlineEditor .selectPrimaryElement (element, { add: true });
|
|
195
|
+
}
|
|
187
196
|
|
|
188
197
|
// Scroll element into view.
|
|
189
198
|
// Hide scrollbars during scroll to prevent overlay issue.
|
|
@@ -185,6 +185,10 @@ module .exports = class Document extends Interface
|
|
|
185
185
|
|
|
186
186
|
// Restore
|
|
187
187
|
|
|
188
|
+
const pkg = require ("../../package.json");
|
|
189
|
+
|
|
190
|
+
console .info (`Welcome to ${pkg .productName} v${pkg .version}.`);
|
|
191
|
+
|
|
188
192
|
await this .restoreFile ();
|
|
189
193
|
|
|
190
194
|
if (!this .isInitialScene)
|
|
@@ -320,8 +324,8 @@ module .exports = class Document extends Interface
|
|
|
320
324
|
|
|
321
325
|
const activeElement = this .activeElement;
|
|
322
326
|
|
|
323
|
-
if (activeElement .is ("input"))
|
|
324
|
-
return
|
|
327
|
+
if (activeElement .is ("input:not([type]), input[type=text]"))
|
|
328
|
+
return true;
|
|
325
329
|
|
|
326
330
|
if (activeElement .is ("textarea"))
|
|
327
331
|
return true;
|
|
@@ -452,7 +456,7 @@ Viewpoint {
|
|
|
452
456
|
pkg = require ("../../package.json"),
|
|
453
457
|
generator = scene .getMetaData ("generator") ?.filter (value => !value .startsWith (pkg .productName)) ?? [ ];
|
|
454
458
|
|
|
455
|
-
generator .
|
|
459
|
+
generator .unshift (`${pkg .productName} V${pkg .version}, ${pkg .homepage}`);
|
|
456
460
|
|
|
457
461
|
if (!scene .getMetaData ("creator") ?.some (value => value .includes (this .fullname)))
|
|
458
462
|
scene .addMetaData ("creator", this .fullname);
|
|
@@ -631,7 +635,7 @@ Viewpoint {
|
|
|
631
635
|
if (this .activeElementIsMonacoEditor ())
|
|
632
636
|
return;
|
|
633
637
|
|
|
634
|
-
this .sidebar .outlineEditor .copyNodes (
|
|
638
|
+
this .sidebar .outlineEditor .copyNodes ();
|
|
635
639
|
return false;
|
|
636
640
|
}
|
|
637
641
|
|
|
@@ -36,8 +36,8 @@ module .exports = new class Hierarchy extends Interface
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
#targetTypes = new Set ([
|
|
39
|
-
X3D .X3DConstants .X3DShapeNode,
|
|
40
39
|
X3D .X3DConstants .Inline,
|
|
40
|
+
X3D .X3DConstants .X3DShapeNode,
|
|
41
41
|
]);
|
|
42
42
|
|
|
43
43
|
target (node)
|
|
@@ -70,10 +70,17 @@ module .exports = new class Hierarchy extends Interface
|
|
|
70
70
|
|
|
71
71
|
const node = object .getValue () .valueOf ();
|
|
72
72
|
|
|
73
|
-
if (!node .getType () .some (type => this .#targetTypes .has (type))
|
|
73
|
+
if (!node .getType () .some (type => this .#targetTypes .has (type)) &&
|
|
74
|
+
!(node instanceof X3D .X3DImportedNodeProxy))
|
|
75
|
+
{
|
|
74
76
|
continue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const target = node .getType () .includes (X3D .X3DConstants .X3DShapeNode)
|
|
80
|
+
? node .getGeometry () ?.valueOf () ?? node
|
|
81
|
+
: node;
|
|
75
82
|
|
|
76
|
-
targets .push (
|
|
83
|
+
targets .push (target);
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
for (const hierarchy of this .#find (targets))
|
package/src/Controls/Dialog.js
CHANGED
|
@@ -47,9 +47,12 @@ module .exports = class Dialog extends Interface
|
|
|
47
47
|
{
|
|
48
48
|
// Set default config values.
|
|
49
49
|
|
|
50
|
+
defaults .minSize ??= defaults .size;
|
|
51
|
+
|
|
50
52
|
this .config .file .setDefaultValues (Object .assign ({
|
|
51
53
|
position: undefined,
|
|
52
54
|
size: [400, 250],
|
|
55
|
+
minSize: [400, 250],
|
|
53
56
|
},
|
|
54
57
|
defaults));
|
|
55
58
|
}
|
|
@@ -58,8 +61,8 @@ module .exports = class Dialog extends Interface
|
|
|
58
61
|
{
|
|
59
62
|
this .element .dialog ({
|
|
60
63
|
position: { ... this .config .file .position, of: $("body") },
|
|
61
|
-
minWidth: this .config .file .
|
|
62
|
-
minHeight: this .config .file .
|
|
64
|
+
minWidth: this .config .file .minSize [0],
|
|
65
|
+
minHeight: this .config .file .minSize [1],
|
|
63
66
|
width: this .config .file .size [0],
|
|
64
67
|
height: this .config .file .size [1],
|
|
65
68
|
})
|
package/src/Editors/Console.js
CHANGED
|
@@ -5,6 +5,7 @@ const
|
|
|
5
5
|
$ = require ("jquery"),
|
|
6
6
|
electron = require ("electron"),
|
|
7
7
|
Interface = require ("../Application/Interface"),
|
|
8
|
+
util = require ("util"),
|
|
8
9
|
_ = require ("../Application/GetText");
|
|
9
10
|
|
|
10
11
|
module .exports = class Console extends Interface
|
|
@@ -31,34 +32,103 @@ module .exports = class Console extends Interface
|
|
|
31
32
|
this .history = [ ];
|
|
32
33
|
this .addMessageCallback = this .addMessage .bind (this);
|
|
33
34
|
|
|
34
|
-
this .console
|
|
35
|
-
this .left
|
|
36
|
-
this .toolbar
|
|
37
|
-
|
|
38
|
-
this .
|
|
35
|
+
this .console = element;
|
|
36
|
+
this .left = $("<div></div>") .addClass ("console-left") .appendTo (this .console);
|
|
37
|
+
this .toolbar = $("<div></div>") .addClass (["toolbar", "vertical-toolbar", "console-toolbar"]) .appendTo (this .console);
|
|
38
|
+
|
|
39
|
+
this .output = $("<div></div>")
|
|
40
|
+
.addClass (["console-output", "output"])
|
|
41
|
+
.attr ("tabindex", 0)
|
|
42
|
+
.on ("keydown", event => this .outputKey (event))
|
|
43
|
+
.appendTo (this .left);
|
|
44
|
+
|
|
45
|
+
this .input = $("<div></div>")
|
|
46
|
+
.addClass ("console-input")
|
|
47
|
+
.appendTo (this .left);
|
|
48
|
+
|
|
49
|
+
// Search Widget
|
|
50
|
+
|
|
51
|
+
this .search = $("<div></div>")
|
|
52
|
+
.addClass ("console-search")
|
|
53
|
+
.appendTo (this .left)
|
|
54
|
+
.hide ();
|
|
55
|
+
|
|
56
|
+
this .search .resizable({
|
|
57
|
+
handles: "w",
|
|
58
|
+
minWidth: 285,
|
|
59
|
+
resize: () => this .config .file .searchWidth = this .search .width (),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
this .searchInputElements = $("<div></div>")
|
|
63
|
+
.addClass ("console-search-input-elements")
|
|
64
|
+
.appendTo (this .search);
|
|
65
|
+
|
|
66
|
+
this .searchInput = $("<input></input>")
|
|
67
|
+
.attr ("type", "text")
|
|
68
|
+
.attr ("placeholder", _("Find"))
|
|
69
|
+
.addClass ("console-search-input")
|
|
70
|
+
.on ("input", () => this .searchString ())
|
|
71
|
+
.on ("keydown", event => this .searchKey (event))
|
|
72
|
+
.appendTo (this .searchInputElements);
|
|
73
|
+
|
|
74
|
+
this .searchCaseSensitiveButton = $("<div></div>")
|
|
75
|
+
.addClass (["codicon", "codicon-case-sensitive", "console-search-case-sensitive"])
|
|
76
|
+
.on ("click", () => this .searchCaseSensitive (!this .config .file .searchCaseSensitive))
|
|
77
|
+
.appendTo (this .searchInputElements);
|
|
78
|
+
|
|
79
|
+
this .searchStatus = $("<div></div>")
|
|
80
|
+
.addClass ("console-search-status")
|
|
81
|
+
.text ("No results")
|
|
82
|
+
.appendTo (this .search);
|
|
83
|
+
|
|
84
|
+
this .searchPreviousButton = $("<div></div>")
|
|
85
|
+
.addClass (["search-previous", "codicon", "codicon-arrow-up", "disabled"])
|
|
86
|
+
.attr ("tabindex", 0)
|
|
87
|
+
.on ("click", () => this .searchPrevious ())
|
|
88
|
+
.appendTo (this .search);
|
|
89
|
+
|
|
90
|
+
this .searchNextButton = $("<div></div>")
|
|
91
|
+
.addClass (["search-next", "codicon", "codicon-arrow-down", "disabled"])
|
|
92
|
+
.attr ("tabindex", 0)
|
|
93
|
+
.on ("click", () => this .searchNext ())
|
|
94
|
+
.appendTo (this .search);
|
|
95
|
+
|
|
96
|
+
// Toolbar
|
|
97
|
+
|
|
98
|
+
this .searchButton = $("<span></span>")
|
|
99
|
+
.addClass ("material-icons")
|
|
100
|
+
.css ("transform", "scale(1.2)")
|
|
101
|
+
.attr ("title", _("Show search widget."))
|
|
102
|
+
.text ("search")
|
|
103
|
+
.on ("click", () => this .toggleSearch (!this .config .file .search))
|
|
104
|
+
.appendTo (this .toolbar);
|
|
105
|
+
|
|
106
|
+
$("<span></span>") .addClass ("separator") .appendTo (this .toolbar);
|
|
39
107
|
|
|
40
108
|
this .suspendButton = $("<span></span>")
|
|
41
109
|
.addClass ("material-icons")
|
|
42
110
|
.attr ("title", _("Suspend console output."))
|
|
43
|
-
.text ("
|
|
44
|
-
.
|
|
45
|
-
.
|
|
111
|
+
.text ("pause_circle")
|
|
112
|
+
.on ("click", () => this .setSuspendConsole (!this .suspendConsole))
|
|
113
|
+
.appendTo (this .toolbar);
|
|
46
114
|
|
|
47
115
|
this .clearButton = $("<span></span>")
|
|
48
116
|
.addClass ("material-icons")
|
|
49
117
|
.attr ("title", _("Clear console."))
|
|
50
118
|
.text ("delete_forever")
|
|
51
|
-
.
|
|
52
|
-
.
|
|
119
|
+
.on ("click", () => this .clearConsole ())
|
|
120
|
+
.appendTo (this .toolbar);
|
|
53
121
|
|
|
54
122
|
$("<span></span>") .addClass ("separator") .appendTo (this .toolbar);
|
|
55
123
|
|
|
124
|
+
// Input
|
|
125
|
+
|
|
56
126
|
this .textarea = $("<textarea></textarea>")
|
|
57
127
|
.attr ("placeholder", _("Evaluate X3D Script code here, e.g. type `Browser.name`."))
|
|
58
128
|
.attr ("tabindex", 0)
|
|
59
|
-
.appendTo (this .input)
|
|
60
129
|
.on ("keydown", event => this .onkeydown (event))
|
|
61
|
-
.on ("keyup", event => this .onkeyup (event))
|
|
130
|
+
.on ("keyup", event => this .onkeyup (event))
|
|
131
|
+
.appendTo (this .input);
|
|
62
132
|
|
|
63
133
|
if (this .console .attr ("id") !== "console")
|
|
64
134
|
{
|
|
@@ -75,10 +145,21 @@ module .exports = class Console extends Interface
|
|
|
75
145
|
{
|
|
76
146
|
super .configure ();
|
|
77
147
|
|
|
78
|
-
this .config .file .setDefaultValues ({
|
|
148
|
+
this .config .file .setDefaultValues ({
|
|
149
|
+
history: [ ],
|
|
150
|
+
search: false,
|
|
151
|
+
searchWidth: 285,
|
|
152
|
+
searchCaseSensitive: false,
|
|
153
|
+
});
|
|
79
154
|
|
|
80
155
|
this .history = this .config .file .history .slice (-this .HISTORY_MAX);
|
|
81
156
|
this .historyIndex = this .history .length;
|
|
157
|
+
|
|
158
|
+
this .output .scrollTop (this .output .prop ("scrollHeight"));
|
|
159
|
+
|
|
160
|
+
this .search .width (this .config .file .searchWidth);
|
|
161
|
+
this .toggleSearch (this .config .file .search);
|
|
162
|
+
this .searchCaseSensitive ();
|
|
82
163
|
}
|
|
83
164
|
|
|
84
165
|
async set_browser_initialized ()
|
|
@@ -98,6 +179,8 @@ module .exports = class Console extends Interface
|
|
|
98
179
|
excludes = [
|
|
99
180
|
"The vm module of Node.js is unsupported",
|
|
100
181
|
"Uncaught TypeError: Cannot read properties of null (reading 'removeChild')",
|
|
182
|
+
"aria-hidden",
|
|
183
|
+
"<line>",
|
|
101
184
|
// "Invalid asm.js: Invalid member of stdlib",
|
|
102
185
|
];
|
|
103
186
|
|
|
@@ -108,8 +191,14 @@ module .exports = class Console extends Interface
|
|
|
108
191
|
|
|
109
192
|
const
|
|
110
193
|
classes = [this .logLevels [level] ?? "log", this .logClasses [level]],
|
|
111
|
-
title = sourceId ? `${sourceId}:${line}`: ""
|
|
112
|
-
|
|
194
|
+
title = sourceId ? `${sourceId}:${line}`: "";
|
|
195
|
+
|
|
196
|
+
const text = $(message .split ("\n")
|
|
197
|
+
.map (line => $("<p></p>")
|
|
198
|
+
.addClass (classes)
|
|
199
|
+
.attr ("title", title)
|
|
200
|
+
.text (line)
|
|
201
|
+
.get (0)));
|
|
113
202
|
|
|
114
203
|
if (this .messageTime && performance .now () - this .messageTime > 1000)
|
|
115
204
|
this .output .append ($("<p></p>") .addClass ("splitter"));
|
|
@@ -132,6 +221,8 @@ module .exports = class Console extends Interface
|
|
|
132
221
|
|
|
133
222
|
this .output .append (text);
|
|
134
223
|
this .output .scrollTop (this .output .prop ("scrollHeight"));
|
|
224
|
+
|
|
225
|
+
this .findElements (text, this .currentElement, false);
|
|
135
226
|
}
|
|
136
227
|
|
|
137
228
|
setSuspendConsole (value)
|
|
@@ -158,6 +249,7 @@ module .exports = class Console extends Interface
|
|
|
158
249
|
|
|
159
250
|
this .output .empty ();
|
|
160
251
|
this .addMessage (null, "info", __filename, 0, `Console cleared at ${new Date () .toLocaleTimeString ()}.`);
|
|
252
|
+
this .searchString ();
|
|
161
253
|
}
|
|
162
254
|
|
|
163
255
|
onkeydown (event)
|
|
@@ -244,13 +336,156 @@ module .exports = class Console extends Interface
|
|
|
244
336
|
|
|
245
337
|
try
|
|
246
338
|
{
|
|
247
|
-
console .debug (
|
|
339
|
+
console .debug (this .scriptNode .evaluate (text));
|
|
248
340
|
}
|
|
249
341
|
catch (error)
|
|
250
342
|
{
|
|
251
|
-
console .error (
|
|
343
|
+
console .error (error);
|
|
252
344
|
}
|
|
253
345
|
|
|
254
346
|
this .textarea .val ("");
|
|
255
347
|
}
|
|
348
|
+
|
|
349
|
+
toggleSearch (visible)
|
|
350
|
+
{
|
|
351
|
+
this .config .file .search = visible;
|
|
352
|
+
|
|
353
|
+
if (visible)
|
|
354
|
+
{
|
|
355
|
+
this .searchButton .addClass ("active");
|
|
356
|
+
this .search .show ();
|
|
357
|
+
this .searchInput .trigger ("focus");
|
|
358
|
+
|
|
359
|
+
this .searchString ();
|
|
360
|
+
}
|
|
361
|
+
else
|
|
362
|
+
{
|
|
363
|
+
this .searchButton .removeClass ("active");
|
|
364
|
+
this .search .hide ();
|
|
365
|
+
this .output .find (".selected") .removeClass ("selected");
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
searchString ()
|
|
370
|
+
{
|
|
371
|
+
this .foundElements = [ ];
|
|
372
|
+
|
|
373
|
+
this .findElements (this .output .children (), 0, true);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
findElements (elements, currentElement, scroll)
|
|
377
|
+
{
|
|
378
|
+
if (this .search .is (":hidden"))
|
|
379
|
+
return;
|
|
380
|
+
|
|
381
|
+
const
|
|
382
|
+
toString = this .searchCaseSensitiveButton .hasClass ("active") ? "toString" : "toLowerCase",
|
|
383
|
+
string = this .searchInput .val () [toString] ();
|
|
384
|
+
|
|
385
|
+
if (!string)
|
|
386
|
+
return;
|
|
387
|
+
|
|
388
|
+
this .foundElements = this .foundElements .concat (Array .from (elements, element => $(element))
|
|
389
|
+
.filter (element => element .text () [toString] () .includes (string)));
|
|
390
|
+
|
|
391
|
+
this .updateCurrentElement (currentElement, scroll);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
searchKey (event)
|
|
395
|
+
{
|
|
396
|
+
switch (event .key)
|
|
397
|
+
{
|
|
398
|
+
case "Enter":
|
|
399
|
+
{
|
|
400
|
+
if (!this .foundElements .length)
|
|
401
|
+
break;
|
|
402
|
+
|
|
403
|
+
if (event .shiftKey)
|
|
404
|
+
this .searchPrevious ();
|
|
405
|
+
else
|
|
406
|
+
this .searchNext ();
|
|
407
|
+
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
searchCaseSensitive (value = this .config .file .searchCaseSensitive)
|
|
414
|
+
{
|
|
415
|
+
this .config .file .searchCaseSensitive = value;
|
|
416
|
+
|
|
417
|
+
if (this .config .file .searchCaseSensitive)
|
|
418
|
+
this .searchCaseSensitiveButton .addClass ("active");
|
|
419
|
+
else
|
|
420
|
+
this .searchCaseSensitiveButton .removeClass ("active");
|
|
421
|
+
|
|
422
|
+
this .searchInput .trigger ("focus");
|
|
423
|
+
|
|
424
|
+
this .searchString ();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
searchPrevious ()
|
|
428
|
+
{
|
|
429
|
+
this .updateCurrentElement (this .currentElement - 1);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
searchNext ()
|
|
433
|
+
{
|
|
434
|
+
this .updateCurrentElement (this .currentElement + 1);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
updateCurrentElement (value, scroll = true)
|
|
438
|
+
{
|
|
439
|
+
if (value < 0)
|
|
440
|
+
value = this .foundElements .length - 1;
|
|
441
|
+
|
|
442
|
+
if (value >= this .foundElements .length)
|
|
443
|
+
value = 0;
|
|
444
|
+
|
|
445
|
+
this .currentElement = value;
|
|
446
|
+
|
|
447
|
+
this .output .find (".selected") .removeClass ("selected");
|
|
448
|
+
|
|
449
|
+
if (this .foundElements .length)
|
|
450
|
+
{
|
|
451
|
+
const element = this .foundElements [this .currentElement];
|
|
452
|
+
|
|
453
|
+
element .addClass ("selected");
|
|
454
|
+
|
|
455
|
+
if (scroll)
|
|
456
|
+
{
|
|
457
|
+
element .get (0) .scrollIntoView ({ block: "center", inline: "start", behavior: "smooth" });
|
|
458
|
+
$(window) .scrollTop (0);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
this .searchStatus .text (util .format (_("%d of %d"), this .currentElement + 1, this .foundElements .length));
|
|
462
|
+
this .searchPreviousButton .removeClass ("disabled");
|
|
463
|
+
this .searchNextButton .removeClass ("disabled");
|
|
464
|
+
}
|
|
465
|
+
else
|
|
466
|
+
{
|
|
467
|
+
this .searchStatus .text (`No results`);
|
|
468
|
+
this .searchPreviousButton .addClass ("disabled");
|
|
469
|
+
this .searchNextButton .addClass ("disabled");
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
outputKey (event)
|
|
474
|
+
{
|
|
475
|
+
switch (event .key)
|
|
476
|
+
{
|
|
477
|
+
case "f":
|
|
478
|
+
{
|
|
479
|
+
if (event .ctrlKey || event .metaKey)
|
|
480
|
+
{
|
|
481
|
+
this .searchInput .val (window .getSelection () .toString ());
|
|
482
|
+
this .searchInput .trigger ("select");
|
|
483
|
+
|
|
484
|
+
this .toggleSearch (true);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
256
491
|
};
|
package/src/Editors/Library.js
CHANGED
|
@@ -26,7 +26,7 @@ module .exports = class Materials extends LibraryPane
|
|
|
26
26
|
|
|
27
27
|
this .#list = $("<ul></ul>")
|
|
28
28
|
.appendTo (this .output)
|
|
29
|
-
.addClass ("library-list");
|
|
29
|
+
.addClass (["library-list", "materials"]);
|
|
30
30
|
|
|
31
31
|
const
|
|
32
32
|
canvas = $("<x3d-canvas preserveDrawingBuffer='true' xrSessionMode='NONE'></x3d-canvas>"),
|
|
@@ -51,9 +51,11 @@ module .exports = class Materials extends LibraryPane
|
|
|
51
51
|
|
|
52
52
|
nodes .push ($("<li></li>")
|
|
53
53
|
.addClass (["node", "icon"])
|
|
54
|
-
.text (`${group .getNodeName ()} ${c + 1}`)
|
|
55
54
|
.attr ("group", g)
|
|
56
55
|
.attr ("child", c)
|
|
56
|
+
.append ($("<span></span>")
|
|
57
|
+
.addClass ("text")
|
|
58
|
+
.text (`${group .getNodeName ()} ${c + 1}`))
|
|
57
59
|
.appendTo (this .#list)
|
|
58
60
|
.on ("dblclick", () => this .importX3D (material .getNodeName (), material .toXMLString ())));
|
|
59
61
|
}
|
|
@@ -65,7 +67,7 @@ module .exports = class Materials extends LibraryPane
|
|
|
65
67
|
.css ({ "position": "absolute", "visibility": "hidden" })
|
|
66
68
|
.prependTo ($("body"));
|
|
67
69
|
|
|
68
|
-
await browser .resize (
|
|
70
|
+
await browser .resize (256, 256);
|
|
69
71
|
await browser .replaceWorld (scene);
|
|
70
72
|
|
|
71
73
|
for (const element of Array .from (this .output .find (".node"), e => $(e)))
|