sunrize 1.7.63 → 1.8.0

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.
Files changed (40) hide show
  1. package/package.json +4 -4
  2. package/src/Application/ActionKeys.js +3 -3
  3. package/src/Application/Application.js +1 -1
  4. package/src/Application/Dashboard.js +87 -6
  5. package/src/Application/Document.js +144 -24
  6. package/src/Application/Hierarchy.js +268 -0
  7. package/src/Application/Selection.js +6 -6
  8. package/src/Components/Grouping/StaticGroup.js +1 -1
  9. package/src/Components/Grouping/Switch.js +34 -0
  10. package/src/Components/Navigation/Collision.js +70 -0
  11. package/src/Components/Navigation/LOD.js +34 -0
  12. package/src/Editors/Library.js +1 -1
  13. package/src/Editors/OutlineEditor.js +6 -2
  14. package/src/Editors/OutlineRouteGraph.js +4 -4
  15. package/src/Editors/OutlineView.js +210 -63
  16. package/src/Tools/Core/X3DNodeTool.js +2 -0
  17. package/src/Tools/EnvironmentalSensor/X3DEnvironmentalSensorNodeTool.x3d +1 -0
  18. package/src/Tools/Geometry2D/Arc2DTool.js +1 -0
  19. package/src/Tools/Geometry2D/ArcClose2DTool.js +1 -0
  20. package/src/Tools/Geometry2D/Circle2DTool.js +1 -0
  21. package/src/Tools/Geometry2D/Disk2DTool.js +2 -0
  22. package/src/Tools/Geometry2D/Rectangle2DTool.js +1 -0
  23. package/src/Tools/Geometry3D/BoxTool.js +1 -0
  24. package/src/Tools/Geometry3D/ConeTool.js +1 -0
  25. package/src/Tools/Geometry3D/CylinderTool.js +1 -0
  26. package/src/Tools/Geometry3D/SphereTool.js +1 -0
  27. package/src/Tools/Grouping/X3DBoundedObjectTool.x3d +28 -12
  28. package/src/Tools/Grouping/X3DTransformNodeTool.x3d +30 -12
  29. package/src/Tools/Lighting/X3DLightNodeTool.x3d +1 -0
  30. package/src/Tools/Navigation/X3DViewpointNodeTool.x3d +1 -0
  31. package/src/Tools/SnapTool/X3DSnapNodeTool.js +8 -6
  32. package/src/Tools/Sound/ListenerPointSourceTool.x3d +1 -0
  33. package/src/Tools/Sound/SoundTool.x3d +5 -0
  34. package/src/Tools/Sound/SpatialSoundTool.x3d +2 -1
  35. package/src/Tools/TextureProjection/X3DTextureProjectorNodeTool.x3d +1 -0
  36. package/src/Undo/Editor.js +1 -1
  37. package/src/Undo/UndoManager.js +4 -4
  38. package/src/X3D.js +1 -1
  39. package/src/assets/themes/default-template.css +6 -0
  40. package/src/assets/themes/default.css +6 -0
@@ -289,32 +289,60 @@ module .exports = class OutlineView extends Interface
289
289
  child .find (".node .name")
290
290
  .on ("mouseenter", this .updateNodeTitle .bind (this));
291
291
 
292
- child .find (".toggle-visibility")
293
- .on ("click", this .toggleVisibility .bind (this));
292
+ child .find ("[action]")
293
+ .on ("click", this .nodeAction .bind (this));
294
+ }
294
295
 
295
- child .find (".toggle-tool")
296
- .on ("click", this .toggleTool .bind (this));
296
+ nodeAction (event)
297
+ {
298
+ const button = $(event .target);
297
299
 
298
- child .find (".activate-layer")
299
- .on ("click", this .activateLayer .bind (this));
300
+ switch (button .attr ("action"))
301
+ {
302
+ case "toggle-visibility":
303
+ this .toggleVisibility (event);
304
+ break;
300
305
 
301
- child .find (".bind-node")
302
- .on ("click", this .bindNode .bind (this));
306
+ case "toggle-tool":
307
+ this .toggleTool (event);
308
+ break;
309
+
310
+ case "proxy-display":
311
+ this .proxyDisplay (event);
312
+ break;
313
+
314
+ case "activate-layer":
315
+ this .activateLayer (event);
316
+ break;
317
+
318
+ case "bind-node":
319
+ this .bindNode (event);
320
+ break;
321
+
322
+ case "play-node":
323
+ this .playNode (event);
324
+ break;
303
325
 
304
- child .find (".play-node")
305
- .on ("click", this .playNode .bind (this));
326
+ case "stop-node":
327
+ this .stopNode (event);
328
+ break;
306
329
 
307
- child .find (".stop-node")
308
- .on ("click", this .stopNode .bind (this));
330
+ case "loop-node":
331
+ this .loopNode (event);
332
+ break;
309
333
 
310
- child .find (".loop-node")
311
- .on ("click", this .loopNode .bind (this));
334
+ case "reload-node":
335
+ this .reloadNode (event);
336
+ break;
312
337
 
313
- child .find (".reload-node")
314
- .on ("click", this .reloadNode .bind (this));
338
+ case "show-preview":
339
+ this .showPreview (event);
340
+ break;
315
341
 
316
- child .find (".show-preview")
317
- .on ("click", this .showPreview .bind (this));
342
+ case "show-branch":
343
+ this .showBranch (event);
344
+ break;
345
+ }
318
346
  }
319
347
 
320
348
  connectFieldActions (child)
@@ -1043,7 +1071,7 @@ module .exports = class OutlineView extends Interface
1043
1071
 
1044
1072
  // Add buttons to name.
1045
1073
 
1046
- this .addNodeButtons (node, name);
1074
+ this .addNodeButtons (this .getNode (parent), node, name);
1047
1075
 
1048
1076
  // Append empty tree to enable expander.
1049
1077
 
@@ -1061,7 +1089,7 @@ module .exports = class OutlineView extends Interface
1061
1089
  return child;
1062
1090
  }
1063
1091
 
1064
- addNodeButtons (node, name)
1092
+ addNodeButtons (parent, node, name)
1065
1093
  {
1066
1094
  // Add buttons to name.
1067
1095
 
@@ -1074,7 +1102,8 @@ module .exports = class OutlineView extends Interface
1074
1102
  buttons .push ($("<span></span>")
1075
1103
  .attr ("order", "0")
1076
1104
  .attr ("title", "Toggle visibility.")
1077
- .addClass (["toggle-visibility", "button", "material-symbols-outlined"])
1105
+ .attr ("action", "toggle-visibility")
1106
+ .addClass (["button", "material-symbols-outlined"])
1078
1107
  .addClass (node .isHidden () ? "off" : "on")
1079
1108
  .text (node .isHidden () ? "visibility_off" : "visibility"));
1080
1109
  }
@@ -1084,7 +1113,8 @@ module .exports = class OutlineView extends Interface
1084
1113
  buttons .push ($("<span></span>")
1085
1114
  .attr ("order", "1")
1086
1115
  .attr ("title", _("Toggle display tool."))
1087
- .addClass (["toggle-tool", "button", "material-symbols-outlined"])
1116
+ .attr ("action", "toggle-tool")
1117
+ .addClass (["button", "material-symbols-outlined"])
1088
1118
  .addClass (node .valueOf () === node ? "off" : "on")
1089
1119
  .text ("build_circle"));
1090
1120
  }
@@ -1094,16 +1124,29 @@ module .exports = class OutlineView extends Interface
1094
1124
  {
1095
1125
  switch (type)
1096
1126
  {
1127
+ case X3D .X3DConstants .Collision:
1128
+ {
1129
+ buttons .push ($("<span></span>")
1130
+ .attr ("order", "2")
1131
+ .attr ("title", _("Display proxy node."))
1132
+ .attr ("action", "proxy-display")
1133
+ .addClass (["button", "material-symbols-outlined"])
1134
+ .addClass (node .getProxyDisplay () ? "on" : "off")
1135
+ .text ("highlight_mouse_cursor"));
1136
+
1137
+ break;
1138
+ }
1097
1139
  case X3D .X3DConstants .X3DLayerNode:
1098
1140
  {
1099
1141
  if (node .getExecutionContext () !== this .executionContext)
1100
1142
  continue;
1101
1143
 
1102
1144
  buttons .push ($("<span></span>")
1103
- .attr ("order", "2")
1145
+ .attr ("order", "3")
1104
1146
  .attr ("title", _("Activate layer."))
1105
- .addClass (["activate-layer", "button", "material-symbols-outlined"])
1106
- .addClass (this .browser .getActiveLayer () === node ? "green" : "off")
1147
+ .attr ("action", "activate-layer")
1148
+ .addClass (["button", "material-symbols-outlined"])
1149
+ .addClass (this .browser .getActiveLayer () === node ? "on" : "off")
1107
1150
  .text ("check_circle"));
1108
1151
 
1109
1152
  continue;
@@ -1116,9 +1159,10 @@ module .exports = class OutlineView extends Interface
1116
1159
  node ._isBound .addFieldCallback (this .#updateNodeBoundSymbol, this .updateNodeBound .bind (this, node));
1117
1160
 
1118
1161
  buttons .push ($("<span></span>")
1119
- .attr ("order", "3")
1162
+ .attr ("order", "4")
1120
1163
  .attr ("title", _("Bind node."))
1121
- .addClass (["bind-node", "button", "material-symbols-outlined"])
1164
+ .attr ("action", "bind-node")
1165
+ .addClass (["button", "material-symbols-outlined"])
1122
1166
  .addClass (node ._isBound .getValue () ? "on" : "off")
1123
1167
  .text (node ._isBound .getValue () ? "radio_button_checked" : "radio_button_unchecked"));
1124
1168
 
@@ -1135,23 +1179,26 @@ module .exports = class OutlineView extends Interface
1135
1179
  node ._loop .addFieldCallback (this .#updateNodePlaySymbol, this .updateNodePlay .bind (this, node));
1136
1180
 
1137
1181
  buttons .push ($("<span></span>")
1138
- .attr ("order", "4")
1182
+ .attr ("order", "5")
1139
1183
  .attr ("title", node ._isActive .getValue () && !node ._isPaused .getValue () ? _("Pause timer.") : _("Start timer."))
1140
- .addClass (["play-node", "button", "material-icons"])
1184
+ .attr ("action", "play-node")
1185
+ .addClass (["button", "material-icons"])
1141
1186
  .addClass (node ._isPaused .getValue () ? "on" : "off")
1142
1187
  .text (node ._isActive .getValue () ? "pause" : "play_arrow"));
1143
1188
 
1144
1189
  buttons .push ($("<span></span>")
1145
- .attr ("order", "5")
1190
+ .attr ("order", "6")
1146
1191
  .attr ("title", _("Stop timer."))
1147
- .addClass (["stop-node", "button", "material-icons"])
1192
+ .attr ("action", "stop-node")
1193
+ .addClass (["button", "material-icons"])
1148
1194
  .addClass (node ._isActive .getValue () ? "on" : "off")
1149
1195
  .text ("stop"));
1150
1196
 
1151
1197
  buttons .push ($("<span></span>")
1152
- .attr ("order", "6")
1198
+ .attr ("order", "7")
1153
1199
  .attr ("title", _("Toggle loop."))
1154
- .addClass (["loop-node", "button", "material-icons"])
1200
+ .attr ("action", "loop-node")
1201
+ .addClass (["button", "material-icons"])
1155
1202
  .addClass (node ._loop .getValue () ? "on" : "off")
1156
1203
  .text ("repeat"));
1157
1204
 
@@ -1173,9 +1220,10 @@ module .exports = class OutlineView extends Interface
1173
1220
  node .getLoadState () .addFieldCallback (this .#updateNodeLoadStateSymbol, this .updateNodeLoadState .bind (this, node));
1174
1221
 
1175
1222
  buttons .push ($("<span></span>")
1176
- .attr ("order", "7")
1223
+ .attr ("order", "8")
1177
1224
  .attr ("title", "Load now.")
1178
- .addClass (["reload-node", "button", "material-symbols-outlined", className])
1225
+ .attr ("action", "reload-node")
1226
+ .addClass (["button", "material-symbols-outlined", className])
1179
1227
  .text ("autorenew"));
1180
1228
 
1181
1229
  continue;
@@ -1186,9 +1234,10 @@ module .exports = class OutlineView extends Interface
1186
1234
  case X3D .X3DConstants .X3DSingleTextureNode:
1187
1235
  {
1188
1236
  buttons .push ($("<span></span>")
1189
- .attr ("order", "8")
1237
+ .attr ("order", "9")
1190
1238
  .attr ("title", _("Show preview."))
1191
- .addClass (["show-preview", "button", "material-symbols-outlined", "off"])
1239
+ .attr ("action", "show-preview")
1240
+ .addClass (["button", "material-symbols-outlined", "off"])
1192
1241
  .css ("top", "2px")
1193
1242
  .text ("preview"));
1194
1243
 
@@ -1197,6 +1246,26 @@ module .exports = class OutlineView extends Interface
1197
1246
  }
1198
1247
  }
1199
1248
 
1249
+ for (const type of parent .getType ())
1250
+ {
1251
+ switch (type)
1252
+ {
1253
+ case X3D .X3DConstants .LOD:
1254
+ case X3D .X3DConstants .Switch:
1255
+ {
1256
+ buttons .push ($("<span></span>")
1257
+ .attr ("order", "10")
1258
+ .attr ("title", _("Show branch."))
1259
+ .attr ("action", "show-branch")
1260
+ .addClass (["button", "material-symbols-outlined"])
1261
+ .addClass (parent .getEditChild () === node ? "on" : "off")
1262
+ .text ("highlight_mouse_cursor"));
1263
+
1264
+ break;
1265
+ }
1266
+ }
1267
+ }
1268
+
1200
1269
  buttons .sort ((a, b) => a .attr ("order") - b .attr ("order"))
1201
1270
 
1202
1271
  for (const button of buttons)
@@ -1249,17 +1318,20 @@ module .exports = class OutlineView extends Interface
1249
1318
 
1250
1319
  updateActiveLayer ()
1251
1320
  {
1252
- this .sceneGraph .find (".activate-layer") .removeClass ("green") .addClass ("off");
1321
+ const node = this .browser .getActiveLayer ();
1322
+
1323
+ this .sceneGraph .find ("[action=activate-layer]") .addClass ("off");
1253
1324
 
1254
- if (!this .browser .getActiveLayer ())
1325
+ if (!node)
1255
1326
  return;
1256
1327
 
1257
- this .sceneGraph .find (`.node[node-id=${this .browser .getActiveLayer () .getId ()}],
1258
- .imported-node[node-id=${this .browser .getActiveLayer () .getId ()}],
1259
- .exported-node[node-id=${this .browser .getActiveLayer () .getId ()}]`)
1260
- .find ("> .item .activate-layer")
1328
+ this .sceneGraph
1329
+ .find (`.node[node-id=${node .getId ()}],
1330
+ .imported-node[node-id=${node .getId ()}],
1331
+ .exported-node[node-id=${node .getId ()}]`)
1332
+ .find ("> .item [action=activate-layer]")
1261
1333
  .removeClass ("off")
1262
- .addClass ("green");
1334
+ .addClass ("on");
1263
1335
  }
1264
1336
 
1265
1337
  updateNodeBound (node)
@@ -1268,7 +1340,7 @@ module .exports = class OutlineView extends Interface
1268
1340
  .find (`.node[node-id=${node .getId ()}],
1269
1341
  .imported-node[node-id=${node .getId ()}],
1270
1342
  .exported-node[node-id=${node .getId ()}]`)
1271
- .find ("> .item .bind-node")
1343
+ .find ("> .item [action=bind-node]")
1272
1344
  .removeClass (["on", "off"])
1273
1345
  .addClass (node ._isBound .getValue () ? "on" : "off")
1274
1346
  .text (node ._isBound .getValue () ? "radio_button_checked" : "radio_button_unchecked");
@@ -1296,7 +1368,7 @@ module .exports = class OutlineView extends Interface
1296
1368
  .find (`.node[node-id=${node .getId ()}],
1297
1369
  .imported-node[node-id=${node .getId ()}],
1298
1370
  .exported-node[node-id=${node .getId ()}]`)
1299
- .find ("> .item .play-node")
1371
+ .find ("> .item [action=play-node]")
1300
1372
  .removeClass (["on", "off"])
1301
1373
  .addClass (node ._isPaused .getValue () ? "on" : "off")
1302
1374
  .attr ("title", node ._isActive .getValue () && !node ._isPaused .getValue () ? _("Pause timer.") : _("Start timer."))
@@ -1306,7 +1378,7 @@ module .exports = class OutlineView extends Interface
1306
1378
  .find (`.node[node-id=${node .getId ()}],
1307
1379
  .imported-node[node-id=${node .getId ()}],
1308
1380
  .exported-node[node-id=${node .getId ()}]`)
1309
- .find ("> .item .stop-node")
1381
+ .find ("> .item [action=stop-node]")
1310
1382
  .removeClass (["on", "off"])
1311
1383
  .addClass (node ._isActive .getValue () ? "on" : "off"));
1312
1384
 
@@ -1314,7 +1386,7 @@ module .exports = class OutlineView extends Interface
1314
1386
  .find (`.node[node-id=${node .getId ()}],
1315
1387
  .imported-node[node-id=${node .getId ()}],
1316
1388
  .exported-node[node-id=${node .getId ()}]`)
1317
- .find ("> .item .loop-node")
1389
+ .find ("> .item [action=loop-node]")
1318
1390
  .removeClass (["on", "off"])
1319
1391
  .addClass (node ._loop .getValue () ? "on" : "off"));
1320
1392
 
@@ -1386,7 +1458,7 @@ module .exports = class OutlineView extends Interface
1386
1458
 
1387
1459
  // Add buttons to name.
1388
1460
 
1389
- this .addNodeButtons (importedNode .getExportedNode (), name);
1461
+ this .addNodeButtons (this .getNode (parent), importedNode .getExportedNode (), name);
1390
1462
 
1391
1463
  // Append empty tree to enable expander.
1392
1464
 
@@ -1490,7 +1562,7 @@ module .exports = class OutlineView extends Interface
1490
1562
 
1491
1563
  // Add buttons to name.
1492
1564
 
1493
- this .addNodeButtons (node, name);
1565
+ this .addNodeButtons (this .getNode (parent), node, name);
1494
1566
 
1495
1567
  // Append empty tree to enable expander.
1496
1568
 
@@ -3026,21 +3098,27 @@ module .exports = class OutlineView extends Interface
3026
3098
  {
3027
3099
  this .deselectAll ();
3028
3100
 
3029
- const elements = this .sceneGraph .find ("> .root-nodes > ul > li[node-id]");
3101
+ const
3102
+ hierarchy = require ("../Application/Hierarchy"),
3103
+ elements = this .sceneGraph .find ("> .root-nodes > ul > li[node-id]");
3104
+
3105
+ hierarchy .target (this .executionContext);
3030
3106
 
3031
3107
  for (const element of elements)
3032
- this .selectNodeElement ($(element), true);
3108
+ this .selectNodeElement ($(element), { add: true });
3033
3109
  }
3034
3110
 
3035
3111
  deselectAll ()
3036
3112
  {
3037
3113
  const
3038
3114
  selection = require ("../Application/Selection"),
3115
+ hierarchy = require ("../Application/Hierarchy"),
3039
3116
  nodes = this .sceneGraph .find (".primary, .selected");
3040
3117
 
3041
3118
  nodes .removeClass (["primary", "manually", "selected"]);
3042
3119
 
3043
3120
  selection .clear ();
3121
+ hierarchy .clear ();
3044
3122
  }
3045
3123
 
3046
3124
  showPreview (event)
@@ -3127,7 +3205,7 @@ module .exports = class OutlineView extends Interface
3127
3205
  this .sceneGraph .find (`.node[node-id=${node .getId ()}],
3128
3206
  .imported-node[node-id=${node .getId ()}],
3129
3207
  .exported-node[node-id=${node .getId ()}]`)
3130
- .find ("> .item .toggle-visibility")
3208
+ .find ("> .item [action=toggle-visibility]")
3131
3209
  .removeClass (["on", "off"])
3132
3210
  .addClass (hidden ? "off" : "on")
3133
3211
  .text (hidden ? "visibility_off" : "visibility");
@@ -3156,13 +3234,34 @@ module .exports = class OutlineView extends Interface
3156
3234
 
3157
3235
  node .setUserData (_changing, true);
3158
3236
 
3159
- this .sceneGraph .find (`.node[node-id=${node .getId ()}] > .item .toggle-tool,
3160
- .imported-node[node-id=${node .getId ()}] > .item .toggle-tool,
3161
- .exported-node[node-id=${node .getId ()}] > .item .toggle-tool`)
3237
+ this .sceneGraph .find (`.node[node-id=${node .getId ()}],
3238
+ .imported-node[node-id=${node .getId ()}],
3239
+ .exported-node[node-id=${node .getId ()}]`)
3240
+ .find ("> .item [action=toggle-tool]")
3162
3241
  .removeClass (["on", "off"])
3163
3242
  .addClass (tool ? "off" : "on");
3164
3243
  }
3165
3244
 
3245
+ proxyDisplay (event)
3246
+ {
3247
+ const
3248
+ target = $(event .target),
3249
+ element = target .closest (".node, .imported-node, .exported-node", this .sceneGraph),
3250
+ node = this .getNode (element);
3251
+
3252
+ event .preventDefault ();
3253
+ event .stopImmediatePropagation ();
3254
+
3255
+ node .setProxyDisplay (!node .getProxyDisplay ());
3256
+
3257
+ this .sceneGraph .find (`.node[node-id=${node .getId ()}],
3258
+ .imported-node[node-id=${node .getId ()}],
3259
+ .exported-node[node-id=${node .getId ()}]`)
3260
+ .find ("> .item [action=proxy-display]")
3261
+ .removeClass (["on", "off"])
3262
+ .addClass (node .getProxyDisplay () ? "on" : "off");
3263
+ }
3264
+
3166
3265
  activateLayer (event) { }
3167
3266
 
3168
3267
  bindNode (event)
@@ -3207,6 +3306,35 @@ module .exports = class OutlineView extends Interface
3207
3306
  }
3208
3307
  }
3209
3308
 
3309
+ showBranch (event)
3310
+ {
3311
+ const
3312
+ target = $(event .target),
3313
+ element = target .closest (".node", this .sceneGraph),
3314
+ parentElement = element .parent () .closest (".node", this .sceneGraph),
3315
+ node = this .getNode (element),
3316
+ parent = this .getNode (parentElement);
3317
+
3318
+ event .preventDefault ();
3319
+ event .stopImmediatePropagation ();
3320
+
3321
+ this .sceneGraph .find (`.node[node-id=${parent .getId ()}] .node[node-id=${node .getId ()}]`)
3322
+ .siblings ()
3323
+ .find ("> .item [action=show-branch]")
3324
+ .removeClass (["on", "off"])
3325
+ .addClass ("off");
3326
+
3327
+ this .sceneGraph .find (`.node[node-id=${parent .getId ()}] .node[node-id=${node .getId ()}]`)
3328
+ .find ("> .item [action=show-branch]")
3329
+ .removeClass (["on", "off"])
3330
+ .addClass (parent .getEditChild () !== node ? "on" : "off");
3331
+
3332
+ if (parent .getEditChild () === node)
3333
+ parent .setEditChild (null)
3334
+ else
3335
+ parent .setEditChild (node);
3336
+ }
3337
+
3210
3338
  hideUnselectedObjects ()
3211
3339
  {
3212
3340
  // Hide all X3DShapeNode nodes and show all other nodes.
@@ -3226,7 +3354,7 @@ module .exports = class OutlineView extends Interface
3226
3354
  this .sceneGraph .find (`.node[node-id=${node .getId ()}],
3227
3355
  .imported-node[node-id=${node .getId ()}],
3228
3356
  .exported-node[node-id=${node .getId ()}]`)
3229
- .find ("> .item .toggle-visibility")
3357
+ .find ("> .item [action=toggle-visibility]")
3230
3358
  .removeClass (["on", "off"])
3231
3359
  .addClass (node .isHidden () ? "off" : "on")
3232
3360
  .text (node .isHidden () ? "visibility_off" : "visibility");
@@ -3333,15 +3461,16 @@ module .exports = class OutlineView extends Interface
3333
3461
 
3334
3462
  const
3335
3463
  element = $(event .currentTarget) .closest (".node, .externproto, .proto"),
3336
- add = window .event .shiftKey || window .event .metaKey;
3464
+ add = event .shiftKey || event .metaKey;
3337
3465
 
3338
3466
  if (element .hasClass ("node"))
3339
- this .selectNodeElement (element, add);
3467
+ this .selectNodeElement (element, { add, target: true });
3468
+
3340
3469
  else if (element .is (".externproto, .proto"))
3341
3470
  this .selectPrimaryElement (element, add);
3342
3471
  }
3343
3472
 
3344
- selectNodeElement (element, add = false)
3473
+ selectNodeElement (element, { add = false, target = false } = { })
3345
3474
  {
3346
3475
  if (!element .hasClass ("node"))
3347
3476
  return;
@@ -3351,6 +3480,7 @@ module .exports = class OutlineView extends Interface
3351
3480
 
3352
3481
  const
3353
3482
  selection = require ("../Application/Selection"),
3483
+ hierarchy = require ("../Application/Hierarchy"),
3354
3484
  selected = element .hasClass ("manually"),
3355
3485
  selectedElements = this .sceneGraph .find (".primary, .selected"),
3356
3486
  node = this .getNode (element),
@@ -3384,16 +3514,30 @@ module .exports = class OutlineView extends Interface
3384
3514
  }
3385
3515
 
3386
3516
  if (elements .filter (".manually") .length)
3517
+ {
3518
+ if (target)
3519
+ hierarchy .target (node);
3520
+
3387
3521
  selection .add (node);
3522
+ hierarchy .add (node);
3523
+ }
3388
3524
  else
3525
+ {
3389
3526
  selection .remove (node);
3527
+ hierarchy .remove (node);
3528
+ }
3390
3529
  }
3391
3530
  else
3392
3531
  {
3393
3532
  selectedElements .removeClass (["manually", "selected"]);
3394
3533
  element .addClass (["primary", "manually"]);
3395
3534
  elements .addClass ("selected");
3535
+
3536
+ if (target)
3537
+ hierarchy .target (node);
3538
+
3396
3539
  selection .set (node);
3540
+ hierarchy .set (node);
3397
3541
  }
3398
3542
 
3399
3543
  for (const [node, tool] of changed)
@@ -3711,14 +3855,15 @@ module .exports = class OutlineView extends Interface
3711
3855
 
3712
3856
  onDragEnd (event) { }
3713
3857
 
3714
- expandTo (object, expandObject = false)
3858
+ expandTo (object, { expandObject = false, expandAll = false } = { })
3715
3859
  {
3716
3860
  let flags = Traverse .NONE;
3717
3861
 
3718
3862
  if (this .expandExternProtoDeclarations)
3719
3863
  flags |= Traverse .EXTERNPROTO_DECLARATIONS | Traverse .EXTERNPROTO_DECLARATION_SCENE;
3720
3864
 
3721
- flags |= Traverse .PROTO_DECLARATIONS | Traverse .PROTO_DECLARATION_BODY;
3865
+ flags |= Traverse .PROTO_DECLARATIONS;
3866
+ flags |= Traverse .PROTO_DECLARATION_BODY;
3722
3867
 
3723
3868
  if (this .expandInlineNodes)
3724
3869
  flags |= Traverse .INLINE_SCENE;
@@ -3739,7 +3884,9 @@ module .exports = class OutlineView extends Interface
3739
3884
  hierarchy .pop ();
3740
3885
 
3741
3886
  this .expandHierarchy (hierarchy, this .sceneGraph, this .executionContext);
3742
- break;
3887
+
3888
+ if (!expandAll)
3889
+ break;
3743
3890
  }
3744
3891
  }
3745
3892
 
@@ -156,6 +156,7 @@ class X3DNodeTool extends X3DBaseTool
156
156
  {
157
157
  const scene = await this .getBrowser () .createX3DFromURL (new X3D .MFString (protoURL));
158
158
 
159
+ scene .setPrivate (true);
159
160
  scene .setExecutionContext (this .getBrowser () .getPrivateScene ());
160
161
  scene .setCountPrimitives (false);
161
162
 
@@ -188,6 +189,7 @@ class X3DNodeTool extends X3DBaseTool
188
189
  this [tool] = scene .createProto (protoName);
189
190
 
190
191
  this [tool] .getValue () .setPrivate (true);
192
+ this [tool] .getValue () .setUserData (_tool, this);
191
193
 
192
194
  X3DNodeTool .tools .add (this);
193
195
  X3DNodeTool .processToolInterests ();
@@ -91,6 +91,7 @@ async function initialize ()
91
91
  tool .undo = false;
92
92
  tool .tools = new MFString ("TRANSLATE", "SCALE");
93
93
  tool .centerTool = false;
94
+ tool .bboxEvents = false;
94
95
  }
95
96
 
96
97
  function set_selected ()
@@ -37,6 +37,7 @@ class Arc2DTool extends X3DLineGeometryNodeTool
37
37
  transformTool .centerDisplay = false;
38
38
  transformTool .centerTool = false;
39
39
  transformTool .zAxisDisplay = false;
40
+ transformTool .bboxEvents = false;
40
41
  transformTool .bboxColor = ToolColors .BLUE;
41
42
 
42
43
  this .tool .group = this .getTypeName ();
@@ -37,6 +37,7 @@ class ArcClose2DTool extends X3DGeometryNodeTool
37
37
  transformTool .centerDisplay = false;
38
38
  transformTool .centerTool = false;
39
39
  transformTool .zAxisDisplay = false;
40
+ transformTool .bboxEvents = false;
40
41
  transformTool .bboxColor = ToolColors .BLUE;
41
42
 
42
43
  this .tool .group = this .getTypeName ();
@@ -37,6 +37,7 @@ class Circle2DTool extends X3DLineGeometryNodeTool
37
37
  transformTool .centerDisplay = false;
38
38
  transformTool .centerTool = false;
39
39
  transformTool .zAxisDisplay = false;
40
+ transformTool .bboxEvents = false;
40
41
  transformTool .bboxColor = ToolColors .BLUE;
41
42
 
42
43
  this .tool .group = this .getTypeName ();
@@ -42,6 +42,7 @@ class Disk2DTool extends X3DGeometryNodeTool
42
42
  transformTool .centerDisplay = false;
43
43
  transformTool .centerTool = false;
44
44
  transformTool .zAxisDisplay = false;
45
+ transformTool .bboxEvents = false;
45
46
  transformTool .bboxColor = ToolColors .BLUE;
46
47
 
47
48
  toolChildren .push (transformNode);
@@ -76,6 +77,7 @@ class Disk2DTool extends X3DGeometryNodeTool
76
77
  transformTool .centerDisplay = false;
77
78
  transformTool .centerTool = false;
78
79
  transformTool .zAxisDisplay = false;
80
+ transformTool .bboxEvents = false;
79
81
  transformTool .bboxColor = ToolColors .BLUE;
80
82
 
81
83
  toolChildren .push (transformNode);
@@ -36,6 +36,7 @@ class Rectangle2DTool extends X3DGeometryNodeTool
36
36
  transformTool .centerDisplay = false;
37
37
  transformTool .centerTool = false;
38
38
  transformTool .zAxisDisplay = false;
39
+ transformTool .bboxEvents = false;
39
40
  transformTool .bboxDisplay = false;
40
41
 
41
42
  this .tool .group = this .getTypeName ();
@@ -35,6 +35,7 @@ class BoxTool extends X3DGeometryNodeTool
35
35
  transformTool .keys = ["SHIFT"];
36
36
  transformTool .centerDisplay = false;
37
37
  transformTool .centerTool = false;
38
+ transformTool .bboxEvents = false;
38
39
  transformTool .bboxDisplay = false;
39
40
 
40
41
  this .tool .group = this .getTypeName ();
@@ -37,6 +37,7 @@ class ConeTool extends X3DGeometryNodeTool
37
37
  transformTool .connectedAxes = ["XZ", "ZX"];
38
38
  transformTool .centerDisplay = false;
39
39
  transformTool .centerTool = false;
40
+ transformTool .bboxEvents = false;
40
41
  transformTool .bboxColor = ToolColors .BLUE;
41
42
 
42
43
  this .tool .group = this .getTypeName ();
@@ -37,6 +37,7 @@ class CylinderTool extends X3DGeometryNodeTool
37
37
  transformTool .connectedAxes = ["XZ", "ZX"];
38
38
  transformTool .centerDisplay = false;
39
39
  transformTool .centerTool = false;
40
+ transformTool .bboxEvents = false;
40
41
  transformTool .bboxColor = ToolColors .BLUE;
41
42
 
42
43
  this .tool .group = this .getTypeName ();
@@ -37,6 +37,7 @@ class SphereTool extends X3DGeometryNodeTool
37
37
  transformTool .connectedAxes = ["XY", "XZ", "YX", "YZ", "ZX", "ZY"];
38
38
  transformTool .centerDisplay = false;
39
39
  transformTool .centerTool = false;
40
+ transformTool .bboxEvents = false;
40
41
  transformTool .bboxColor = ToolColors .BLUE;
41
42
 
42
43
  this .tool .group = this .getTypeName ();