sunrize 1.7.63 → 1.8.1
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 +4 -4
- package/src/Application/ActionKeys.js +3 -3
- package/src/Application/Application.js +5 -1
- package/src/Application/Dashboard.js +87 -6
- package/src/Application/Document.js +167 -24
- package/src/Application/Hierarchy.js +268 -0
- package/src/Application/Selection.js +6 -6
- package/src/Application/Tabs.js +1 -0
- package/src/Components/Grouping/StaticGroup.js +1 -1
- package/src/Components/Grouping/Switch.js +34 -0
- package/src/Components/Navigation/Collision.js +70 -0
- package/src/Components/Navigation/LOD.js +34 -0
- package/src/Editors/Library.js +1 -1
- package/src/Editors/OutlineEditor.js +6 -2
- package/src/Editors/OutlineRouteGraph.js +4 -4
- package/src/Editors/OutlineView.js +210 -63
- package/src/Tools/Core/X3DNodeTool.js +2 -0
- package/src/Tools/EnvironmentalSensor/X3DEnvironmentalSensorNodeTool.x3d +1 -0
- package/src/Tools/Geometry2D/Arc2DTool.js +1 -0
- package/src/Tools/Geometry2D/ArcClose2DTool.js +1 -0
- package/src/Tools/Geometry2D/Circle2DTool.js +1 -0
- package/src/Tools/Geometry2D/Disk2DTool.js +2 -0
- package/src/Tools/Geometry2D/Rectangle2DTool.js +1 -0
- package/src/Tools/Geometry3D/BoxTool.js +1 -0
- package/src/Tools/Geometry3D/ConeTool.js +1 -0
- package/src/Tools/Geometry3D/CylinderTool.js +1 -0
- package/src/Tools/Geometry3D/SphereTool.js +1 -0
- package/src/Tools/Grouping/X3DBoundedObjectTool.x3d +28 -12
- package/src/Tools/Grouping/X3DTransformNodeTool.x3d +30 -12
- package/src/Tools/Lighting/X3DLightNodeTool.x3d +1 -0
- package/src/Tools/Navigation/X3DViewpointNodeTool.x3d +1 -0
- package/src/Tools/SnapTool/SnapSource.js +4 -2
- package/src/Tools/SnapTool/SnapTool.x3d +1 -1
- package/src/Tools/SnapTool/X3DSnapNodeTool.js +8 -6
- package/src/Tools/Sound/ListenerPointSourceTool.x3d +1 -0
- package/src/Tools/Sound/SoundTool.x3d +5 -0
- package/src/Tools/Sound/SpatialSoundTool.x3d +2 -1
- package/src/Tools/TextureProjection/X3DTextureProjectorNodeTool.x3d +1 -0
- package/src/Undo/Editor.js +1 -1
- package/src/Undo/UndoManager.js +4 -4
- package/src/X3D.js +1 -1
- package/src/assets/themes/default-template.css +6 -0
- package/src/assets/themes/default.css +6 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sunrize",
|
|
3
3
|
"productName": "Sunrize X3D Editor",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.8.1",
|
|
5
5
|
"description": "A Multi-Platform X3D Editor",
|
|
6
6
|
"main": "src/main.js",
|
|
7
7
|
"bin": {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"dependencies": {
|
|
91
91
|
"capitalize": "^2.0.4",
|
|
92
92
|
"console": "^0.7.2",
|
|
93
|
-
"electron": "^35.1.
|
|
93
|
+
"electron": "^35.1.4",
|
|
94
94
|
"electron-prompt": "^1.7.0",
|
|
95
95
|
"electron-squirrel-startup": "^1.0.1",
|
|
96
96
|
"electron-tabs": "^1.0.4",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"jquery-ui-dist": "^1.13.3",
|
|
100
100
|
"jstree": "^3.3.17",
|
|
101
101
|
"material-icons": "^1.13.14",
|
|
102
|
-
"material-symbols": "^0.29.
|
|
102
|
+
"material-symbols": "^0.29.3",
|
|
103
103
|
"md5": "^2.3.0",
|
|
104
104
|
"mime-types": "^3.0.1",
|
|
105
105
|
"monaco-editor": "^0.50.0",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"string-similarity": "^4.0.4",
|
|
110
110
|
"tweakpane": "^3.1.10",
|
|
111
111
|
"update-electron-app": "^3.1.1",
|
|
112
|
-
"x_ite": "^11.5.
|
|
112
|
+
"x_ite": "^11.5.2",
|
|
113
113
|
"x3d-traverse": "^1.0.11"
|
|
114
114
|
}
|
|
115
115
|
}
|
|
@@ -58,7 +58,7 @@ module .exports = new class ActionKeys
|
|
|
58
58
|
if (this .value === value)
|
|
59
59
|
return;
|
|
60
60
|
|
|
61
|
-
this
|
|
61
|
+
this .#processInterests ();
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
onkeyup (event)
|
|
@@ -94,7 +94,7 @@ module .exports = new class ActionKeys
|
|
|
94
94
|
if (this .value === value)
|
|
95
95
|
return;
|
|
96
96
|
|
|
97
|
-
this
|
|
97
|
+
this .#processInterests ();
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
#interests = new Map ();
|
|
@@ -109,7 +109,7 @@ module .exports = new class ActionKeys
|
|
|
109
109
|
this .#interests .delete (key);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
processInterests ()
|
|
112
|
+
#processInterests ()
|
|
113
113
|
{
|
|
114
114
|
for (const callback of this .#interests .values ())
|
|
115
115
|
callback (this .value);
|
|
@@ -288,7 +288,7 @@ module .exports = class Application
|
|
|
288
288
|
},
|
|
289
289
|
{ type: "separator" },
|
|
290
290
|
{
|
|
291
|
-
label: _("
|
|
291
|
+
label: _("Enable Browser Update on Load"),
|
|
292
292
|
type: "checkbox",
|
|
293
293
|
checked: this .config .browserUpdate,
|
|
294
294
|
click: () =>
|
|
@@ -789,6 +789,10 @@ module .exports = class Application
|
|
|
789
789
|
label: _("Center Snap Target in Selection"),
|
|
790
790
|
click: () => this .mainWindow .webContents .send ("center-snap-target-in-selection"),
|
|
791
791
|
},
|
|
792
|
+
{
|
|
793
|
+
label: _("Center Snap Source in Selection"),
|
|
794
|
+
click: () => this .mainWindow .webContents .send ("center-snap-source-in-selection"),
|
|
795
|
+
},
|
|
792
796
|
{
|
|
793
797
|
label: _("Move Selection to Snap Target"),
|
|
794
798
|
accelerator: "CmdOrCtrl+M",
|
|
@@ -9,11 +9,12 @@ const
|
|
|
9
9
|
|
|
10
10
|
module .exports = class Dashboard extends Interface
|
|
11
11
|
{
|
|
12
|
-
constructor (element)
|
|
12
|
+
constructor (element, document)
|
|
13
13
|
{
|
|
14
14
|
super ("Sunrize.Dashboard.");
|
|
15
15
|
|
|
16
|
-
this .
|
|
16
|
+
this .document = document;
|
|
17
|
+
this .toolbar = element;
|
|
17
18
|
|
|
18
19
|
this .setup ();
|
|
19
20
|
}
|
|
@@ -44,12 +45,41 @@ module .exports = class Dashboard extends Interface
|
|
|
44
45
|
|
|
45
46
|
$("<span></span>") .addClass ("separator") .appendTo (this .toolbar);
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
const hierarchy = require ("./Hierarchy");
|
|
49
|
+
|
|
50
|
+
this .upButton = $("<span></span>")
|
|
51
|
+
.addClass (["material-icons", "disabled"])
|
|
52
|
+
.attr ("title", _("Select parent node(s)."))
|
|
53
|
+
.css ({ transform: "rotate(-90deg) scaleX(0.8)", "margin-top": "-6px", "margin-bottom": "-7px" })
|
|
54
|
+
.text ("play_arrow")
|
|
55
|
+
.appendTo (this .toolbar)
|
|
56
|
+
.on ("click", () => this .selectParent ());
|
|
57
|
+
|
|
58
|
+
this .downButton = $("<span></span>")
|
|
59
|
+
.addClass (["material-icons", "disabled"])
|
|
60
|
+
.attr ("title", _("Select child node(s)."))
|
|
61
|
+
.css ({ transform: "rotate(90deg) scaleX(0.8)", "margin-top": "-7px", "margin-bottom": "-6px" })
|
|
62
|
+
.text ("play_arrow")
|
|
63
|
+
.appendTo (this .toolbar)
|
|
64
|
+
.on ("click", () => this .selectChild ());
|
|
65
|
+
|
|
66
|
+
hierarchy .addInterest (this, () => this .onHierarchy ());
|
|
67
|
+
|
|
68
|
+
$("<span></span>") .addClass ("separator") .appendTo (this .toolbar);
|
|
69
|
+
|
|
70
|
+
this .viewSelectedButton = $("<span></span>")
|
|
48
71
|
.addClass (["material-symbols-outlined"])
|
|
49
72
|
.attr ("title", _("Look at selected objects."))
|
|
50
73
|
.text ("center_focus_strong")
|
|
51
74
|
.appendTo (this .toolbar)
|
|
52
|
-
.on ("click", () => this .viewAll ());
|
|
75
|
+
.on ("click", () => this .viewAll (true));
|
|
76
|
+
|
|
77
|
+
this .viewAllButton = $("<span></span>")
|
|
78
|
+
.addClass (["material-symbols-outlined"])
|
|
79
|
+
.attr ("title", _("Look at all objects in active layer."))
|
|
80
|
+
.text ("zoom_out_map")
|
|
81
|
+
.appendTo (this .toolbar)
|
|
82
|
+
.on ("click", () => this .viewAll (false));
|
|
53
83
|
|
|
54
84
|
this .straightenButton = $("<span></span>")
|
|
55
85
|
.addClass (["material-symbols-outlined", "active"])
|
|
@@ -130,13 +160,64 @@ module .exports = class Dashboard extends Interface
|
|
|
130
160
|
this .playButton .removeClass ("active");
|
|
131
161
|
}
|
|
132
162
|
|
|
133
|
-
|
|
163
|
+
selectParent ()
|
|
164
|
+
{
|
|
165
|
+
this .selectHierarchy ("up");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
selectChild ()
|
|
169
|
+
{
|
|
170
|
+
this .selectHierarchy ("down");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
selectHierarchy (direction)
|
|
174
|
+
{
|
|
175
|
+
const
|
|
176
|
+
hierarchy = require ("./Hierarchy"),
|
|
177
|
+
outlineEditor = this .document .sidebar .outlineEditor,
|
|
178
|
+
nodes = hierarchy [direction] ();
|
|
179
|
+
|
|
180
|
+
for (const node of nodes)
|
|
181
|
+
outlineEditor .expandTo (node, { expandObject: true, expandAll: true });
|
|
182
|
+
|
|
183
|
+
const elements = nodes .map (node => outlineEditor .sceneGraph .find (`.node[node-id=${node .getId ()}]`));
|
|
184
|
+
|
|
185
|
+
for (const [i, element] of elements .entries ())
|
|
186
|
+
outlineEditor .selectNodeElement (element, { add: i > 0 });
|
|
187
|
+
|
|
188
|
+
// Scroll element into view.
|
|
189
|
+
// Hide scrollbars during scroll to prevent overlay issue.
|
|
190
|
+
|
|
191
|
+
outlineEditor .treeView .css ("overflow", "hidden");
|
|
192
|
+
|
|
193
|
+
elements [0] ?.[0] ?.scrollIntoView ({ block: "center", inline: "start", behavior: "smooth" });
|
|
194
|
+
$(window) .scrollTop (0);
|
|
195
|
+
|
|
196
|
+
setTimeout (() => outlineEditor .treeView .css ("overflow", ""), 1000);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
onHierarchy ()
|
|
200
|
+
{
|
|
201
|
+
const hierarchy = require ("./Hierarchy");
|
|
202
|
+
|
|
203
|
+
if (hierarchy .canUp ())
|
|
204
|
+
this .upButton .removeClass ("disabled");
|
|
205
|
+
else
|
|
206
|
+
this .upButton .addClass ("disabled");
|
|
207
|
+
|
|
208
|
+
if (hierarchy .canDown ())
|
|
209
|
+
this .downButton .removeClass ("disabled");
|
|
210
|
+
else
|
|
211
|
+
this .downButton .addClass ("disabled");
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
viewAll (selected)
|
|
134
215
|
{
|
|
135
216
|
const
|
|
136
217
|
selection = require ("./Selection"),
|
|
137
218
|
nodes = selection .nodes;
|
|
138
219
|
|
|
139
|
-
if (nodes .length)
|
|
220
|
+
if (selected && nodes .length)
|
|
140
221
|
{
|
|
141
222
|
const
|
|
142
223
|
executionContext = this .browser .currentScene,
|
|
@@ -28,9 +28,6 @@ module .exports = class Document extends Interface
|
|
|
28
28
|
{
|
|
29
29
|
super ("Sunrize.Document.");
|
|
30
30
|
|
|
31
|
-
// Add X3D to window to provide access in Script nodes.
|
|
32
|
-
window .X3D = X3D;
|
|
33
|
-
|
|
34
31
|
// Globals
|
|
35
32
|
|
|
36
33
|
this .config .global .setDefaultValues ({
|
|
@@ -41,7 +38,7 @@ module .exports = class Document extends Interface
|
|
|
41
38
|
|
|
42
39
|
this .verticalSplitter = new Splitter ($("#vertical-splitter"), "vertical");
|
|
43
40
|
this .horizontalSplitter = new Splitter ($("#horizontal-splitter"), "horizontal");
|
|
44
|
-
this .secondaryToolbar = new Dashboard ($("#secondary-toolbar"));
|
|
41
|
+
this .secondaryToolbar = new Dashboard ($("#secondary-toolbar"), this);
|
|
45
42
|
this .footer = new Footer ($("#footer"));
|
|
46
43
|
this .sidebar = new Sidebar ($("#sidebar"));
|
|
47
44
|
|
|
@@ -120,6 +117,7 @@ module .exports = class Document extends Interface
|
|
|
120
117
|
electron .ipcRenderer .on ("activate-snap-target", (event, visible) => this .activateSnapTarget (visible));
|
|
121
118
|
electron .ipcRenderer .on ("activate-snap-source", (event, visible) => this .activateSnapSource (visible));
|
|
122
119
|
electron .ipcRenderer .on ("center-snap-target-in-selection", () => this .centerSnapTargetInSelection ());
|
|
120
|
+
electron .ipcRenderer .on ("center-snap-source-in-selection", () => this .centerSnapSourceInSelection ());
|
|
123
121
|
electron .ipcRenderer .on ("move-selection-to-snap-target", () => this .moveSelectionToSnapTarget ());
|
|
124
122
|
electron .ipcRenderer .on ("move-selection-center-to-snap-target", () => this .moveSelectionCenterToSnapTarget ());
|
|
125
123
|
|
|
@@ -166,9 +164,10 @@ module .exports = class Document extends Interface
|
|
|
166
164
|
|
|
167
165
|
// Connect for Snap Target and Snap Source.
|
|
168
166
|
|
|
169
|
-
$(this .browser .element
|
|
167
|
+
$(this .browser .element)
|
|
170
168
|
.on ("mousedown", event => this .onmousedown (event))
|
|
171
|
-
.on ("mouseup", event => this .
|
|
169
|
+
.on ("mouseup", event => this .onsnaptool (event))
|
|
170
|
+
.on ("mouseup", event => this .onselect (event));
|
|
172
171
|
|
|
173
172
|
// Load components.
|
|
174
173
|
|
|
@@ -178,6 +177,9 @@ module .exports = class Document extends Interface
|
|
|
178
177
|
// Modify nodes.
|
|
179
178
|
|
|
180
179
|
this .browser .updateConcreteNode (require ("../Components/Grouping/StaticGroup"));
|
|
180
|
+
this .browser .updateConcreteNode (require ("../Components/Grouping/Switch"));
|
|
181
|
+
this .browser .updateConcreteNode (require ("../Components/Navigation/Collision"));
|
|
182
|
+
this .browser .updateConcreteNode (require ("../Components/Navigation/LOD"));
|
|
181
183
|
|
|
182
184
|
require ("../Components");
|
|
183
185
|
|
|
@@ -939,48 +941,79 @@ Viewpoint {
|
|
|
939
941
|
}
|
|
940
942
|
}
|
|
941
943
|
|
|
944
|
+
#select = false;
|
|
945
|
+
#pointer = new X3D .Vector2 ();
|
|
942
946
|
#snapTarget = null;
|
|
943
947
|
#snapSource = null;
|
|
944
948
|
|
|
945
949
|
async onmousedown (event)
|
|
946
950
|
{
|
|
947
|
-
|
|
951
|
+
this .#select = false;
|
|
952
|
+
|
|
953
|
+
if (!this .secondaryToolbar .arrowButton .hasClass ("active"))
|
|
948
954
|
return;
|
|
949
955
|
|
|
950
|
-
switch (
|
|
956
|
+
switch (event .button)
|
|
951
957
|
{
|
|
952
|
-
case
|
|
958
|
+
case 0:
|
|
953
959
|
{
|
|
954
|
-
if (
|
|
955
|
-
|
|
960
|
+
if (event .shiftKey && (event .ctrlKey || event .metaKey))
|
|
961
|
+
return;
|
|
956
962
|
|
|
957
|
-
this .
|
|
963
|
+
this .#pointer .assign (this .browser .getPointerFromEvent (event));
|
|
958
964
|
|
|
959
|
-
|
|
965
|
+
if (this .browser .touch (... this .#pointer))
|
|
966
|
+
{
|
|
967
|
+
if (this .browser .getHit () .sensors .size)
|
|
968
|
+
return;
|
|
969
|
+
|
|
970
|
+
this .#select = true;
|
|
971
|
+
}
|
|
972
|
+
else
|
|
973
|
+
{
|
|
974
|
+
this .#select = true;
|
|
975
|
+
}
|
|
960
976
|
|
|
961
|
-
this .#snapTarget .onmousedown (event, true);
|
|
962
977
|
break;
|
|
963
978
|
}
|
|
964
|
-
case
|
|
979
|
+
case 2:
|
|
965
980
|
{
|
|
966
|
-
|
|
967
|
-
|
|
981
|
+
switch (ActionKeys .value)
|
|
982
|
+
{
|
|
983
|
+
case ActionKeys .None:
|
|
984
|
+
{
|
|
985
|
+
if (this .#snapTarget ?._visible .getValue ())
|
|
986
|
+
break;
|
|
987
|
+
|
|
988
|
+
this .activateSnapTarget (true);
|
|
989
|
+
|
|
990
|
+
await this .#snapTarget .getToolInstance ();
|
|
991
|
+
|
|
992
|
+
this .#snapTarget .onmousedown (event, true);
|
|
993
|
+
break;
|
|
994
|
+
}
|
|
995
|
+
case ActionKeys .Option:
|
|
996
|
+
{
|
|
997
|
+
if (this .#snapSource ?._visible .getValue ())
|
|
998
|
+
break;
|
|
999
|
+
|
|
1000
|
+
this .activateSnapSource (true);
|
|
968
1001
|
|
|
969
|
-
|
|
1002
|
+
await this .#snapSource .getToolInstance ();
|
|
970
1003
|
|
|
971
|
-
|
|
1004
|
+
this .#snapSource .onmousedown (event, true);
|
|
1005
|
+
break;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
972
1008
|
|
|
973
|
-
this .#snapSource .onmousedown (event, true);
|
|
974
1009
|
break;
|
|
975
1010
|
}
|
|
976
1011
|
}
|
|
1012
|
+
|
|
977
1013
|
}
|
|
978
1014
|
|
|
979
|
-
async
|
|
1015
|
+
async onsnaptool (event)
|
|
980
1016
|
{
|
|
981
|
-
if (ActionKeys .value & ActionKeys .Control)
|
|
982
|
-
event .button = 2;
|
|
983
|
-
|
|
984
1017
|
if (event .button !== 2)
|
|
985
1018
|
return;
|
|
986
1019
|
|
|
@@ -991,6 +1024,94 @@ Viewpoint {
|
|
|
991
1024
|
this .#snapTarget ?.onmouseup (event);
|
|
992
1025
|
}
|
|
993
1026
|
|
|
1027
|
+
onselect (event)
|
|
1028
|
+
{
|
|
1029
|
+
if (!this .secondaryToolbar .arrowButton .hasClass ("active"))
|
|
1030
|
+
return;
|
|
1031
|
+
|
|
1032
|
+
if (event .button !== 0)
|
|
1033
|
+
return;
|
|
1034
|
+
|
|
1035
|
+
if (!this .#select)
|
|
1036
|
+
return;
|
|
1037
|
+
|
|
1038
|
+
const pointer = this .browser .getPointerFromEvent (event);
|
|
1039
|
+
|
|
1040
|
+
if (this .#pointer .distance (pointer) > this .browser .getRenderingProperty ("ContentScale"))
|
|
1041
|
+
return;
|
|
1042
|
+
|
|
1043
|
+
// Stop event propagation.
|
|
1044
|
+
|
|
1045
|
+
event .preventDefault ();
|
|
1046
|
+
|
|
1047
|
+
// Select or deselect.
|
|
1048
|
+
|
|
1049
|
+
const outlineEditor = this .sidebar .outlineEditor;
|
|
1050
|
+
|
|
1051
|
+
if (!this .browser .touch (... pointer))
|
|
1052
|
+
{
|
|
1053
|
+
outlineEditor .deselectAll ();
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
// Select.
|
|
1058
|
+
|
|
1059
|
+
const
|
|
1060
|
+
shapeNode = this .browser .getHit () .shapeNode,
|
|
1061
|
+
geometryTool = shapeNode .getGeometry () ?.getTool (),
|
|
1062
|
+
tool = geometryTool ?? shapeNode .getExecutionContext () .getOuterNode () ?.getTool (),
|
|
1063
|
+
node = tool ?? shapeNode;
|
|
1064
|
+
|
|
1065
|
+
outlineEditor .expandTo (node, { expandObject: true, expandAll: true });
|
|
1066
|
+
|
|
1067
|
+
let elements = outlineEditor .sceneGraph .find (`.node[node-id=${node .getId ()}]`);
|
|
1068
|
+
|
|
1069
|
+
if (!elements .length)
|
|
1070
|
+
return;
|
|
1071
|
+
|
|
1072
|
+
if (outlineEditor .isEditable (elements))
|
|
1073
|
+
{
|
|
1074
|
+
if (tool)
|
|
1075
|
+
{
|
|
1076
|
+
elements = Array .from (elements);
|
|
1077
|
+
}
|
|
1078
|
+
else
|
|
1079
|
+
{
|
|
1080
|
+
const parentElements = Array .from (elements) .flatMap (element =>
|
|
1081
|
+
{
|
|
1082
|
+
const parentElements = Array .from ($(element) .parent () .closest (".node", outlineEditor .sceneGraph));
|
|
1083
|
+
|
|
1084
|
+
return parentElements .length ? parentElements : element;
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
elements = parentElements .map ((element, i) => outlineEditor .getNode ($(element)) .getType () .includes (X3D .X3DConstants .X3DGroupingNode) ? parentElements [i] : elements [i]);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
else
|
|
1091
|
+
{
|
|
1092
|
+
while (!outlineEditor .isEditable (elements))
|
|
1093
|
+
{
|
|
1094
|
+
elements .jstree ("close_node", elements);
|
|
1095
|
+
elements = elements .parent () .closest (".node, .scene", outlineEditor .sceneGraph);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
elements = Array .from (elements);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
for (const [i, element] of elements .entries ())
|
|
1102
|
+
outlineEditor .selectNodeElement ($(element), { add: (event .shiftKey || event .metaKey) || i > 0, target: true });
|
|
1103
|
+
|
|
1104
|
+
// Scroll element into view.
|
|
1105
|
+
// Hide scrollbars during scroll to prevent overlay issue.
|
|
1106
|
+
|
|
1107
|
+
outlineEditor .treeView .css ("overflow", "hidden");
|
|
1108
|
+
|
|
1109
|
+
elements [0] ?.scrollIntoView ({ block: "center", inline: "start", behavior: "smooth" });
|
|
1110
|
+
$(window) .scrollTop (0);
|
|
1111
|
+
|
|
1112
|
+
setTimeout (() => outlineEditor .treeView .css ("overflow", ""), 1000);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
994
1115
|
activateSnapTarget (visible)
|
|
995
1116
|
{
|
|
996
1117
|
const SnapTarget = require ("../Tools/SnapTool/SnapTarget");
|
|
@@ -1035,6 +1156,28 @@ Viewpoint {
|
|
|
1035
1156
|
UndoManager .shared .endUndo ();
|
|
1036
1157
|
}
|
|
1037
1158
|
|
|
1159
|
+
async centerSnapSourceInSelection ()
|
|
1160
|
+
{
|
|
1161
|
+
this .activateSnapSource (true);
|
|
1162
|
+
|
|
1163
|
+
const
|
|
1164
|
+
selection = require ("./Selection"),
|
|
1165
|
+
source = await this .#snapSource .getToolInstance (),
|
|
1166
|
+
executionContext = this .browser .currentScene,
|
|
1167
|
+
layerNode = this .browser .getActiveLayer (),
|
|
1168
|
+
nodes = selection .nodes,
|
|
1169
|
+
[values, bbox] = Editor .getModelMatricesAndBBoxes (executionContext, layerNode, nodes);
|
|
1170
|
+
|
|
1171
|
+
if (!bbox .size .magnitude ())
|
|
1172
|
+
return;
|
|
1173
|
+
|
|
1174
|
+
UndoManager .shared .beginUndo (_("Center SnapSource in Selection"));
|
|
1175
|
+
|
|
1176
|
+
Editor .setFieldValue (executionContext, source .getValue (), source .position, bbox .center);
|
|
1177
|
+
|
|
1178
|
+
UndoManager .shared .endUndo ();
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1038
1181
|
async moveSelectionToSnapTarget ()
|
|
1039
1182
|
{
|
|
1040
1183
|
const
|