@itwin/appui-react 3.4.0-dev.35 → 3.4.0-dev.39
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/lib/cjs/appui-react/childwindow/ChildWindowManager.d.ts.map +1 -1
- package/lib/cjs/appui-react/childwindow/ChildWindowManager.js +4 -5
- package/lib/cjs/appui-react/childwindow/ChildWindowManager.js.map +1 -1
- package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts +13 -1
- package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
- package/lib/cjs/appui-react/frontstage/FrontstageDef.js +140 -96
- package/lib/cjs/appui-react/frontstage/FrontstageDef.js.map +1 -1
- package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts +0 -6
- package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
- package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts +20 -697
- package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
- package/lib/cjs/appui-react/widget-panels/Frontstage.js +286 -278
- package/lib/cjs/appui-react/widget-panels/Frontstage.js.map +1 -1
- package/lib/cjs/appui-react/widget-panels/useWidgetDirection.js +1 -1
- package/lib/cjs/appui-react/widget-panels/useWidgetDirection.js.map +1 -1
- package/lib/cjs/appui-react/widgets/WidgetDef.d.ts +13 -6
- package/lib/cjs/appui-react/widgets/WidgetDef.d.ts.map +1 -1
- package/lib/cjs/appui-react/widgets/WidgetDef.js +6 -1
- package/lib/cjs/appui-react/widgets/WidgetDef.js.map +1 -1
- package/lib/esm/appui-react/childwindow/ChildWindowManager.d.ts.map +1 -1
- package/lib/esm/appui-react/childwindow/ChildWindowManager.js +4 -5
- package/lib/esm/appui-react/childwindow/ChildWindowManager.js.map +1 -1
- package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts +13 -1
- package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
- package/lib/esm/appui-react/frontstage/FrontstageDef.js +142 -98
- package/lib/esm/appui-react/frontstage/FrontstageDef.js.map +1 -1
- package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts +0 -6
- package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
- package/lib/esm/appui-react/widget-panels/Frontstage.d.ts +20 -697
- package/lib/esm/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
- package/lib/esm/appui-react/widget-panels/Frontstage.js +277 -272
- package/lib/esm/appui-react/widget-panels/Frontstage.js.map +1 -1
- package/lib/esm/appui-react/widget-panels/useWidgetDirection.js +2 -2
- package/lib/esm/appui-react/widget-panels/useWidgetDirection.js.map +1 -1
- package/lib/esm/appui-react/widgets/WidgetDef.d.ts +13 -6
- package/lib/esm/appui-react/widgets/WidgetDef.d.ts.map +1 -1
- package/lib/esm/appui-react/widgets/WidgetDef.js +6 -1
- package/lib/esm/appui-react/widgets/WidgetDef.js.map +1 -1
- package/package.json +32 -32
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
// cSpell:ignore popout
|
|
10
10
|
import "./Frontstage.scss";
|
|
11
|
-
import produce
|
|
11
|
+
import produce from "immer";
|
|
12
12
|
import * as React from "react";
|
|
13
13
|
import { assert, Logger, ProcessDetector } from "@itwin/core-bentley";
|
|
14
14
|
import { StagePanelLocation, UiItemsManager, WidgetState } from "@itwin/appui-abstract";
|
|
15
|
-
import { Size, UiStateStorageStatus } from "@itwin/core-react";
|
|
15
|
+
import { Rectangle, Size, UiStateStorageStatus } from "@itwin/core-react";
|
|
16
16
|
import { ToolbarPopupAutoHideContext } from "@itwin/components-react";
|
|
17
|
-
import { addPanelWidget, addTab,
|
|
17
|
+
import { addFloatingWidget, addPanelWidget, addTab, addTabToWidget, convertAllPopupWidgetContainersToFloating, createNineZoneState, floatingWidgetBringToFront, FloatingWidgets, getTabLocation, getUniqueId, getWidgetPanelSectionId, insertPanelWidget, insertTabToWidget, isFloatingTabLocation, isHorizontalPanelSide, isPanelTabLocation, isPopoutTabLocation, NineZone, NineZoneStateReducer, panelSides, removeTab, removeTabFromWidget, toolSettingsTabId, WidgetPanels, } from "@itwin/appui-layout-react";
|
|
18
18
|
import { useActiveFrontstageDef } from "../frontstage/Frontstage";
|
|
19
19
|
import { FrontstageManager } from "../frontstage/FrontstageManager";
|
|
20
20
|
import { StagePanelState } from "../stagepanels/StagePanelDef";
|
|
@@ -259,7 +259,6 @@ export function appendWidgets(state, widgetDefs, side, preferredWidgetIndex) {
|
|
|
259
259
|
const saveTab = state.tabs[widgetDef.id];
|
|
260
260
|
const preferredPanelWidgetSize = saveTab ? saveTab.preferredPanelWidgetSize : widgetDef.preferredPanelSize;
|
|
261
261
|
const preferredFloatingWidgetSize = saveTab ? saveTab.preferredFloatingWidgetSize : widgetDef.defaultFloatingSize;
|
|
262
|
-
const preferredPopoutWidgetSize = saveTab ? saveTab.preferredPopoutWidgetSize : undefined;
|
|
263
262
|
// if a defaultFloatingSize is specified then this mean the widget can't determine its intrinsic size and must be explicitly sized
|
|
264
263
|
const userSized = saveTab ? (saveTab.userSized || !!widgetDef.defaultFloatingSize && !!saveTab.preferredFloatingWidgetSize)
|
|
265
264
|
: !!widgetDef.defaultFloatingSize;
|
|
@@ -269,7 +268,6 @@ export function appendWidgets(state, widgetDefs, side, preferredWidgetIndex) {
|
|
|
269
268
|
canPopout: widgetDef.canPopout,
|
|
270
269
|
preferredPanelWidgetSize,
|
|
271
270
|
preferredFloatingWidgetSize,
|
|
272
|
-
preferredPopoutWidgetSize,
|
|
273
271
|
userSized,
|
|
274
272
|
isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
|
|
275
273
|
hideWithUiWhenFloating: !!widgetDef.hideWithUiWhenFloating,
|
|
@@ -277,13 +275,35 @@ export function appendWidgets(state, widgetDefs, side, preferredWidgetIndex) {
|
|
|
277
275
|
if (widgetDef.isFloatingStateSupported && widgetDef.defaultState === WidgetState.Floating) {
|
|
278
276
|
const floatingContainerId = (_a = widgetDef.floatingContainerId) !== null && _a !== void 0 ? _a : getUniqueId();
|
|
279
277
|
const widgetContainerId = getWidgetId(side, panelZoneKeys[preferredWidgetIndex]);
|
|
280
|
-
const
|
|
278
|
+
const home = { side, widgetId: widgetContainerId, widgetIndex: 0 };
|
|
281
279
|
const preferredPosition = widgetDef.defaultFloatingPosition;
|
|
282
|
-
|
|
280
|
+
if (floatingContainerId in state.widgets) {
|
|
281
|
+
state = addTabToWidget(state, widgetDef.id, floatingContainerId);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
const tab = state.tabs[widgetDef.id];
|
|
285
|
+
const size = { height: 200, width: 300, ...tab.preferredFloatingWidgetSize };
|
|
286
|
+
const preferredPoint = preferredPosition !== null && preferredPosition !== void 0 ? preferredPosition : { x: (state.size.width - size.width) / 2, y: (state.size.height - size.height) / 2 };
|
|
287
|
+
const nzBounds = Rectangle.createFromSize(state.size);
|
|
288
|
+
const bounds = Rectangle.createFromSize(size).offset(preferredPoint);
|
|
289
|
+
const containedBounds = bounds.containIn(nzBounds);
|
|
290
|
+
state = addFloatingWidget(state, floatingContainerId, [widgetDef.id], {
|
|
291
|
+
bounds: containedBounds.toProps(),
|
|
292
|
+
home,
|
|
293
|
+
userSized,
|
|
294
|
+
}, {
|
|
295
|
+
isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
283
298
|
}
|
|
284
299
|
else {
|
|
285
300
|
const widgetPanelSectionId = getWidgetPanelSectionId(side, preferredWidgetIndex);
|
|
286
|
-
|
|
301
|
+
if (widgetPanelSectionId in state.widgets) {
|
|
302
|
+
state = addTabToWidget(state, widgetDef.id, widgetPanelSectionId);
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
state = addPanelWidget(state, side, widgetPanelSectionId, [widgetDef.id]);
|
|
306
|
+
}
|
|
287
307
|
}
|
|
288
308
|
}
|
|
289
309
|
return state;
|
|
@@ -329,17 +349,15 @@ export function addMissingWidgets(frontstageDef, initialState) {
|
|
|
329
349
|
state = appendWidgets(state, determineNewWidgets((_t = frontstageDef.bottomPanel) === null || _t === void 0 ? void 0 : _t.panelZones.end.widgetDefs, state), "bottom", 1);
|
|
330
350
|
return state;
|
|
331
351
|
}
|
|
332
|
-
/**
|
|
333
|
-
function
|
|
352
|
+
/** Hide widgets with Hidden defaultState. */
|
|
353
|
+
function hideWidgets(state, frontstageDef) {
|
|
334
354
|
const tabs = Object.values(state.tabs);
|
|
335
355
|
for (const tab of tabs) {
|
|
336
356
|
const widgetDef = frontstageDef.findWidgetDef(tab.id);
|
|
337
357
|
if (!widgetDef)
|
|
338
358
|
continue;
|
|
339
359
|
if (widgetDef.defaultState === WidgetState.Hidden) {
|
|
340
|
-
state =
|
|
341
|
-
hideWidget(draft, widgetDef);
|
|
342
|
-
});
|
|
360
|
+
state = hideWidget(state, widgetDef);
|
|
343
361
|
}
|
|
344
362
|
}
|
|
345
363
|
return state;
|
|
@@ -348,16 +366,15 @@ function removeHiddenWidgets(state, frontstageDef) {
|
|
|
348
366
|
* @internal
|
|
349
367
|
*/
|
|
350
368
|
export function removeMissingWidgets(frontstageDef, initialState) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
});
|
|
369
|
+
let state = initialState;
|
|
370
|
+
for (const [, tab] of Object.entries(state.tabs)) {
|
|
371
|
+
if (tab.id === toolSettingsTabId)
|
|
372
|
+
continue;
|
|
373
|
+
const widgetDef = frontstageDef.findWidgetDef(tab.id);
|
|
374
|
+
if (widgetDef)
|
|
375
|
+
continue;
|
|
376
|
+
state = removeTab(state, tab.id);
|
|
377
|
+
}
|
|
361
378
|
return state;
|
|
362
379
|
}
|
|
363
380
|
function getWidgetLabel(label) {
|
|
@@ -508,23 +525,23 @@ export function isFrontstageStateSettingResult(settingsResult) {
|
|
|
508
525
|
return false;
|
|
509
526
|
}
|
|
510
527
|
/** @internal */
|
|
511
|
-
export function initializePanel(
|
|
512
|
-
|
|
528
|
+
export function initializePanel(state, frontstageDef, panelSide) {
|
|
529
|
+
state = addPanelWidgets(state, frontstageDef, panelSide);
|
|
513
530
|
const location = toStagePanelLocation(panelSide);
|
|
514
531
|
const panelDef = frontstageDef.getStagePanelDef(location);
|
|
515
|
-
|
|
532
|
+
state = produce(state, (draft) => {
|
|
516
533
|
var _a, _b, _c;
|
|
517
534
|
const panel = draft.panels[panelSide];
|
|
518
535
|
panel.minSize = (_a = panelDef === null || panelDef === void 0 ? void 0 : panelDef.minSize) !== null && _a !== void 0 ? _a : panel.minSize;
|
|
519
536
|
panel.pinned = (_b = panelDef === null || panelDef === void 0 ? void 0 : panelDef.pinned) !== null && _b !== void 0 ? _b : panel.pinned;
|
|
520
537
|
panel.resizable = (_c = panelDef === null || panelDef === void 0 ? void 0 : panelDef.resizable) !== null && _c !== void 0 ? _c : panel.resizable;
|
|
521
538
|
if (panelDef === null || panelDef === void 0 ? void 0 : panelDef.maxSizeSpec) {
|
|
522
|
-
panel.maxSize = getPanelMaxSize(panelDef.maxSizeSpec, panelSide,
|
|
539
|
+
panel.maxSize = getPanelMaxSize(panelDef.maxSizeSpec, panelSide, state.size);
|
|
523
540
|
}
|
|
524
541
|
const size = panelDef === null || panelDef === void 0 ? void 0 : panelDef.size;
|
|
525
542
|
panel.size = size === undefined ? size : Math.min(Math.max(size, panel.minSize), panel.maxSize);
|
|
526
543
|
});
|
|
527
|
-
return
|
|
544
|
+
return state;
|
|
528
545
|
}
|
|
529
546
|
function getPanelMaxSize(maxSizeSpec, panel, nineZoneSize) {
|
|
530
547
|
if (typeof maxSizeSpec === "number") {
|
|
@@ -533,7 +550,7 @@ function getPanelMaxSize(maxSizeSpec, panel, nineZoneSize) {
|
|
|
533
550
|
const size = isHorizontalPanelSide(panel) ? nineZoneSize.height : nineZoneSize.width;
|
|
534
551
|
return maxSizeSpec.percentage / 100 * size;
|
|
535
552
|
}
|
|
536
|
-
const stateVersion =
|
|
553
|
+
const stateVersion = 13; // this needs to be bumped when NineZoneState is changed (to recreate the layout).
|
|
537
554
|
/** @internal */
|
|
538
555
|
export function initializeNineZoneState(frontstageDef) {
|
|
539
556
|
let nineZone = defaultNineZone;
|
|
@@ -555,6 +572,7 @@ export function initializeNineZoneState(frontstageDef) {
|
|
|
555
572
|
for (const [, panel] of Object.entries(stateDraft.panels)) {
|
|
556
573
|
const expanded = panel.widgets.find((widgetId) => stateDraft.widgets[widgetId].minimized === false);
|
|
557
574
|
const firstWidget = panel.widgets.length > 0 ? stateDraft.widgets[panel.widgets[0]] : undefined;
|
|
575
|
+
// istanbul ignore next
|
|
558
576
|
if (!expanded && firstWidget) {
|
|
559
577
|
firstWidget.minimized = false;
|
|
560
578
|
}
|
|
@@ -583,7 +601,7 @@ export function initializeNineZoneState(frontstageDef) {
|
|
|
583
601
|
}
|
|
584
602
|
});
|
|
585
603
|
nineZone = addMissingWidgets(frontstageDef, nineZone);
|
|
586
|
-
nineZone =
|
|
604
|
+
nineZone = hideWidgets(nineZone, frontstageDef);
|
|
587
605
|
nineZone = processPopoutWidgets(nineZone, frontstageDef);
|
|
588
606
|
return nineZone;
|
|
589
607
|
}
|
|
@@ -595,29 +613,32 @@ export function initializeNineZoneState(frontstageDef) {
|
|
|
595
613
|
export function restoreNineZoneState(frontstageDef, saved) {
|
|
596
614
|
let restored = {
|
|
597
615
|
...saved,
|
|
598
|
-
tabs:
|
|
616
|
+
tabs: defaultNineZone.tabs,
|
|
599
617
|
};
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
618
|
+
for (const [, tab] of Object.entries(saved.tabs)) {
|
|
619
|
+
// Re-add the placeholder tab in order to correctly remove it from the state if WidgetDef is not found.
|
|
620
|
+
restored = addTab(restored, tab.id);
|
|
621
|
+
const widgetDef = frontstageDef.findWidgetDef(tab.id);
|
|
622
|
+
if (!widgetDef) {
|
|
623
|
+
Logger.logInfo(UiFramework.loggerCategory(restoreNineZoneState), "WidgetDef is not found for saved tab.", () => ({
|
|
624
|
+
frontstageId: frontstageDef.id,
|
|
625
|
+
tabId: tab.id,
|
|
626
|
+
}));
|
|
627
|
+
restored = removeTab(restored, tab.id);
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
restored = produce(restored, (draft) => {
|
|
612
631
|
draft.tabs[tab.id] = {
|
|
613
632
|
...tab,
|
|
614
|
-
label: getWidgetLabel(
|
|
615
|
-
hideWithUiWhenFloating: widgetDef
|
|
616
|
-
iconSpec: widgetDef
|
|
617
|
-
canPopout: widgetDef
|
|
618
|
-
isFloatingStateWindowResizable: widgetDef
|
|
633
|
+
label: getWidgetLabel(widgetDef.label),
|
|
634
|
+
hideWithUiWhenFloating: widgetDef.hideWithUiWhenFloating,
|
|
635
|
+
iconSpec: widgetDef.iconSpec,
|
|
636
|
+
canPopout: widgetDef.canPopout,
|
|
637
|
+
isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
|
|
619
638
|
};
|
|
620
|
-
}
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
restored = produce(restored, (draft) => {
|
|
621
642
|
// remove center panel section if one is found in left or right panels
|
|
622
643
|
const oldLeftMiddleIndex = saved.panels.left.widgets.findIndex((value) => value === "leftMiddle");
|
|
623
644
|
// istanbul ignore next
|
|
@@ -645,14 +666,6 @@ export function restoreNineZoneState(frontstageDef, saved) {
|
|
|
645
666
|
}
|
|
646
667
|
return;
|
|
647
668
|
});
|
|
648
|
-
// TODO: remove when isUUID check is refactored.
|
|
649
|
-
restored = produce(restored, (draft) => {
|
|
650
|
-
// Floating widget might have been removed when saving, dock tool settings if tab is not found.
|
|
651
|
-
const location = findTab(draft, toolSettingsTabId);
|
|
652
|
-
if (!location) {
|
|
653
|
-
draft.toolSettings.type = "docked";
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
669
|
if (FrontstageManager.nineZoneSize && (0 !== FrontstageManager.nineZoneSize.height || 0 !== FrontstageManager.nineZoneSize.width)) {
|
|
657
670
|
restored = FrameworkStateReducer(restored, {
|
|
658
671
|
type: "RESIZE",
|
|
@@ -664,20 +677,6 @@ export function restoreNineZoneState(frontstageDef, saved) {
|
|
|
664
677
|
}
|
|
665
678
|
return restored;
|
|
666
679
|
}
|
|
667
|
-
/**
|
|
668
|
-
* Checks to see whether a widget id is one of our generated uuids
|
|
669
|
-
* @param uuid the string value to test
|
|
670
|
-
* @returns boolean
|
|
671
|
-
*/
|
|
672
|
-
function isUUID(uuid) {
|
|
673
|
-
const s = `${uuid}`;
|
|
674
|
-
const result = s.match("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
|
|
675
|
-
// istanbul ignore else
|
|
676
|
-
if (result === null) {
|
|
677
|
-
return false;
|
|
678
|
-
}
|
|
679
|
-
return true;
|
|
680
|
-
}
|
|
681
680
|
/** Prepares NineZoneState to be saved.
|
|
682
681
|
* @note Removes toolSettings tab.
|
|
683
682
|
* @note Removes tab labels and iconSpec.
|
|
@@ -692,31 +691,60 @@ export function packNineZoneState(state) {
|
|
|
692
691
|
for (const [, tab] of Object.entries(state.tabs)) {
|
|
693
692
|
if (tab.id === toolSettingsTabId)
|
|
694
693
|
continue;
|
|
695
|
-
// istanbul ignore else
|
|
696
|
-
if (isUUID(tab.id))
|
|
697
|
-
continue;
|
|
698
694
|
draft.tabs[tab.id] = {
|
|
699
695
|
id: tab.id,
|
|
700
696
|
preferredFloatingWidgetSize: tab.preferredFloatingWidgetSize,
|
|
701
|
-
preferredPopoutWidgetSize: tab.preferredPopoutWidgetSize,
|
|
702
697
|
allowedPanelTargets: tab.allowedPanelTargets,
|
|
703
698
|
userSized: tab.userSized,
|
|
704
699
|
};
|
|
705
700
|
}
|
|
706
701
|
});
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
702
|
+
return packed;
|
|
703
|
+
}
|
|
704
|
+
// TODO: clean-up of saved widgets.
|
|
705
|
+
// istanbul ignore next
|
|
706
|
+
function packSavedWidgets(savedWidgets, frontstageDef) {
|
|
707
|
+
for (const widgetDef of frontstageDef.widgetDefs) {
|
|
708
|
+
const id = widgetDef.id;
|
|
709
|
+
const initialWidget = {
|
|
710
|
+
id,
|
|
711
|
+
};
|
|
712
|
+
const widget = produce(initialWidget, (draft) => {
|
|
713
|
+
if (widgetDef.tabLocation) {
|
|
714
|
+
draft.tabLocation = { ...widgetDef.tabLocation };
|
|
715
|
+
}
|
|
716
|
+
if (widgetDef.popoutBounds) {
|
|
717
|
+
draft.popoutBounds = widgetDef.popoutBounds.toProps();
|
|
716
718
|
}
|
|
719
|
+
});
|
|
720
|
+
if (widget === initialWidget)
|
|
721
|
+
continue;
|
|
722
|
+
savedWidgets = produce(savedWidgets, (draft) => {
|
|
723
|
+
draft.push(widget);
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
return savedWidgets;
|
|
727
|
+
}
|
|
728
|
+
// istanbul ignore next
|
|
729
|
+
function restoreSavedWidgets(savedWidgets, frontstage) {
|
|
730
|
+
let i = savedWidgets.length;
|
|
731
|
+
while (i--) {
|
|
732
|
+
const savedWidget = savedWidgets[i];
|
|
733
|
+
const widgetId = savedWidget.id;
|
|
734
|
+
const widgetDef = frontstage.findWidgetDef(widgetId);
|
|
735
|
+
if (!widgetDef)
|
|
736
|
+
continue;
|
|
737
|
+
if (savedWidget.tabLocation) {
|
|
738
|
+
widgetDef.tabLocation = { ...savedWidget.tabLocation };
|
|
717
739
|
}
|
|
718
|
-
|
|
719
|
-
|
|
740
|
+
if (savedWidget.popoutBounds) {
|
|
741
|
+
widgetDef.popoutBounds = Rectangle.create(savedWidget.popoutBounds);
|
|
742
|
+
}
|
|
743
|
+
savedWidgets = produce(savedWidgets, (draft) => {
|
|
744
|
+
draft.splice(i, 1);
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
return savedWidgets;
|
|
720
748
|
}
|
|
721
749
|
/** @internal */
|
|
722
750
|
export function isPanelCollapsed(zoneStates, panelStates) {
|
|
@@ -724,121 +752,127 @@ export function isPanelCollapsed(zoneStates, panelStates) {
|
|
|
724
752
|
const openPanel = panelStates.find((panelState) => panelState === StagePanelState.Open);
|
|
725
753
|
return !openZone && !openPanel;
|
|
726
754
|
}
|
|
727
|
-
function
|
|
728
|
-
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
|
|
735
|
-
hideWithUiWhenFloating: !!widgetDef.hideWithUiWhenFloating,
|
|
736
|
-
});
|
|
737
|
-
nineZone.tabs[newTab.id] = newTab;
|
|
738
|
-
if (widgetDef.tabLocation.widgetId in nineZone.widgets) {
|
|
739
|
-
// Add to existing widget (by widget id).
|
|
740
|
-
const widgetId = widgetDef.tabLocation.widgetId;
|
|
741
|
-
const newTabWidget = nineZone.widgets[widgetId];
|
|
742
|
-
newTabWidget.tabs.splice(widgetDef.tabLocation.tabIndex, 0, newTab.id);
|
|
755
|
+
function addHiddenWidget(state, widgetDef) {
|
|
756
|
+
const tabLocation = widgetDef.tabLocation || widgetDef.defaultTabLocation;
|
|
757
|
+
const tabId = widgetDef.id;
|
|
758
|
+
const { widgetId, tabIndex } = tabLocation;
|
|
759
|
+
if (widgetId in state.widgets) {
|
|
760
|
+
// Add to an existing widget (by widget id).
|
|
761
|
+
return insertTabToWidget(state, tabId, widgetId, tabIndex);
|
|
743
762
|
}
|
|
744
|
-
else if (
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
}
|
|
763
|
+
else if (tabLocation.floatingWidget) {
|
|
764
|
+
const floatingWidget = tabLocation.floatingWidget;
|
|
765
|
+
assert(widgetId === floatingWidget.id);
|
|
766
|
+
// Add to a new floating widget.
|
|
767
|
+
const nzBounds = Rectangle.createFromSize(state.size);
|
|
768
|
+
const bounds = Rectangle.create(floatingWidget.bounds).containIn(nzBounds);
|
|
769
|
+
return addFloatingWidget(state, floatingWidget.id, [tabId], {
|
|
770
|
+
...floatingWidget,
|
|
771
|
+
bounds: bounds.toProps(),
|
|
772
|
+
});
|
|
755
773
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
newTabWidget.tabs.splice(widgetDef.tabLocation.tabIndex, 0, newTab.id);
|
|
764
|
-
}
|
|
765
|
-
else {
|
|
766
|
-
// Create a new panel widget.
|
|
767
|
-
const newWidget = createWidgetState(getUniqueId(), [newTab.id]);
|
|
768
|
-
nineZone.widgets[newWidget.id] = castDraft(newWidget);
|
|
769
|
-
newTabPanel.widgets.splice(widgetDef.tabLocation.widgetIndex, 0, newWidget.id);
|
|
770
|
-
}
|
|
774
|
+
// Add to a panel section.
|
|
775
|
+
const panel = state.panels[tabLocation.side];
|
|
776
|
+
// Add to existing panel section.
|
|
777
|
+
if (panel.widgets.length >= panel.maxWidgetCount) {
|
|
778
|
+
const sectionIndex = Math.min(panel.maxWidgetCount - 1, tabLocation.widgetIndex);
|
|
779
|
+
const sectionId = panel.widgets[sectionIndex];
|
|
780
|
+
return insertTabToWidget(state, tabId, sectionId, tabLocation.tabIndex);
|
|
771
781
|
}
|
|
782
|
+
// Create a new panel section.
|
|
783
|
+
const newSectionId = getUniqueId();
|
|
784
|
+
return insertPanelWidget(state, panel.side, newSectionId, [tabId], tabLocation.widgetIndex);
|
|
772
785
|
}
|
|
773
786
|
/** @internal */
|
|
774
|
-
export
|
|
787
|
+
export function setWidgetState(state, widgetDef, widgetState) {
|
|
775
788
|
var _a, _b;
|
|
776
|
-
if (
|
|
789
|
+
if (widgetState === WidgetState.Hidden) {
|
|
790
|
+
return hideWidget(state, widgetDef);
|
|
791
|
+
}
|
|
792
|
+
else if (widgetState === WidgetState.Open) {
|
|
777
793
|
const id = widgetDef.id;
|
|
778
|
-
let location =
|
|
794
|
+
let location = getTabLocation(state, id);
|
|
779
795
|
if (!location) {
|
|
780
|
-
|
|
781
|
-
location =
|
|
782
|
-
assert(!!location);
|
|
796
|
+
state = addHiddenWidget(state, widgetDef);
|
|
797
|
+
location = getTabLocation(state, id);
|
|
783
798
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
panel.collapsed && (panel.collapsed = false);
|
|
795
|
-
// istanbul ignore next
|
|
796
|
-
if (undefined === panel.size || 0 === panel.size) {
|
|
797
|
-
panel.size = (_b = panel.minSize) !== null && _b !== void 0 ? _b : 200;
|
|
799
|
+
return produce(state, (draft) => {
|
|
800
|
+
var _a;
|
|
801
|
+
assert(!!location);
|
|
802
|
+
const widget = draft.widgets[location.widgetId];
|
|
803
|
+
widget.minimized = false;
|
|
804
|
+
widget.activeTabId = id;
|
|
805
|
+
if (isFloatingTabLocation(location)) {
|
|
806
|
+
const floatingWidget = draft.floatingWidgets.byId[location.floatingWidgetId];
|
|
807
|
+
floatingWidget.hidden = false;
|
|
808
|
+
// istanbul ignore else
|
|
798
809
|
}
|
|
799
|
-
|
|
810
|
+
else if (isPanelTabLocation(location)) {
|
|
811
|
+
const panel = draft.panels[location.side];
|
|
812
|
+
panel.collapsed = false;
|
|
813
|
+
if (undefined === panel.size || 0 === panel.size) {
|
|
814
|
+
// istanbul ignore next
|
|
815
|
+
panel.size = (_a = panel.minSize) !== null && _a !== void 0 ? _a : 200;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
});
|
|
800
819
|
}
|
|
801
|
-
else if (
|
|
820
|
+
else if (widgetState === WidgetState.Closed) {
|
|
802
821
|
const id = widgetDef.id;
|
|
803
|
-
let location =
|
|
822
|
+
let location = getTabLocation(state, id);
|
|
804
823
|
if (!location) {
|
|
805
|
-
|
|
806
|
-
location =
|
|
807
|
-
assert(!!location);
|
|
808
|
-
}
|
|
809
|
-
if (isFloatingLocation(location)) {
|
|
810
|
-
const widget = nineZone.widgets[location.widgetId];
|
|
811
|
-
if (id !== widget.activeTabId)
|
|
812
|
-
return;
|
|
813
|
-
widget.minimized = true;
|
|
824
|
+
state = addHiddenWidget(state, widgetDef);
|
|
825
|
+
location = getTabLocation(state, id);
|
|
814
826
|
}
|
|
827
|
+
// TODO: should change activeTabId of a widget with multiple tabs.
|
|
828
|
+
return produce(state, (draft) => {
|
|
829
|
+
assert(!!location);
|
|
830
|
+
const widget = draft.widgets[location.widgetId];
|
|
831
|
+
if (isFloatingTabLocation(location)) {
|
|
832
|
+
if (id === widget.activeTabId) {
|
|
833
|
+
widget.minimized = true;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
});
|
|
815
837
|
}
|
|
816
|
-
else if (
|
|
817
|
-
|
|
838
|
+
else if (widgetState === WidgetState.Floating) {
|
|
839
|
+
const id = widgetDef.id;
|
|
840
|
+
let location = getTabLocation(state, id);
|
|
841
|
+
if (!location) {
|
|
842
|
+
state = addHiddenWidget(state, widgetDef);
|
|
843
|
+
location = getTabLocation(state, id);
|
|
844
|
+
}
|
|
845
|
+
assert(!!location);
|
|
846
|
+
if (isFloatingTabLocation(location))
|
|
847
|
+
return state;
|
|
848
|
+
// Widget is not floating.
|
|
849
|
+
state = removeTabFromWidget(state, id);
|
|
850
|
+
const bounds = (_b = (_a = widgetDef.tabLocation) === null || _a === void 0 ? void 0 : _a.floatingWidget) === null || _b === void 0 ? void 0 : _b.bounds;
|
|
851
|
+
state = addFloatingWidget(state, getUniqueId(), [id], { bounds });
|
|
818
852
|
}
|
|
819
|
-
|
|
853
|
+
return state;
|
|
854
|
+
}
|
|
820
855
|
/** Stores widget location and hides it in the UI. */
|
|
821
856
|
function hideWidget(state, widgetDef) {
|
|
822
|
-
const location =
|
|
857
|
+
const location = getTabLocation(state, widgetDef.id);
|
|
823
858
|
if (!location)
|
|
824
|
-
return;
|
|
825
|
-
|
|
826
|
-
|
|
859
|
+
return state;
|
|
860
|
+
// istanbul ignore else
|
|
861
|
+
if (isFloatingTabLocation(location)) {
|
|
862
|
+
const floatingWidget = state.floatingWidgets.byId[location.widgetId];
|
|
827
863
|
widgetDef.setFloatingContainerId(location.floatingWidgetId);
|
|
828
864
|
widgetDef.tabLocation = {
|
|
829
|
-
side:
|
|
830
|
-
tabIndex:
|
|
831
|
-
widgetId:
|
|
832
|
-
widgetIndex:
|
|
833
|
-
|
|
865
|
+
side: floatingWidget.home.side,
|
|
866
|
+
tabIndex: floatingWidget.home.widgetIndex,
|
|
867
|
+
widgetId: floatingWidget.id,
|
|
868
|
+
widgetIndex: floatingWidget.home.widgetIndex,
|
|
869
|
+
floatingWidget,
|
|
834
870
|
};
|
|
835
871
|
}
|
|
836
|
-
else
|
|
837
|
-
// istanbul ignore else
|
|
838
|
-
if (!isPopoutLocation(location)) {
|
|
872
|
+
else if (!isPopoutTabLocation(location)) {
|
|
839
873
|
const widgetId = location.widgetId;
|
|
840
|
-
const side =
|
|
841
|
-
const widgetIndex =
|
|
874
|
+
const side = isPanelTabLocation(location) ? location.side : "left";
|
|
875
|
+
const widgetIndex = isPanelTabLocation(location) ? state.panels[side].widgets.indexOf(widgetId) : 0;
|
|
842
876
|
const tabIndex = state.widgets[location.widgetId].tabs.indexOf(widgetDef.id);
|
|
843
877
|
widgetDef.tabLocation = {
|
|
844
878
|
side,
|
|
@@ -847,50 +881,53 @@ function hideWidget(state, widgetDef) {
|
|
|
847
881
|
widgetIndex,
|
|
848
882
|
};
|
|
849
883
|
}
|
|
850
|
-
|
|
884
|
+
return removeTabFromWidget(state, widgetDef.id);
|
|
851
885
|
}
|
|
852
886
|
/** @internal */
|
|
853
|
-
export
|
|
854
|
-
const location =
|
|
887
|
+
export function showWidget(state, id) {
|
|
888
|
+
const location = getTabLocation(state, id);
|
|
855
889
|
if (!location)
|
|
856
|
-
return;
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const panel = nineZone.panels[location.side];
|
|
860
|
-
panel.collapsed = false;
|
|
861
|
-
widget.minimized = false;
|
|
890
|
+
return state;
|
|
891
|
+
state = produce(state, (draft) => {
|
|
892
|
+
const widget = draft.widgets[location.widgetId];
|
|
862
893
|
widget.activeTabId = id;
|
|
863
|
-
|
|
894
|
+
widget.minimized = false;
|
|
895
|
+
if (isPanelTabLocation(location)) {
|
|
896
|
+
const panel = draft.panels[location.side];
|
|
897
|
+
panel.collapsed = false;
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
if (isFloatingTabLocation(location)) {
|
|
901
|
+
state = floatingWidgetBringToFront(state, location.floatingWidgetId);
|
|
864
902
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
isFloatingLocation(location) && floatingWidgetBringToFront(nineZone, location.floatingWidgetId);
|
|
868
|
-
});
|
|
903
|
+
return state;
|
|
904
|
+
}
|
|
869
905
|
/** @internal */
|
|
870
|
-
export
|
|
871
|
-
const location =
|
|
906
|
+
export function expandWidget(state, id) {
|
|
907
|
+
const location = getTabLocation(state, id);
|
|
872
908
|
if (!location)
|
|
873
|
-
return;
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
909
|
+
return state;
|
|
910
|
+
return produce(state, (draft) => {
|
|
911
|
+
const widget = draft.widgets[location.widgetId];
|
|
912
|
+
if (isPanelTabLocation(location)) {
|
|
913
|
+
const panel = draft.panels[location.side];
|
|
914
|
+
panel.widgets.forEach((wId) => {
|
|
915
|
+
const w = draft.widgets[wId];
|
|
916
|
+
w.minimized = true;
|
|
917
|
+
});
|
|
918
|
+
}
|
|
881
919
|
widget.minimized = false;
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
widget.minimized = false;
|
|
885
|
-
return;
|
|
886
|
-
});
|
|
920
|
+
});
|
|
921
|
+
}
|
|
887
922
|
/** @internal */
|
|
888
|
-
export
|
|
889
|
-
if (!(id in
|
|
890
|
-
return;
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
923
|
+
export function setWidgetLabel(state, id, label) {
|
|
924
|
+
if (!(id in state.tabs))
|
|
925
|
+
return state;
|
|
926
|
+
return produce(state, (draft) => {
|
|
927
|
+
const tab = draft.tabs[id];
|
|
928
|
+
tab.label = label;
|
|
929
|
+
});
|
|
930
|
+
}
|
|
894
931
|
/** @internal */
|
|
895
932
|
export function useSavedFrontstageState(frontstageDef) {
|
|
896
933
|
const uiStateStorage = useUiStateStorageHandler();
|
|
@@ -911,20 +948,23 @@ export function useSavedFrontstageState(frontstageDef) {
|
|
|
911
948
|
}
|
|
912
949
|
const id = frontstageDef.id;
|
|
913
950
|
const version = frontstageDef.version;
|
|
914
|
-
const
|
|
915
|
-
if (isMountedRef.current)
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
951
|
+
const settingResult = await uiStateStorageRef.current.getSetting(FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(id));
|
|
952
|
+
if (!isMountedRef.current)
|
|
953
|
+
return;
|
|
954
|
+
if (isFrontstageStateSettingResult(settingResult)) {
|
|
955
|
+
const setting = settingResult.setting;
|
|
956
|
+
if (setting.version >= version && setting.stateVersion >= stateVersion) {
|
|
957
|
+
const restored = restoreNineZoneState(frontstageDef, setting.nineZone);
|
|
958
|
+
const savedWidgets = restoreSavedWidgets(setting.widgets, frontstageDef);
|
|
920
959
|
let state = addMissingWidgets(frontstageDef, restored);
|
|
921
|
-
state =
|
|
960
|
+
state = hideWidgets(state, frontstageDef);
|
|
922
961
|
state = processPopoutWidgets(state, frontstageDef);
|
|
923
962
|
frontstageDef.nineZoneState = state;
|
|
963
|
+
frontstageDef.savedWidgetDefs = savedWidgets;
|
|
924
964
|
return;
|
|
925
965
|
}
|
|
926
|
-
frontstageDef.nineZoneState = initializeNineZoneState(frontstageDef);
|
|
927
966
|
}
|
|
967
|
+
frontstageDef.nineZoneState = initializeNineZoneState(frontstageDef);
|
|
928
968
|
}
|
|
929
969
|
fetchFrontstageState(); // eslint-disable-line @typescript-eslint/no-floating-promises
|
|
930
970
|
}, [frontstageDef]);
|
|
@@ -933,16 +973,19 @@ export function useSavedFrontstageState(frontstageDef) {
|
|
|
933
973
|
export function useSaveFrontstageSettings(frontstageDef) {
|
|
934
974
|
const nineZone = useNineZoneState(frontstageDef);
|
|
935
975
|
const uiSettingsStorage = useUiStateStorageHandler();
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
976
|
+
const saveSetting = React.useMemo(() => {
|
|
977
|
+
return debounce(async (frontstage, state, savedWidgets) => {
|
|
978
|
+
const id = frontstage.id;
|
|
979
|
+
const setting = {
|
|
980
|
+
id,
|
|
981
|
+
version: frontstage.version,
|
|
982
|
+
stateVersion,
|
|
983
|
+
nineZone: packNineZoneState(state),
|
|
984
|
+
widgets: packSavedWidgets(savedWidgets, frontstage),
|
|
985
|
+
};
|
|
986
|
+
await uiSettingsStorage.saveSetting(FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(id), setting);
|
|
987
|
+
}, 1000);
|
|
988
|
+
}, [uiSettingsStorage]);
|
|
946
989
|
React.useEffect(() => {
|
|
947
990
|
return () => {
|
|
948
991
|
saveSetting.cancel();
|
|
@@ -951,7 +994,8 @@ export function useSaveFrontstageSettings(frontstageDef) {
|
|
|
951
994
|
React.useEffect(() => {
|
|
952
995
|
if (!nineZone || nineZone.draggedTab)
|
|
953
996
|
return;
|
|
954
|
-
|
|
997
|
+
const savedWidgets = frontstageDef.savedWidgetDefs || [];
|
|
998
|
+
saveSetting(frontstageDef, nineZone, savedWidgets);
|
|
955
999
|
}, [frontstageDef, nineZone, saveSetting]);
|
|
956
1000
|
}
|
|
957
1001
|
/** @internal */
|
|
@@ -1085,7 +1129,7 @@ export function useItemsManager(frontstageDef) {
|
|
|
1085
1129
|
return;
|
|
1086
1130
|
state = addMissingWidgets(def, state);
|
|
1087
1131
|
state = removeMissingWidgets(def, state);
|
|
1088
|
-
state =
|
|
1132
|
+
state = hideWidgets(state, def); // TODO: should only apply to widgets provided by registered provider in onUiProviderRegisteredEvent.
|
|
1089
1133
|
def.nineZoneState = state;
|
|
1090
1134
|
};
|
|
1091
1135
|
React.useEffect(() => {
|
|
@@ -1098,47 +1142,8 @@ export function useItemsManager(frontstageDef) {
|
|
|
1098
1142
|
return remove;
|
|
1099
1143
|
}, [frontstageDef]);
|
|
1100
1144
|
}
|
|
1101
|
-
function tabShownInCurrentWidget(def, state) {
|
|
1102
|
-
for (const [, widget] of Object.entries(state.widgets)) {
|
|
1103
|
-
const foundTab = widget.tabs.find((tabId) => tabId === def.id);
|
|
1104
|
-
// istanbul ignore else
|
|
1105
|
-
if (foundTab)
|
|
1106
|
-
return true;
|
|
1107
|
-
}
|
|
1108
|
-
return false;
|
|
1109
|
-
}
|
|
1110
1145
|
// istanbul ignore next
|
|
1111
1146
|
function determineNewWidgets(defs, state) {
|
|
1112
|
-
|
|
1113
|
-
return (defs || []).filter((def) => !(def.id in state.tabs) || !tabShownInCurrentWidget(def, state));
|
|
1114
|
-
}
|
|
1115
|
-
/** @internal */
|
|
1116
|
-
export async function saveFrontstagePopoutWidgetSizeAndPosition(state, stageId, stageVersion, childWindowId, childWindow) {
|
|
1117
|
-
const location = findWidget(state, childWindowId);
|
|
1118
|
-
// istanbul ignore else
|
|
1119
|
-
if (location) {
|
|
1120
|
-
const adjustmentWidth = ProcessDetector.isElectronAppFrontend ? 16 : 0;
|
|
1121
|
-
const adjustmentHeight = ProcessDetector.isElectronAppFrontend ? 39 : 0;
|
|
1122
|
-
const newState = produce(state, (draft) => {
|
|
1123
|
-
const widget = draft.widgets[childWindowId];
|
|
1124
|
-
const tab = draft.tabs[widget.activeTabId];
|
|
1125
|
-
tab.preferredPopoutWidgetSize = {
|
|
1126
|
-
x: childWindow.screenX,
|
|
1127
|
-
y: childWindow.screenY,
|
|
1128
|
-
width: childWindow.innerWidth + adjustmentWidth,
|
|
1129
|
-
height: childWindow.innerHeight + adjustmentHeight,
|
|
1130
|
-
};
|
|
1131
|
-
});
|
|
1132
|
-
const setting = {
|
|
1133
|
-
id: stageId,
|
|
1134
|
-
nineZone: packNineZoneState(newState),
|
|
1135
|
-
stateVersion,
|
|
1136
|
-
version: stageVersion,
|
|
1137
|
-
};
|
|
1138
|
-
await UiFramework.getUiStateStorage().saveSetting(FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(stageId), setting);
|
|
1139
|
-
return newState;
|
|
1140
|
-
}
|
|
1141
|
-
// istanbul ignore next
|
|
1142
|
-
return state;
|
|
1147
|
+
return (defs || []).filter((def) => !(def.id in state.tabs));
|
|
1143
1148
|
}
|
|
1144
1149
|
//# sourceMappingURL=Frontstage.js.map
|