sunrize 1.0.43 → 1.0.45

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.
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/perl
2
+ use v5.10.0;
3
+ use utf8;
4
+ use open qw/:std :utf8/;
5
+
6
+ sub node {
7
+ $filename = shift;
8
+ chomp $filename;
9
+
10
+ $filename =~ m|([^/]+)/([^/]+)\.js$|;
11
+
12
+ $componentName = $1;
13
+ $typeName = $2;
14
+
15
+ return if $componentName =~ /^Annotation$/;
16
+ return if $typeName =~ /^X3D/;
17
+
18
+ return unless $typeName =~ /^Transform$/;
19
+ say "$componentName $typeName";
20
+
21
+ $file = `cat ../x_ite/docs/_posts/components/$componentName/$typeName.md`;
22
+
23
+ @fields = $file =~ m|###\s*[SM]F\w+.*|go;
24
+
25
+ say $_ foreach @fields;
26
+
27
+ #exit;
28
+ }
29
+
30
+ node $_ foreach sort `find ../x_ite/src/x_ite/Components -type f -mindepth 2`;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sunrize",
3
3
  "productName": "Sunrize X3D Editor",
4
- "version": "1.0.43",
4
+ "version": "1.0.45",
5
5
  "description": "A Multi Platform X3D Editor",
6
6
  "homepage": "https://create3000.github.io/sunrize/",
7
7
  "author": "Holger Seelig",
@@ -35,12 +35,12 @@
35
35
  }
36
36
  ],
37
37
  "devDependencies": {
38
- "@electron-forge/cli": "^6.1.1",
39
- "@electron-forge/maker-deb": "^6.1.1",
40
- "@electron-forge/maker-rpm": "^6.1.1",
41
- "@electron-forge/maker-squirrel": "^6.1.1",
42
- "@electron-forge/maker-zip": "^6.1.1",
43
- "electron": "^25.1.0"
38
+ "@electron-forge/cli": "^6.2.1",
39
+ "@electron-forge/maker-deb": "^6.2.1",
40
+ "@electron-forge/maker-rpm": "^6.2.1",
41
+ "@electron-forge/maker-squirrel": "^6.2.1",
42
+ "@electron-forge/maker-zip": "^6.2.1",
43
+ "electron": "^25.1.1"
44
44
  },
45
45
  "dependencies": {
46
46
  "capitalize": "^2.0.4",
@@ -52,14 +52,14 @@
52
52
  "jquery-ui-dist": "^1.13.2",
53
53
  "jstree": "^3.3.15",
54
54
  "material-icons": "^1.13.8",
55
- "material-symbols": "^0.6.0",
55
+ "material-symbols": "^0.8.0",
56
56
  "md5": "^2.3.0",
57
57
  "monaco-editor": "^0.39.0",
58
58
  "node-localstorage": "^2.2.1",
59
59
  "qtip2": "^3.0.3",
60
60
  "spectrum-colorpicker2": "^2.0.10",
61
61
  "string-similarity": "^4.0.4",
62
- "x_ite": "^8.8.3"
62
+ "x_ite": "^8.8.5"
63
63
  },
64
64
  "main": "src/main.js",
65
65
  "bin": {
@@ -2,7 +2,7 @@
2
2
  <head>
3
3
  <meta charset="utf-8"/>
4
4
  <!-- Theme -->
5
- <link rel="stylesheet" type="text/css" href="../themes/dark.css"/>
5
+ <link rel="stylesheet" type="text/css" href="../themes/default.css"/>
6
6
  </head>
7
7
  <body>
8
8
  <tab-group sortable="true">
@@ -24,12 +24,21 @@
24
24
  }
25
25
 
26
26
  .etabs .tab.active {
27
- z-index: 1000;
28
- padding-bottom: 5px;
27
+ z-index: 1100;
29
28
  background: var(--background-color);
30
29
  color: var(--window-tabs-highlight-color);
31
30
  }
32
31
 
32
+ .etabs::before {
33
+ z-index: 1000;
34
+ content: "";
35
+ position: relative;
36
+ display: block;
37
+ height: 1px;
38
+ width: 100%;
39
+ box-shadow: var(--tabs-shadow);
40
+ }
41
+
33
42
  .etabs .buttons {
34
43
  border-color: var(--border-color);
35
44
  }
@@ -3,7 +3,7 @@
3
3
  <meta charset="utf-8"/>
4
4
  <link rel="stylesheet" type="text/css" href="../../node_modules/jquery-ui-dist/jquery-ui.min.css"/>
5
5
  <link rel="stylesheet" type="text/css" href="../../node_modules/qtip2/dist/jquery.qtip.min.css"/>
6
- <link rel="stylesheet" type="text/css" href="../themes/dark.css"/>
6
+ <link rel="stylesheet" type="text/css" href="../themes/default.css"/>
7
7
  <link rel="stylesheet" data-name="vs/editor/editor.main" href="../../node_modules/monaco-editor/min/vs/editor/editor.main.css">
8
8
  </head>
9
9
  <body>
@@ -564,7 +564,7 @@ module .exports = class Application
564
564
  height: Math .max (this .config .getDefaultValue ("size") [1] / 4, this .config .size [1]),
565
565
  minWidth: this .config .getDefaultValue ("size") [0] / 4,
566
566
  minHeight: this .config .getDefaultValue ("size") [1] / 4,
567
- backgroundColor: "rgb(28, 28, 30)",
567
+ backgroundColor: electron .nativeTheme .shouldUseDarkColors ? "rgb(28, 28, 30)" : "rgb(242, 242, 247)",
568
568
  show: false,
569
569
  webPreferences: {
570
570
  preload: path .join (__dirname, `../../html/${file}.js`),
@@ -0,0 +1,20 @@
1
+ "use strict"
2
+
3
+ const $ = require ("jquery")
4
+
5
+ // CSS
6
+
7
+ const colorScheme = window .matchMedia ("(prefers-color-scheme: dark)")
8
+
9
+ colorScheme .addEventListener ("change", event => changeColorScheme (event));
10
+
11
+ changeColorScheme (colorScheme)
12
+
13
+ function changeColorScheme (event)
14
+ {
15
+ $("body")
16
+ .removeClass (["light", "dark"])
17
+ .addClass (event .matches ? "dark" : "light")
18
+ }
19
+
20
+ module .exports = { colorScheme }
@@ -35,6 +35,7 @@ module .exports = new class Document extends Interface
35
35
 
36
36
  this .setup ()
37
37
  }
38
+
38
39
  /**
39
40
  *
40
41
  */
@@ -42,7 +43,7 @@ module .exports = new class Document extends Interface
42
43
  {
43
44
  await this .browser .loadComponents (this .browser .getComponent ("Grouping"))
44
45
 
45
- this .browser .updateConcreteNode ("StaticGroup", require ("../Components/Grouping/StaticGroup"))
46
+ this .browser .updateConcreteNode (require ("../Components/Grouping/StaticGroup"))
46
47
 
47
48
  await this .restoreFile ()
48
49
 
@@ -85,6 +86,8 @@ module .exports = new class Document extends Interface
85
86
  this .browserSize = require ("../Editors/BrowserSize")
86
87
  this .resizeSensor = new ResizeSensor ($("#browser-frame"), this .onresize .bind (this))
87
88
 
89
+ // Change undo menu items.
90
+
88
91
  this .activate ()
89
92
  }
90
93
 
@@ -5,6 +5,7 @@ const
5
5
  url = require ("url"),
6
6
  md5 = require ("md5"),
7
7
  X3D = require ("../X3D"),
8
+ CSS = require ("../Application/CSS"),
8
9
  DataStorage = require ("./DataStorage")
9
10
 
10
11
  require ("../Bits/Highlight")
@@ -23,12 +24,15 @@ module .exports = class Interface
23
24
  this .config .file = this .createFileConfig ()
24
25
 
25
26
  this .browser .addBrowserCallback (this, this .setBrowserEvent .bind (this))
27
+ CSS .colorScheme .addEventListener ("change", event => this .colorScheme (!! event .matches))
26
28
  }
27
29
 
28
30
  setup ()
29
31
  {
30
32
  this .initialize ()
31
33
 
34
+ // Configure
35
+
32
36
  this .setBrowserEvent (X3D .X3DConstants .INITIALIZED_EVENT)
33
37
  }
34
38
 
@@ -93,8 +97,14 @@ module .exports = class Interface
93
97
  this .config .file = this .createFileConfig (this .browser .getWorldURL ())
94
98
 
95
99
  this .configure ()
100
+ this .colorScheme (!! CSS .colorScheme .matches)
96
101
  }
97
102
 
103
+ /**
104
+ * @param {object} event
105
+ */
106
+ colorScheme (shouldUseDarkColors) { }
107
+
98
108
  /**
99
109
  *
100
110
  * @param {string} namespace
@@ -9,6 +9,7 @@ const
9
9
  path = require ("path"),
10
10
  fs = require ("fs"),
11
11
  md5 = require ("md5"),
12
+ CSS = require ("./CSS"),
12
13
  _ = require ("./GetText")
13
14
 
14
15
  module .exports = new class Tabs
@@ -31,7 +32,7 @@ module .exports = new class Tabs
31
32
 
32
33
  initialize ()
33
34
  {
34
- this .tabs .on ("tab-active", (tab) =>
35
+ this .tabs .on ("tab-active", tab =>
35
36
  {
36
37
  electron .ipcRenderer .send ("title", tab .title)
37
38
 
@@ -41,6 +42,8 @@ module .exports = new class Tabs
41
42
  if (tab .domReady)
42
43
  tab .webview .send ("activate")
43
44
 
45
+ tab .initialized = true
46
+
44
47
  this .saveTabs ()
45
48
  })
46
49
 
@@ -252,9 +255,11 @@ module .exports = new class Tabs
252
255
  if (numTabs === 1)
253
256
  return
254
257
 
255
- const position = Math .max (tab .getPosition () - 1, 0)
258
+ const
259
+ position = Math .max (tab .getPosition () - 1, 0),
260
+ nextTab = this .tabs .getTabByPosition (position)
256
261
 
257
- this .tabs .getTabByPosition (position) .activate ()
262
+ nextTab .activate ()
258
263
  }
259
264
 
260
265
  tabClose (tab)
@@ -301,9 +306,11 @@ module .exports = new class Tabs
301
306
  {
302
307
  this .saveTabs ()
303
308
 
304
- let numTabs = this .tabs .getTabs () .length
309
+ const tabs = this .tabs .getTabs () .filter (tab => tab .initialized)
305
310
 
306
- for (const tab of this .tabs .getTabs ())
311
+ let numTabs = tabs .length
312
+
313
+ for (const tab of tabs)
307
314
  {
308
315
  tab .webview .addEventListener ("ipc-message", (event) =>
309
316
  {
@@ -317,7 +324,7 @@ module .exports = new class Tabs
317
324
  })
318
325
  }
319
326
 
320
- for (const tab of this .tabs .getTabs ())
327
+ for (const tab of tabs)
321
328
  tab .webview .send ("close")
322
329
 
323
330
  //this .maintenance ()
@@ -192,9 +192,6 @@ module .exports = class Traverse
192
192
  if (!executionContext)
193
193
  return
194
194
 
195
- if (executionContext .isPrivate ())
196
- return
197
-
198
195
  hierarchy .push (executionContext)
199
196
 
200
197
  if (executionContext === object)
@@ -11,6 +11,7 @@ $.fn.popover = function (options)
11
11
  position: {
12
12
  my: "top right",
13
13
  at: "bottom left",
14
+ viewport: $("body"),
14
15
  },
15
16
  style: {
16
17
  classes: "qtip-tipsy",
@@ -58,7 +58,29 @@ module .exports = class Splitter extends Interface
58
58
  configure ()
59
59
  {
60
60
  if (this .config .file .position !== undefined)
61
+ {
61
62
  this .position = this .config .file .position
63
+ }
64
+ else
65
+ {
66
+ switch (this .orientation)
67
+ {
68
+ case "horizontal":
69
+ {
70
+ const top = this .splitter .find ("> .horizontal-splitter-top")
71
+
72
+ this .position = top .outerHeight () / this .splitter .innerHeight ()
73
+ break
74
+ }
75
+ case "vertical":
76
+ {
77
+ const left = this .splitter .find ("> .vertical-splitter-left")
78
+
79
+ this .position = left .outerWidth () / this .splitter .innerWidth ()
80
+ break
81
+ }
82
+ }
83
+ }
62
84
  }
63
85
 
64
86
  get position ()
@@ -98,5 +120,7 @@ module .exports = class Splitter extends Interface
98
120
  break
99
121
  }
100
122
  }
123
+
124
+ this .splitter .trigger ("position")
101
125
  }
102
126
  }
@@ -19,6 +19,8 @@ module .exports = class Console extends Interface
19
19
  "error",
20
20
  ]
21
21
 
22
+ logClasses = ["", "", "filled", "filled"]
23
+
22
24
  constructor (element)
23
25
  {
24
26
  super (`Sunrize.Console.${element .attr ("id")}.`)
@@ -63,11 +65,13 @@ module .exports = class Console extends Interface
63
65
  this .output .html ($("#console .console-output") .html ())
64
66
  this .output .scrollTop (this .output .prop ("scrollHeight"))
65
67
  }
68
+ else
69
+ {
70
+ this .addMessage (null, 1, "", "", this .browser .getWelcomeMessage ())
71
+ }
66
72
 
67
73
  electron .ipcRenderer .on ("console-message", this .addMessageCallback)
68
74
 
69
- this .browser .printWelcomeMessage ()
70
-
71
75
  this .setup ()
72
76
  }
73
77
 
@@ -109,14 +113,25 @@ module .exports = class Console extends Interface
109
113
  return
110
114
 
111
115
  const
112
- classes = this .logLevels [level] || "log",
113
- text = $("<p></p>") .addClass (classes) .attr ("title", `${sourceId}:${line}`) .text (message)
116
+ classes = [this .logLevels [level] ?? "log", this .logClasses [level]],
117
+ title = sourceId ? `${sourceId}:${line}`: "",
118
+ text = $("<p></p>") .addClass (classes) .attr ("title", title) .text (message)
114
119
 
115
120
  if (this .messageTime && performance .now () - this .messageTime > 1000)
116
- text .addClass ("splitter")
121
+ this .output .append ($("<p></p>") .addClass ("splitter"))
117
122
 
118
123
  this .messageTime = performance .now ()
119
124
 
125
+ const last = this .output .children () .last ()
126
+
127
+ if (last .hasClass (this .logLevels [level]))
128
+ {
129
+ last .css ("margin-bottom", "0")
130
+ text .css ("margin-top", "0")
131
+ last .css ("border-bottom", "none")
132
+ text .css ("border-top", "none")
133
+ }
134
+
120
135
  this .output .append (text)
121
136
  this .output .scrollTop (this .output .prop ("scrollHeight"))
122
137
  }
@@ -38,7 +38,7 @@ module .exports = new class Library extends Dialog
38
38
  this .input = $("<input></input>")
39
39
  .appendTo (this .element)
40
40
  .addClass ("library-input")
41
- .attr ("placeholder", _ ("Node type name"))
41
+ .attr ("placeholder", _ ("Search a node"))
42
42
  .on ("keydown", event => this .enter (event))
43
43
  .on ("keyup", () => this .update ())
44
44
 
@@ -32,7 +32,7 @@ module .exports = class NodeList extends Interface
32
32
  this .executionContext = this .browser .currentScene
33
33
 
34
34
  this .update ()
35
- this .setNode (this .nodes [this .config .file .index] || null)
35
+ this .setNode (this .nodes [this .config .file .index] ?? null, false)
36
36
 
37
37
  this .executionContext .sceneGraph_changed .addInterest ("update", this)
38
38
  }
@@ -77,10 +77,12 @@ module .exports = class NodeList extends Interface
77
77
  this .setNode (null)
78
78
  }
79
79
 
80
- setNode (node)
80
+ setNode (node, config = true)
81
81
  {
82
- this .config .file .index = this .nodes .indexOf (node)
83
- this .node = node
82
+ if (config)
83
+ this .config .file .index = this .nodes .indexOf (node)
84
+
85
+ this .node = node
84
86
 
85
87
  this .callback (node)
86
88
  }
@@ -884,7 +884,7 @@ module .exports = class OutlineEditor extends OutlineRouteGraph
884
884
 
885
885
  removeColorField (element)
886
886
  {
887
- element .spectrum ("destroy")
887
+ element .spectrum ?.("destroy")
888
888
  }
889
889
 
890
890
  addTimeField (time)
@@ -146,7 +146,6 @@ module .exports = class OutlineRouteGraph extends OutlineView
146
146
  canvas = $canvas .get (0),
147
147
  context = canvas .getContext ("2d")
148
148
 
149
- $canvas .width (Math .ceil (parent .width ()))
150
149
  $canvas .height (Math .ceil (parent .height ()))
151
150
 
152
151
  canvas .width = $canvas .width ()
@@ -238,7 +237,6 @@ module .exports = class OutlineRouteGraph extends OutlineView
238
237
  canvas = $canvas .get (0),
239
238
  context = canvas .getContext ("2d")
240
239
 
241
- $canvas .width (Math .ceil (parent .width ()))
242
240
  $canvas .height (Math .ceil (parent .height ()))
243
241
 
244
242
  canvas .width = $canvas .width ()
@@ -686,6 +686,9 @@ module .exports = class OutlineView extends Interface
686
686
  .wrapInner ("<div class=\"item no-select\"/>")
687
687
  .find (".item") .append ("<div class=\"route-curves\"><canvas></canvas></div>")
688
688
 
689
+ child .find (".field .name, .special .name")
690
+ .on ("mouseenter", this .updateTitle .bind (this))
691
+
689
692
  child .find ("area.input-selector")
690
693
  .on ("mouseenter", this .hoverInConnector .bind (this, "input"))
691
694
  .on ("mouseleave", this .hoverOutConnector .bind (this, "input"))
@@ -843,9 +846,9 @@ module .exports = class OutlineView extends Interface
843
846
 
844
847
  // These fields are observed and must never be disconnected, because clones would also lose connection.
845
848
 
846
- node .typeName_changed .addFieldCallback (this, this .changeNodeTypeName .bind (this, node))
847
- node .name_changed .addFieldCallback (this, this .changeNodeName .bind (this, node))
848
- node .cloneCount_changed .addFieldCallback (this, this .changeCloneCount .bind (this, node))
849
+ node .typeName_changed .addFieldCallback (this, this .updateNodeTypeName .bind (this, node))
850
+ node .name_changed .addFieldCallback (this, this .updateNodeName .bind (this, node))
851
+ node .parents_changed .addFieldCallback (this, this .updateCloneCount .bind (this, node))
849
852
  }
850
853
 
851
854
  // Classes
@@ -905,10 +908,12 @@ module .exports = class OutlineView extends Interface
905
908
 
906
909
  name .append (document .createTextNode (" "))
907
910
 
908
- const cloneCount = $("<span></span>") .addClass ("clone-count") .appendTo (name)
911
+ const cloneCount = node .getCloneCount ?.() ?? 0
909
912
 
910
- if (node .getCloneCount () > 1)
911
- cloneCount .text (node .getCloneCount () > 1 ? `[${node .getCloneCount ()}]` : "")
913
+ $("<span></span>")
914
+ .addClass ("clone-count")
915
+ .text (cloneCount > 1 ? `[${cloneCount}]` : "")
916
+ .appendTo (name)
912
917
 
913
918
  // Append empty tree to enable expander.
914
919
 
@@ -926,7 +931,7 @@ module .exports = class OutlineView extends Interface
926
931
  return child
927
932
  }
928
933
 
929
- changeNodeTypeName (node)
934
+ updateNodeTypeName (node)
930
935
  {
931
936
  this .sceneGraph
932
937
  .find (`.node[node-id=${node .getId ()}], .exported-node[node-id=${node .getId ()}]`)
@@ -934,7 +939,7 @@ module .exports = class OutlineView extends Interface
934
939
  .text (node .getTypeName ())
935
940
  }
936
941
 
937
- changeNodeName (node)
942
+ updateNodeName (node)
938
943
  {
939
944
  this .sceneGraph
940
945
  .find (`.node[node-id=${node .getId ()}], .exported-node[node-id=${node .getId ()}]`)
@@ -942,12 +947,14 @@ module .exports = class OutlineView extends Interface
942
947
  .text (node .getDisplayName ())
943
948
  }
944
949
 
945
- changeCloneCount (node)
950
+ updateCloneCount (node)
946
951
  {
952
+ const cloneCount = node .getCloneCount ?.() ?? 0
953
+
947
954
  this .sceneGraph
948
955
  .find (`.node[node-id=${node .getId ()}]`)
949
956
  .find ("> .item .clone-count")
950
- .text (node .getCloneCount () > 1 ? `[${node .getCloneCount ()}]` : "")
957
+ .text (cloneCount > 1 ? `[${cloneCount}]` : "")
951
958
  }
952
959
 
953
960
  isInParents (parent, node)
@@ -1063,8 +1070,8 @@ module .exports = class OutlineView extends Interface
1063
1070
  this .objects .set (exportedNode .getId (), exportedNode)
1064
1071
  this .objects .set (node .getId (), node)
1065
1072
 
1066
- node .typeName_changed .addFieldCallback (this .exportedNodeSymbol, this .changeNodeTypeName .bind (this, node))
1067
- node .name_changed .addFieldCallback (this .exportedNodeSymbol, this .changeNodeName .bind (this, node))
1073
+ node .typeName_changed .addFieldCallback (this .exportedNodeSymbol, this .updateNodeTypeName .bind (this, node))
1074
+ node .name_changed .addFieldCallback (this .exportedNodeSymbol, this .updateNodeName .bind (this, node))
1068
1075
 
1069
1076
  // Node
1070
1077
 
@@ -1157,9 +1164,6 @@ module .exports = class OutlineView extends Interface
1157
1164
  .addClass ("name")
1158
1165
  .appendTo (child)
1159
1166
 
1160
- if (field instanceof X3D .X3DArrayField)
1161
- name .attr ("title", field .length === 1 ? _ ("1 value") : util .format (_ ("%s values"), field .length .toLocaleString (_.locale)))
1162
-
1163
1167
  $("<span></span>")
1164
1168
  .addClass ("field-name")
1165
1169
  .text (field .getName ())
@@ -1386,6 +1390,24 @@ module .exports = class OutlineView extends Interface
1386
1390
  return child
1387
1391
  }
1388
1392
 
1393
+ updateTitle (event)
1394
+ {
1395
+ const
1396
+ name = $(event .currentTarget),
1397
+ element = $(event .currentTarget) .closest (".field, .special", this .sceneGraph),
1398
+ node = this .objects .get (parseInt (element .attr ("node-id"))),
1399
+ field = this .objects .get (parseInt (element .attr ("field-id")))
1400
+
1401
+ if (field instanceof X3D .X3DArrayField)
1402
+ {
1403
+ name .attr ("title", util .format (field .length === 1 ? _ ("%s value") : _ ("%s values"), field .length .toLocaleString (_.locale)))
1404
+ }
1405
+ else
1406
+ {
1407
+ name .attr ("title", field .toString ({ scene: node .getExecutionContext () }))
1408
+ }
1409
+ }
1410
+
1389
1411
  updateReferences (parent, node, field)
1390
1412
  {
1391
1413
  const element = parent .find (`.field[field-id=${field .getId ()}]`)
@@ -1414,9 +1436,9 @@ module .exports = class OutlineView extends Interface
1414
1436
  r = Math .floor (field .r * 255),
1415
1437
  g = Math .floor (field .g * 255),
1416
1438
  b = Math .floor (field .b * 255),
1417
- a = field .getType () === X3D .X3DConstants .SFColorRGBA ? field .a : 1
1439
+ a = field .a ?? 1
1418
1440
 
1419
- return "rgba(" + r + "," + g + "," + b + "," + a + ")"
1441
+ return `rgba(${r},${g},${b},${a})`
1420
1442
  }
1421
1443
 
1422
1444
  getAccessTypeImage (field, active)
@@ -2004,6 +2026,8 @@ module .exports = class OutlineView extends Interface
2004
2026
  this .setTextAreaTabs (textarea)
2005
2027
  this .setTextArea (textarea, node, field)
2006
2028
 
2029
+ textarea .on ("mouseenter", this .updateTitle .bind (this))
2030
+
2007
2031
  if ((field .isInput () || field .isInitializable ()) && this .isEditable (parent))
2008
2032
  {
2009
2033
  textarea .on ("keydown", this .onkeydownArrayField .bind (this, textarea))
@@ -2218,8 +2242,6 @@ module .exports = class OutlineView extends Interface
2218
2242
 
2219
2243
  setTextArea (textarea, node, field)
2220
2244
  {
2221
- textarea .attr ("title", field .length === 1 ? _ ("1 value") : util .format (_ ("%s values"), field .length .toLocaleString (_.locale)))
2222
-
2223
2245
  switch (field .getType ())
2224
2246
  {
2225
2247
  case X3D .X3DConstants .MFBool:
@@ -2471,6 +2493,7 @@ module .exports = class OutlineView extends Interface
2471
2493
  element = $(e),
2472
2494
  field = this .getField (element)
2473
2495
 
2496
+ field .removeReferencesCallback (this)
2474
2497
  field .removeRouteCallback (this)
2475
2498
  field .removeFieldCallback (this)
2476
2499
  field .removeFieldCallback (this .fieldButtonSymbol)
@@ -10,8 +10,13 @@ const
10
10
  Console = require ("./Console"),
11
11
  Editor = require ("../Undo/Editor"),
12
12
  UndoManager = require ("../Undo/UndoManager"),
13
+ monaco = require ("monaco-editor/min/vs/loader.js"),
13
14
  _ = require ("../Application/GetText")
14
15
 
16
+ monaco .require .config ({
17
+ baseUrl: "node_modules/monaco-editor/min",
18
+ })
19
+
15
20
  require ("../Controls/RenameNodeInput")
16
21
 
17
22
  module .exports = class ScriptEditor extends Interface
@@ -39,13 +44,24 @@ module .exports = class ScriptEditor extends Interface
39
44
 
40
45
  this .vSplitter = new Splitter (this .verticalSplitter, "vertical")
41
46
 
47
+ this .verticalSplitter .on ("position", () => this .onSplitterPosition ())
48
+
42
49
  this .toolbar = $("<div></div>")
43
50
  .addClass (["toolbar", "vertical-toolbar", "script-editor-toolbar"])
44
51
  .appendTo (this .scriptEditor)
45
52
 
53
+ this .toggleSidebarButton = $("<span></span>")
54
+ .addClass (["material-symbols-outlined"])
55
+ .attr ("title", _ ("Toggle sidebar."))
56
+ .text ("dock_to_right")
57
+ .appendTo (this .toolbar)
58
+ .on ("click", () => this .toggleSidebar ())
59
+
60
+ $("<span></span>") .addClass ("separator") .appendTo (this .toolbar)
61
+
46
62
  this .createButton = $("<span></span>")
47
63
  .addClass ("material-icons")
48
- .attr ("title", _ ("Create New Script or Shader."))
64
+ .attr ("title", _ ("Create new Script node or shader."))
49
65
  .text ("add")
50
66
  .appendTo (this .toolbar)
51
67
  .on ("click", () => this .create ())
@@ -113,9 +129,19 @@ module .exports = class ScriptEditor extends Interface
113
129
 
114
130
  electron .ipcRenderer .on ("script-editor-menu", (event, key, ...args) => this [key] (...args))
115
131
 
132
+ // Setup.
133
+
116
134
  this .setup ()
117
135
  }
118
136
 
137
+ colorScheme (shouldUseDarkColors)
138
+ {
139
+ monaco .require (["vs/editor/editor.main"], monaco =>
140
+ {
141
+ monaco .editor .setTheme (shouldUseDarkColors ? "vs-dark" : "vs-light")
142
+ })
143
+ }
144
+
119
145
  async setNode (node)
120
146
  {
121
147
  this .directOutputButton .hide ()
@@ -219,13 +245,7 @@ module .exports = class ScriptEditor extends Interface
219
245
  }
220
246
  else
221
247
  {
222
- const monaco = require ("monaco-editor/min/vs/loader.js")
223
-
224
- monaco .require .config ({
225
- baseUrl: "node_modules/monaco-editor/min",
226
- })
227
-
228
- monaco .require (["vs/editor/editor.main"], (monaco) =>
248
+ monaco .require (["vs/editor/editor.main"], monaco =>
229
249
  {
230
250
  const element = $("<div></div>")
231
251
  .addClass ("script-editor-monaco")
@@ -243,7 +263,6 @@ module .exports = class ScriptEditor extends Interface
243
263
  {
244
264
  value: this .getScriptSource (node),
245
265
  language: this .languages [node .getTypeName ()],
246
- theme: "vs-dark",
247
266
  contextmenu: false,
248
267
  automaticLayout: true,
249
268
  wordWrap: "on",
@@ -607,17 +626,24 @@ main ()
607
626
  }
608
627
  }
609
628
 
610
- closeLeftBar ()
629
+ onSplitterPosition ()
611
630
  {
612
- if (this .config .file .vSplitterPosition !== undefined)
631
+ if (this .vSplitter .position)
632
+ this .toggleSidebarButton .addClass ("active")
633
+ else
634
+ this .toggleSidebarButton .removeClass ("active")
635
+ }
636
+
637
+ toggleSidebar ()
638
+ {
639
+ if (this .vSplitter .position)
613
640
  {
614
- this .vSplitter .position = this .config .file .vSplitterPosition
615
- this .config .file .vSplitterPosition = undefined
641
+ this .config .file .vSplitterPosition = this .vSplitter .position
642
+ this .vSplitter .position = 0
616
643
  }
617
644
  else
618
645
  {
619
- this .config .file .vSplitterPosition = this .vSplitter .position
620
- this .vSplitter .position = 0
646
+ this .vSplitter .position = this .config .file .vSplitterPosition
621
647
  }
622
648
  }
623
649
  }
@@ -235,7 +235,11 @@ module .exports = class Editor
235
235
  const oldWorldURL = scene .getMetaData ("base")
236
236
 
237
237
  if (oldWorldURL)
238
+ {
238
239
  this .rewriteURLs (executionContext, [...newProtos, ...nodes], oldWorldURL [0], executionContext .worldURL, undoManager)
240
+ }
241
+
242
+ scene .removeMetaData ("base")
239
243
 
240
244
  this .requestUpdateInstances (executionContext, undoManager)
241
245
 
@@ -5,7 +5,46 @@
5
5
 
6
6
  @import url(../../node_modules/spectrum-colorpicker2/dist/spectrum.css);
7
7
 
8
- :root {
8
+ body {
9
+ /* Colors */
10
+
11
+ --system-red: rgb(255, 59, 48);
12
+ --system-orange: rgb(255, 149, 0);
13
+ --system-yellow: rgb(255, 214, 10);
14
+ --system-green: rgb(52, 199, 89);
15
+ --system-mint: rgb(0, 199, 190);
16
+ --system-teal: rgb(48, 176, 199);
17
+ --system-cyan: rgb(50, 173, 230);
18
+ --system-blue: rgb(0, 122, 255);
19
+ --system-indigo: rgb(88, 86, 214);
20
+ --system-purple: rgb(175, 82, 222);
21
+ --system-pink: rgb(255, 45, 85);
22
+ --system-brown: rgb(162, 132, 94);
23
+
24
+ --system-gray0: rgb(72, 72, 77);
25
+ --system-gray1: rgb(122, 122, 127);
26
+ --system-gray2: rgb(174, 174, 178);
27
+ --system-gray3: rgb(199, 199, 204);
28
+ --system-gray4: rgb(209, 209, 214);
29
+ --system-gray5: rgb(229, 229, 234);
30
+ --system-gray6: rgb(242, 242, 247);
31
+ --system-gray7: rgb(249, 249, 255);
32
+ --system-gray8: rgb(255, 255, 255);
33
+
34
+ /* Filter Colors */
35
+
36
+ --filter-system-red: invert(31%) sepia(82%) saturate(3000%) hue-rotate(344deg) brightness(115%) contrast(105%);
37
+ --filter-system-gray0: invert(36%) sepia(72%) saturate(11%) hue-rotate(222deg) brightness(95%) contrast(90%);
38
+ --filter-system-gray1: invert(63%) sepia(4%) saturate(334%) hue-rotate(201deg) brightness(89%) contrast(86%);
39
+
40
+ /* Special Colors */
41
+
42
+ --sidebar-background-color: rgb(208, 219, 231);
43
+ --tint-color1: rgba(255, 255, 255, 0.3);
44
+ --tint-color2: rgba(255, 255, 255, 0.5);
45
+ }
46
+
47
+ body.dark {
9
48
  /* Colors */
10
49
 
11
50
  --system-red: rgb(255, 69, 58);
@@ -22,7 +61,7 @@
22
61
  --system-brown: rgb(172, 142, 104);
23
62
 
24
63
  --system-gray0: rgb(204, 204, 209);
25
- --system-gray: rgb(142, 142, 147);
64
+ --system-gray1: rgb(142, 142, 147);
26
65
  --system-gray2: rgb(99, 99, 102);
27
66
  --system-gray3: rgb(72, 72, 74);
28
67
  --system-gray4: rgb(58, 58, 60);
@@ -34,28 +73,24 @@
34
73
  /* Filter Colors */
35
74
 
36
75
  --filter-system-red: invert(69%) sepia(59%) saturate(6315%) hue-rotate(336deg) brightness(99%) contrast(108%);
37
- --filter-system-gray: invert(72%) sepia(0%) saturate(6315%) hue-rotate(205deg) brightness(81%) contrast(62%);
38
76
  --filter-system-gray0: invert(97%) sepia(2%) saturate(509%) hue-rotate(200deg) brightness(84%) contrast(94%);
77
+ --filter-system-gray1: invert(72%) sepia(0%) saturate(6315%) hue-rotate(205deg) brightness(81%) contrast(62%);
39
78
 
40
79
  /* Special Colors */
41
80
 
42
81
  --sidebar-background-color: rgb(42, 50, 63);
43
- --tint-color: rgba(0, 0, 0, 0.2);
82
+ --tint-color1: rgba(0, 0, 0, 0.2);
44
83
  --tint-color2: rgba(0, 0, 0, 0.4);
45
- --highlight-tint-color: rgba(255, 255, 255, 0.2);
46
84
  }
47
85
 
48
- .material-symbols-outlined {
49
- font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 48;
50
- }
51
-
52
- :root {
86
+ body {
53
87
  /* Colors */
54
88
 
55
89
  --background-color: var(--system-gray6);
56
- --text-color: var(--system-gray);
57
- --highlight-color: var(--system-gray0);
58
- --border-color: var(--system-gray8);
90
+ --text-color: var(--system-gray0);
91
+ --highlight-color: black;
92
+ --border-color: var(--system-gray3);
93
+ --expander-color: var(--system-gray1);
59
94
  --accent-color: var(--system-red);
60
95
  --separator-color: var(--system-gray3);
61
96
 
@@ -72,10 +107,14 @@
72
107
  --medium-icon-size: 18px;
73
108
  --large-icon-size: 28px;
74
109
 
110
+ /* Tabs */
111
+
112
+ --tabs-shadow: 0px 2px 1.5px 0px var(--border-color);
113
+
75
114
  /* Filter Colors */
76
115
 
77
- --filter-text-color: var(--filter-system-gray);
78
- --filter-highlight-color: var(--filter-system-gray0);
116
+ --filter-text-color: var(--filter-system-gray0);
117
+ --filter-highlight-color: var(--filter-system-grayZ);
79
118
  --filter-accent-color: var(--filter-system-red);
80
119
 
81
120
  /* Fonts */
@@ -88,21 +127,42 @@
88
127
 
89
128
  /* Tools */
90
129
 
91
- --tool-backdrop-filter: blur(5px);
92
- --tool-background-color: rgba(42, 50, 63, 0.7); /* --system-gray6 */
130
+ --tool-backdrop-filter: blur(25px);
131
+ --tool-background-color: rgba(208, 219, 231, 0.8); /* --sidebar-background-color */
93
132
  --tool-border-radius: 6px;
94
- --tool-border: 1px solid var(--system-gray3);
95
- --tool-shadow: 3px 3px 9px var(--system-gray8);
133
+ --tool-border: 1px solid var(--system-gray8);
134
+ --tool-shadow: 3px 3px 9px rgba(0, 0, 0, 0.6);
96
135
 
97
136
  --background-disabled: repeating-linear-gradient(
98
137
  -45deg,
99
- var(--tint-color),
100
- var(--tint-color) 10px,
138
+ var(--tint-color1),
139
+ var(--tint-color1) 10px,
101
140
  transparent 10px,
102
141
  transparent 20px
103
142
  )
104
143
  }
105
144
 
145
+ body.dark {
146
+ /* Colors */
147
+
148
+ --text-color: var(--system-gray1);
149
+ --highlight-color: var(--system-gray0);
150
+ --border-color: var(--system-gray8);
151
+ --expander-color: var(--system-gray8);
152
+ --filter-text-color: var(--filter-system-gray1);
153
+ --filter-highlight-color: var(--filter-system-gray0);
154
+
155
+ /* Tabs */
156
+
157
+ --tabs-shadow: 0px 0px 1px 0px var(--border-color);
158
+
159
+ /* Tools */
160
+
161
+ --tool-background-color: rgba(42, 50, 63, 0.8); /* --sidebar-background-color */
162
+ --tool-border: 1px solid var(--system-gray2);
163
+ --tool-shadow: 3px 3px 9px var(--system-gray8);
164
+ }
165
+
106
166
  body {
107
167
  overflow: hidden;
108
168
  margin: 0;
@@ -112,20 +172,25 @@ body {
112
172
  font-size: var(--font-size);
113
173
  }
114
174
 
175
+ .material-symbols-outlined {
176
+ font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 48;
177
+ }
178
+
115
179
  *:focus {
116
180
  outline: none;
117
181
  }
118
182
 
119
183
  ::placeholder {
120
- color: var(--system-gray3);
121
- font-family: var(--sans-serif);
184
+ color: var(--system-gray2);
122
185
  }
123
186
 
124
187
  ::selection {
125
188
  color: var(--system-gray0);
126
- background: var(--system-gray3);
189
+ background: var(--system-gray4);
127
190
  }
128
191
 
192
+ /* common */
193
+
129
194
  textarea, input, button, select,
130
195
  th, td,
131
196
  .ui-widget, .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button, .ui-widget-content {
@@ -177,7 +242,7 @@ thead tr {
177
242
  }
178
243
 
179
244
  tbody tr:nth-child(odd) {
180
- background: var(--tint-color);
245
+ background: var(--tint-color1);
181
246
  }
182
247
 
183
248
  tbody tr:hover {
@@ -188,22 +253,22 @@ td > input:not([type]),
188
253
  td > input[type="text"],
189
254
  td > input[type="number"] {
190
255
  width: 100%;
191
- border: 1px solid var(--tint-color);
256
+ border: 1px solid var(--tint-color1);
192
257
  }
193
258
 
194
259
  td > textarea {
195
260
  resize: vertical;
196
261
  width: 100%;
197
262
  height: 8em;
198
- border: 1px solid var(--tint-color) !important;
263
+ border: 1px solid var(--tint-color1) !important;
199
264
  }
200
265
 
201
266
  td > select {
202
- border: 1px solid var(--tint-color) !important;
267
+ border: 1px solid var(--tint-color1) !important;
203
268
  }
204
269
 
205
270
  td > div {
206
- border: 1px solid var(--tint-color) !important;
271
+ border: 1px solid var(--tint-color1) !important;
207
272
  }
208
273
 
209
274
  .sticky-headers thead {
@@ -215,7 +280,7 @@ tr.disabled ~ tr input,
215
280
  tr.disabled ~ tr textarea,
216
281
  tr.disabled ~ tr select,
217
282
  tr.disabled ~ tr button {
218
- pointer-events: none;
283
+ pointer-events: none;
219
284
  }
220
285
 
221
286
  tr.disabled ~ tr > td > input,
@@ -223,7 +288,7 @@ tr.disabled ~ tr > td > textarea,
223
288
  tr.disabled ~ tr > td > select,
224
289
  tr.disabled ~ tr > td > button,
225
290
  tr.disabled ~ tr > td > div {
226
- background: var(--background-disabled);
291
+ background: var(--background-disabled);
227
292
  }
228
293
 
229
294
  /* Highlight animation */
@@ -249,6 +314,7 @@ tr.disabled ~ tr > td > div {
249
314
 
250
315
  .vertical-splitter-left,
251
316
  .vertical-splitter-right {
317
+ background-color: var(--background-color);
252
318
  position: absolute;
253
319
  box-sizing: border-box;
254
320
  top: 0;
@@ -310,6 +376,7 @@ tr.disabled ~ tr > td > div {
310
376
 
311
377
  .horizontal-splitter-top,
312
378
  .horizontal-splitter-bottom {
379
+ background-color: var(--background-color);
313
380
  position: absolute;
314
381
  box-sizing: border-box;
315
382
  left: 0;
@@ -381,13 +448,13 @@ tr.disabled ~ tr > td > div {
381
448
  }
382
449
 
383
450
  .ui-tabs.top > .ui-tabs-nav {
384
- border-bottom: 1px solid var(--system-gray3);
451
+ border-bottom: var(--tool-border);
385
452
  }
386
453
 
387
454
  .ui-tabs.bottom > .ui-tabs-nav {
388
455
  position: absolute;
389
456
  bottom: 0;
390
- border-top: 1px solid var(--system-gray3);
457
+ border-top: var(--tool-border);
391
458
  }
392
459
 
393
460
  .ui-tabs > .ui-tabs-nav li,
@@ -459,8 +526,9 @@ tr.disabled ~ tr > td > div {
459
526
  }
460
527
 
461
528
  .qtip-tipsy.qtip {
462
- border: 1px solid var(--border-color);
463
- background: var(--system-gray7);
529
+ border: var(--tool-border);
530
+ background: var(--tool-background-color);
531
+ backdrop-filter: var(--tool-backdrop-filter);
464
532
  }
465
533
 
466
534
  .qtip-tipsy .qtip-content {
@@ -473,9 +541,23 @@ tr.disabled ~ tr > td > div {
473
541
  display: block;
474
542
  width: 100%;
475
543
  background: var(--background-color);
476
- border: 1px solid var(--border-color);
544
+ border: 1px solid var(--system-gray7);
545
+ filter: opacity(80%);
477
546
  }
478
547
 
548
+ .qtip .qtip-content > div > * {
549
+ margin: 0.2em 0em;
550
+ }
551
+
552
+ .qtip .qtip-content > div:first-child {
553
+ margin-top: 0em;
554
+ }
555
+
556
+ .qtip .qtip-content > div:last-child {
557
+ margin-bottom: 0em;
558
+ }
559
+
560
+ .qtip select:hover,
479
561
  .qtip button:hover {
480
562
  background-color: var(--system-gray4);
481
563
  color: var(--system-gray0);
@@ -607,6 +689,23 @@ tr.disabled ~ tr > td > div {
607
689
 
608
690
  /* Dialog */
609
691
 
692
+ .dialog ::selection {
693
+ color: var(--system-gray0);
694
+ background: var(--system-gray2);
695
+ }
696
+
697
+ .dialog ::placeholder {
698
+ color: var(--system-gray1);
699
+ }
700
+
701
+ body.dark .dialog ::placeholder {
702
+ color: var(--system-gray2);
703
+ }
704
+
705
+ .dialog .tabs-panel {
706
+ padding: 0.5em 1em;
707
+ }
708
+
610
709
  .dialog.ui-dialog.ui-widget.ui-widget-content {
611
710
  cursor: move;
612
711
  backdrop-filter: var(--tool-backdrop-filter);
@@ -624,10 +723,6 @@ tr.disabled ~ tr > td > div {
624
723
 
625
724
  /* Library */
626
725
 
627
- .library ::placeholder {
628
- color: var(--system-gray2);
629
- }
630
-
631
726
  .ui-widget .library-input {
632
727
  box-sizing: border-box;
633
728
  display: block;
@@ -676,8 +771,13 @@ tr.disabled ~ tr > td > div {
676
771
 
677
772
  .ui-widget .library-list .component {
678
773
  margin: 1em 0;
679
- border-bottom: 1px solid var(--system-gray2);
680
774
  font-size: var(--small-font-size);
775
+ border-bottom: 1px solid var(--system-gray1);
776
+ color: var(--system-gray1);
777
+ }
778
+
779
+ body.dark .ui-widget .library-list .component {
780
+ border-bottom: 1px solid var(--system-gray2);
681
781
  color: var(--system-gray2);
682
782
  }
683
783
 
@@ -717,7 +817,7 @@ tr.disabled ~ tr > td > div {
717
817
  }
718
818
 
719
819
  .node-list > ul > li:nth-child(odd) {
720
- background-color: var(--tint-color);
820
+ background-color: var(--tint-color1);
721
821
  }
722
822
 
723
823
  .node-list > ul > li:hover {
@@ -748,6 +848,7 @@ tr.disabled ~ tr > td > div {
748
848
  }
749
849
 
750
850
  .console {
851
+ overflow: hidden;
751
852
  box-sizing: border-box;
752
853
  }
753
854
 
@@ -783,7 +884,7 @@ tr.disabled ~ tr > td > div {
783
884
  .console-output p.splitter {
784
885
  margin-top: 5px;
785
886
  border-top: 1px solid var(--system-gray3);
786
- padding-top: 5px;
887
+ margin-bottom: 5px;
787
888
  }
788
889
 
789
890
  .console-output p.debug {
@@ -806,6 +907,42 @@ tr.disabled ~ tr > td > div {
806
907
  color: var(--system-red);
807
908
  }
808
909
 
910
+ .console-output p.filled {
911
+ position: relative;
912
+ z-index: 0;
913
+ margin-top: 5px;
914
+ margin-bottom: 5px;
915
+ color: black;
916
+ }
917
+
918
+ .console-output p.filled:before {
919
+ content: "";
920
+ position: absolute;
921
+ display: block;
922
+ z-index: -1;
923
+ width: 100%;
924
+ height: 100%;
925
+ filter: brightness(2) opacity(60%);
926
+ }
927
+
928
+ .console-output p.warn.filled {
929
+ border-top: 1px solid var(--system-yellow);
930
+ border-bottom: 1px solid var(--system-yellow);
931
+ }
932
+
933
+ .console-output p.warn.filled:before {
934
+ background-color: var(--system-yellow);
935
+ }
936
+
937
+ .console-output p.error.filled {
938
+ border-top: 1px solid var(--system-red);
939
+ border-bottom: 1px solid var(--system-red);
940
+ }
941
+
942
+ .console-output p.error.filled:before {
943
+ background-color: var(--system-red);
944
+ }
945
+
809
946
  .console-input {
810
947
  position: absolute;
811
948
  box-sizing: border-box;
@@ -965,7 +1102,7 @@ tr.disabled ~ tr > td > div {
965
1102
  top: 0;
966
1103
  width: 22px;
967
1104
  cursor: pointer;
968
- color: var(--system-gray8);
1105
+ color: var(--expander-color);
969
1106
  }
970
1107
 
971
1108
  .tree-view .jstree-anchor {
@@ -976,11 +1113,11 @@ tr.disabled ~ tr > td > div {
976
1113
  }
977
1114
 
978
1115
  .tree-view .jstree-node.selected {
979
- background-color: var(--tint-color);
1116
+ background-color: var(--tint-color1);
980
1117
  }
981
1118
 
982
1119
  .tree-view .jstree-node.primary {
983
- outline: 1px solid var(--border-color);
1120
+ outline: 1px solid var(--system-gray8);
984
1121
  }
985
1122
 
986
1123
  .tree-view .no-select {
@@ -1110,9 +1247,9 @@ tr.disabled ~ tr > td > div {
1110
1247
  top: 4px;
1111
1248
  width: 12px;
1112
1249
  height: 12px;
1113
- border: 1px solid var(--system-gray8);
1250
+ border: 1px solid var(--border-color);
1114
1251
  border-radius: 50%;
1115
- background: var(--system-gray8);
1252
+ background: var(--border-color);
1116
1253
  }
1117
1254
 
1118
1255
  .scene-graph .time-button {
@@ -1209,7 +1346,7 @@ tr.disabled ~ tr > td > div {
1209
1346
  padding: 0;
1210
1347
  min-width: calc(100% - 20px);
1211
1348
  max-width: calc(100% - 20px);
1212
- background: var(--tint-color);
1349
+ background: var(--tint-color1);
1213
1350
  color: inherit;
1214
1351
  font-family: var(--sans-serif);
1215
1352
  font-size: inherit;