@babylonjs/gui-editor 5.38.0 → 5.39.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.
@@ -40217,7 +40217,7 @@ class SceneExplorerComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Componen
40217
40217
  if (!scene) {
40218
40218
  return null;
40219
40219
  }
40220
- const guiElements = scene.textures.filter((t) => t.getClassName() === "AdvancedDynamicTexture");
40220
+ const guiElements = [this.props.globalState.guiTexture];
40221
40221
  return ((0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", { id: "tree", onDrop: () => {
40222
40222
  this.props.globalState.onDropObservable.notifyObservers();
40223
40223
  this.props.globalState.onParentingChangeObservable.notifyObservers(null);
@@ -41163,7 +41163,6 @@ class GizmoGeneric extends react__WEBPACK_IMPORTED_MODULE_3__.Component {
41163
41163
  const inNodeSpace = _coordinateHelper__WEBPACK_IMPORTED_MODULE_4__.CoordinateHelper.RttToLocalNodeSpace(node, inRTT.x, inRTT.y, undefined, this._storedValues);
41164
41164
  this._dragLocalBounds(inNodeSpace);
41165
41165
  this._updateNodeFromLocalBounds();
41166
- this.props.globalState.workbench._liveGuiTextureRerender = false;
41167
41166
  this.props.globalState.onPropertyGridUpdateRequiredObservable.notifyObservers();
41168
41167
  }
41169
41168
  if (this.state.isRotating) {
@@ -41717,6 +41716,7 @@ __webpack_require__.r(__webpack_exports__);
41717
41716
 
41718
41717
 
41719
41718
 
41719
+
41720
41720
 
41721
41721
 
41722
41722
  var ConstraintDirection;
@@ -41725,6 +41725,23 @@ var ConstraintDirection;
41725
41725
  ConstraintDirection[ConstraintDirection["X"] = 2] = "X";
41726
41726
  ConstraintDirection[ConstraintDirection["Y"] = 3] = "Y";
41727
41727
  })(ConstraintDirection || (ConstraintDirection = {}));
41728
+ /**
41729
+ * This function will throttle calls to functions.
41730
+ *
41731
+ * @param callback callback to call.
41732
+ * @param time time to wait between calls in ms.
41733
+ */
41734
+ function throttle(callback, time) {
41735
+ let lastCalledTime = 0;
41736
+ return function (...args) {
41737
+ const now = Date.now();
41738
+ if (now - lastCalledTime < time) {
41739
+ return;
41740
+ }
41741
+ lastCalledTime = now;
41742
+ callback(...args);
41743
+ };
41744
+ }
41728
41745
  const ARROW_KEY_MOVEMENT_SMALL = 1; // px
41729
41746
  const ARROW_KEY_MOVEMENT_LARGE = 5; // px
41730
41747
  const MAX_POINTER_TRAVEL_DISTANCE = 5; //px^2. determines how far the pointer can move to be treated as a drag vs. a click
@@ -41737,14 +41754,11 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
41737
41754
  this._constraintDirection = ConstraintDirection.NONE;
41738
41755
  this._isOverGUINode = [];
41739
41756
  this._doubleClick = null;
41740
- this._liveGuiTextureRerender = true;
41741
41757
  this._currLeft = 0;
41742
41758
  this._currTop = 0;
41743
41759
  this._controlsHit = [];
41744
41760
  this._pointerTravelDistance = 0;
41745
41761
  this._processSelectionOnUp = false;
41746
- this._nextLiveGuiRender = -1;
41747
- this._liveGuiRerenderDelay = 30;
41748
41762
  this._defaultGUISize = { width: 1024, height: 1024 };
41749
41763
  this._initialPanningOffset = new core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.Vector2(0, 0);
41750
41764
  this._panningOffset = new core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.Vector2(0, 0);
@@ -42004,16 +42018,6 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42004
42018
  * @param guiControl
42005
42019
  */
42006
42020
  addEditorBehavior(guiControl) {
42007
- const onPointerUpStored = guiControl.onPointerUpObservable.observers.slice();
42008
- guiControl.onPointerUpObservable.clear();
42009
- const onPointerDownStored = guiControl.onPointerDownObservable.observers.slice();
42010
- guiControl.onPointerDownObservable.clear();
42011
- const onPointerEnterStored = guiControl.onPointerEnterObservable.observers.slice();
42012
- guiControl.onPointerEnterObservable.clear();
42013
- const onPointerOutStored = guiControl.onPointerOutObservable.observers.slice();
42014
- guiControl.onPointerOutObservable.clear();
42015
- const onDisposeStored = guiControl.onDisposeObservable.observers.slice();
42016
- guiControl.onDisposeObservable.clear();
42017
42021
  guiControl.onPointerUpObservable.add(() => {
42018
42022
  this.clicked = false;
42019
42023
  });
@@ -42039,21 +42043,9 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42039
42043
  this._isOverGUINode.splice(index, 1);
42040
42044
  }
42041
42045
  });
42042
- // use metadata to keep track of things we need to cleanup/restore when the gui editor closes
42043
- // also stores the old metadata
42044
42046
  guiControl.metadata = {
42047
+ ...guiControl.metadata,
42045
42048
  guiEditor: true,
42046
- metadata: guiControl.metadata,
42047
- isHighlighted: guiControl.isHighlighted,
42048
- highlightLineWidth: guiControl.highlightLineWidth,
42049
- isReadOnly: guiControl.isReadOnly,
42050
- isHitTestVisible: guiControl.isHitTestVisible,
42051
- isPointerBlocker: guiControl.isPointerBlocker,
42052
- onPointerUpStored,
42053
- onPointerDownStored,
42054
- onPointerEnterStored,
42055
- onPointerOutStored,
42056
- onDisposeStored,
42057
42049
  };
42058
42050
  guiControl.highlightLineWidth = 5;
42059
42051
  guiControl.isHighlighted = false;
@@ -42069,44 +42061,15 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42069
42061
  if (!control.metadata || !control.metadata.guiEditor) {
42070
42062
  return;
42071
42063
  }
42072
- const restoreObservers = (observable, storedObservers) => {
42073
- observable.clear();
42074
- for (const observer of storedObservers) {
42075
- const obs = observer;
42076
- observable.add(obs.callback, obs.mask, false, obs.scope, obs.unregisterOnNextCall);
42077
- }
42078
- };
42079
- restoreObservers(control.onPointerUpObservable, control.metadata.onPointerUpStored);
42080
- restoreObservers(control.onPointerDownObservable, control.metadata.onPointerDownStored);
42081
- restoreObservers(control.onPointerEnterObservable, control.metadata.onPointerEnterStored);
42082
- restoreObservers(control.onPointerOutObservable, control.metadata.onPointerOutStored);
42083
- restoreObservers(control.onDisposeObservable, control.metadata.onDisposeStored);
42084
- control.highlightLineWidth = control.metadata.highlightLineWidth;
42085
- control.isHighlighted = control.metadata.isHighlighted;
42086
- control.isPointerBlocker = control.metadata.isPointerBlocker;
42087
- control.isHitTestVisible = control.metadata.isHitTestVisible;
42088
- control.isReadOnly = control.metadata.isReadOnly;
42089
- control.metadata = control.metadata.metadata;
42064
+ delete control.metadata.guiEditor;
42065
+ delete control.metadata.editorUniqueId;
42090
42066
  }
42091
42067
  dispose() {
42092
42068
  this.props.globalState.hostDocument.removeEventListener("keyup", this.keyEvent);
42093
42069
  this.props.globalState.hostDocument.removeEventListener("keydown", this.keyEvent);
42094
42070
  this.props.globalState.hostDocument.defaultView.removeEventListener("blur", this.blurEvent);
42095
- if (this.props.globalState.liveGuiTexture) {
42096
- this.props.globalState.liveGuiTexture.onEndRenderObservable.remove(this._liveRenderObserver);
42097
- this.props.globalState.guiTexture.onBeginRenderObservable.remove(this._guiRenderObserver);
42098
- this.props.globalState.guiTexture.getDescendants().forEach((control) => {
42099
- this.removeEditorBehavior(control);
42100
- this.props.globalState.guiTexture.removeControl(control);
42101
- if (control.parent === this._trueRootContainer) {
42102
- control.parent = this.props.globalState.liveGuiTexture.rootContainer;
42103
- }
42104
- control._host = this.props.globalState.liveGuiTexture;
42105
- });
42106
- this.props.globalState.liveGuiTexture.markAsDirty();
42107
- this.props.globalState.guiTexture.getDescendants(true).forEach((control) => {
42108
- this.props.globalState.guiTexture.removeControl(control);
42109
- });
42071
+ if (this._guiRenderObserver) {
42072
+ this.props.globalState.guiTexture.onEndRenderObservable.remove(this._guiRenderObserver);
42110
42073
  }
42111
42074
  this._engine.dispose();
42112
42075
  }
@@ -42163,9 +42126,6 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42163
42126
  }
42164
42127
  }
42165
42128
  appendBlock(guiElement) {
42166
- if (this.props.globalState.liveGuiTexture) {
42167
- this.props.globalState.liveGuiTexture.addControl(guiElement);
42168
- }
42169
42129
  this.addEditorBehavior(guiElement);
42170
42130
  guiElement.getDescendants(true).forEach((desc) => this.addEditorBehavior(desc));
42171
42131
  if (this.props.globalState.selectedControls.length != 0) {
@@ -42187,12 +42147,6 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42187
42147
  if (dropLocationControl instanceof gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_3__.Container && //dropping inside a container control
42188
42148
  this.props.globalState.draggedControlDirection === _globalState__WEBPACK_IMPORTED_MODULE_2__.DragOverLocation.CENTER) {
42189
42149
  draggedControlParent.removeControl(draggedControl);
42190
- const liveGui = this.props.globalState.liveGuiTexture;
42191
- if (liveGui) {
42192
- if (liveGui.rootContainer.children.indexOf(draggedControl) !== -1) {
42193
- liveGui.rootContainer.removeControl(draggedControl);
42194
- }
42195
- }
42196
42150
  dropLocationControl.addControl(draggedControl);
42197
42151
  }
42198
42152
  else if (dropLocationControl.parent) {
@@ -42247,7 +42201,36 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42247
42201
  }
42248
42202
  }
42249
42203
  this.props.globalState.draggedControl = null;
42250
- this.props.globalState.onPropertyGridUpdateRequiredObservable.notifyObservers();
42204
+ }
42205
+ _canClone() {
42206
+ return this.props.globalState.liveGuiTexture && this.props.globalState.guiTexture && this.trueRootContainer;
42207
+ }
42208
+ _copyEditorGUIToLiveGUI() {
42209
+ if (this._canClone()) {
42210
+ // Before cloning, save all of the live GUI controls that have a linked mesh
42211
+ const controlToLinkedMesh = new Map();
42212
+ const liveRoot = this.props.globalState.liveGuiTexture.rootContainer;
42213
+ liveRoot.getDescendants().forEach((control) => {
42214
+ if (control.linkedMesh) {
42215
+ controlToLinkedMesh.set(control.metadata.editorUniqueId, control.linkedMesh);
42216
+ }
42217
+ });
42218
+ liveRoot.clearControls();
42219
+ const updatedRootChildren = this.trueRootContainer.children.slice(0);
42220
+ for (const child of updatedRootChildren) {
42221
+ const clone = child.clone(this.props.globalState.liveGuiTexture);
42222
+ liveRoot.addControl(clone);
42223
+ }
42224
+ // Relink all meshes
42225
+ liveRoot.getDescendants().forEach((control) => {
42226
+ if (control.metadata && controlToLinkedMesh.has(control.metadata.editorUniqueId)) {
42227
+ const linkedMesh = controlToLinkedMesh.get(control.metadata.editorUniqueId);
42228
+ if (linkedMesh) {
42229
+ control.linkWithMesh(linkedMesh);
42230
+ }
42231
+ }
42232
+ });
42233
+ }
42251
42234
  }
42252
42235
  _reorderGrid(grid, draggedControl, dropLocationControl) {
42253
42236
  const cellInfo = _tools__WEBPACK_IMPORTED_MODULE_5__.Tools.GetCellInfo(grid, draggedControl);
@@ -42443,6 +42426,19 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42443
42426
  this._processSelectionOnUp = false;
42444
42427
  }
42445
42428
  }
42429
+ _copyLiveGUIToEditorGUI() {
42430
+ if (this.props.globalState.liveGuiTexture && this.trueRootContainer) {
42431
+ // Create special IDs that will allow us to know which cloned control corresponds to its original
42432
+ this.props.globalState.liveGuiTexture.rootContainer.getDescendants().forEach((control) => {
42433
+ control.metadata = { ...(control.metadata ?? {}), editorUniqueId: (0,core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.RandomGUID)() };
42434
+ });
42435
+ this.trueRootContainer.clearControls();
42436
+ for (const control of this.props.globalState.liveGuiTexture.rootContainer.children) {
42437
+ const cloned = control.clone(this.props.globalState.guiTexture);
42438
+ this.appendBlock(cloned);
42439
+ }
42440
+ }
42441
+ }
42446
42442
  createGUICanvas(embed) {
42447
42443
  // Get the canvas element from the DOM.
42448
42444
  const canvas = this._rootContainer.current;
@@ -42453,10 +42449,15 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42453
42449
  this._scene.clearColor = new core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.Color4(0, 0, 0, 0);
42454
42450
  const light = new core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.HemisphericLight("light1", core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.Axis.Y, this._scene);
42455
42451
  light.intensity = 0.9;
42456
- if (embed) {
42457
- this.props.globalState.fromPG = true;
42458
- this._guiSize.width = core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.DataStorage.ReadNumber("width", 1024);
42459
- this._guiSize.height = core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.DataStorage.ReadNumber("height", 1024);
42452
+ if (this.props.globalState.liveGuiTexture) {
42453
+ this._guiSize.width = this.props.globalState.liveGuiTexture.getSize().width;
42454
+ this._guiSize.height = this.props.globalState.liveGuiTexture.getSize().height;
42455
+ canvas.width = this._guiSize.width;
42456
+ canvas.height = this._guiSize.height;
42457
+ }
42458
+ else {
42459
+ this._guiSize.width = core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.DataStorage.ReadNumber("GUIEditorWidth", 1024);
42460
+ this._guiSize.height = core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.DataStorage.ReadNumber("GUIEditorHeight", 1024);
42460
42461
  }
42461
42462
  this._panAndZoomContainer = new gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_3__.Container("panAndZoom");
42462
42463
  this._panAndZoomContainer.clipContent = false;
@@ -42474,7 +42475,7 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42474
42475
  adt.useInvalidateRectOptimization = false;
42475
42476
  this.trueRootContainer = adt.rootContainer;
42476
42477
  adt.onEndRenderObservable.add(() => this.props.globalState.onGizmoUpdateRequireObservable.notifyObservers());
42477
- this.synchronizeLiveGUI();
42478
+ this._copyLiveGUIToEditorGUI();
42478
42479
  new core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.ArcRotateCamera("Camera", 0, 0, 0, core_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__.Vector3.Zero(), this._scene);
42479
42480
  // This attaches the mouse controls
42480
42481
  this.addControls(this._scene);
@@ -42495,27 +42496,11 @@ class WorkbenchComponent extends react__WEBPACK_IMPORTED_MODULE_1__.Component {
42495
42496
  ev.object.markAsDirty(false);
42496
42497
  this.props.globalState.onWindowResizeObservable.notifyObservers();
42497
42498
  });
42498
- // Every time the original ADT re-renders, we must also re-render, so that layout information is computed correctly
42499
- // also, every time *we* re-render (due to a change in the GUI), we must re-render the original ADT
42500
- // to prevent an infinite loop, we flip a boolean flag
42499
+ const throttledSynchronization = throttle(() => {
42500
+ this._copyEditorGUIToLiveGUI();
42501
+ }, 33);
42501
42502
  if (this.props.globalState.liveGuiTexture) {
42502
- this._guiRenderObserver = this.props.globalState.guiTexture.onBeginRenderObservable.add(() => {
42503
- if (this._liveGuiTextureRerender) {
42504
- this._nextLiveGuiRender = Date.now() + this._liveGuiRerenderDelay;
42505
- }
42506
- this._liveGuiTextureRerender = true;
42507
- });
42508
- this._liveRenderObserver = this.props.globalState.liveGuiTexture.onEndRenderObservable.add(() => {
42509
- // return the GUI to the editor mode
42510
- this.props.globalState.guiTexture?.markAsDirty();
42511
- this._liveGuiTextureRerender = false;
42512
- });
42513
- this._scene.onAfterRenderObservable.add(() => {
42514
- if (this._nextLiveGuiRender > 0 && Date.now() > this._nextLiveGuiRender) {
42515
- this._nextLiveGuiRender = -1;
42516
- this.props.globalState.liveGuiTexture?.markAsDirty();
42517
- }
42518
- });
42503
+ this._guiRenderObserver = this.props.globalState.guiTexture.onEndRenderObservable.add(throttledSynchronization);
42519
42504
  }
42520
42505
  this._engine.runRenderLoop(() => {
42521
42506
  this._scene.render();