@itwin/appui-react 4.5.1 → 4.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -1
- package/lib/cjs/appui-react/accudraw/MenuButton.d.ts +2 -2
- package/lib/cjs/appui-react/accudraw/MenuButton.d.ts.map +1 -1
- package/lib/cjs/appui-react/accudraw/MenuButton.js.map +1 -1
- package/lib/cjs/appui-react/backstage/BackstageComposer.d.ts.map +1 -1
- package/lib/cjs/appui-react/backstage/BackstageComposer.js.map +1 -1
- package/lib/cjs/appui-react/childwindow/CopyStyles.d.ts.map +1 -1
- package/lib/cjs/appui-react/childwindow/CopyStyles.js +3 -1
- package/lib/cjs/appui-react/childwindow/CopyStyles.js.map +1 -1
- package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.d.ts.map +1 -1
- package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.js +2 -1
- package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.js.map +1 -1
- package/lib/cjs/appui-react/cursor/CursorInformation.d.ts +6 -6
- package/lib/cjs/appui-react/cursor/CursorInformation.d.ts.map +1 -1
- package/lib/cjs/appui-react/cursor/CursorInformation.js.map +1 -1
- package/lib/cjs/appui-react/cursor/cursormenu/CursorMenu.d.ts.map +1 -1
- package/lib/cjs/appui-react/cursor/cursormenu/CursorMenu.js.map +1 -1
- package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopup.d.ts +4 -4
- package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopup.d.ts.map +1 -1
- package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopup.js.map +1 -1
- package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts +5 -5
- package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts.map +1 -1
- package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopupManager.js.map +1 -1
- package/lib/cjs/appui-react/cursor/cursorprompt/CursorPrompt.d.ts +2 -2
- package/lib/cjs/appui-react/cursor/cursorprompt/CursorPrompt.d.ts.map +1 -1
- package/lib/cjs/appui-react/cursor/cursorprompt/CursorPrompt.js.map +1 -1
- package/lib/cjs/appui-react/dialog/ContentDialog.js.map +1 -1
- package/lib/cjs/appui-react/feedback/ElementTooltip.d.ts +1 -2
- package/lib/cjs/appui-react/feedback/ElementTooltip.d.ts.map +1 -1
- package/lib/cjs/appui-react/feedback/ElementTooltip.js.map +1 -1
- package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts +22 -26
- package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
- package/lib/cjs/appui-react/frontstage/FrontstageDef.js +185 -254
- package/lib/cjs/appui-react/frontstage/FrontstageDef.js.map +1 -1
- package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.d.ts +1 -7
- package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.d.ts.map +1 -1
- package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.js +0 -6
- package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.js.map +1 -1
- package/lib/cjs/appui-react/hooks/useActiveIModelConnection.d.ts.map +1 -1
- package/lib/cjs/appui-react/hooks/useActiveIModelConnection.js.map +1 -1
- package/lib/cjs/appui-react/hooks/useActiveViewport.d.ts.map +1 -1
- package/lib/cjs/appui-react/hooks/useActiveViewport.js.map +1 -1
- package/lib/cjs/appui-react/keyboardshortcut/InternalKeyboardShortcut.d.ts.map +1 -1
- package/lib/cjs/appui-react/keyboardshortcut/InternalKeyboardShortcut.js.map +1 -1
- package/lib/cjs/appui-react/messages/MessageManager.d.ts +0 -1
- package/lib/cjs/appui-react/messages/MessageManager.d.ts.map +1 -1
- package/lib/cjs/appui-react/messages/MessageManager.js +1 -2
- package/lib/cjs/appui-react/messages/MessageManager.js.map +1 -1
- package/lib/cjs/appui-react/messages/Pointer.d.ts +1 -2
- package/lib/cjs/appui-react/messages/Pointer.d.ts.map +1 -1
- package/lib/cjs/appui-react/messages/Pointer.js +1 -1
- package/lib/cjs/appui-react/messages/Pointer.js.map +1 -1
- package/lib/cjs/appui-react/popup/PositionPopup.d.ts +2 -2
- package/lib/cjs/appui-react/popup/PositionPopup.d.ts.map +1 -1
- package/lib/cjs/appui-react/popup/PositionPopup.js.map +1 -1
- package/lib/cjs/appui-react/settings/ui/UiSettingsPage.js.map +1 -1
- package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts +16 -20
- package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
- package/lib/cjs/appui-react/stagepanels/StagePanelDef.js +80 -115
- package/lib/cjs/appui-react/stagepanels/StagePanelDef.js.map +1 -1
- package/lib/cjs/appui-react/statusfields/MessageCenter.d.ts.map +1 -1
- package/lib/cjs/appui-react/statusfields/MessageCenter.js +1 -2
- package/lib/cjs/appui-react/statusfields/MessageCenter.js.map +1 -1
- package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts +36 -0
- package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts.map +1 -0
- package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.js +134 -0
- package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.js.map +1 -0
- package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.d.ts +1 -1
- package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.d.ts.map +1 -1
- package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.js +2 -2
- package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.js.map +1 -1
- package/lib/cjs/appui-react/syncui/UiSyncEvent.d.ts +16 -0
- package/lib/cjs/appui-react/syncui/UiSyncEvent.d.ts.map +1 -0
- package/lib/cjs/appui-react/syncui/UiSyncEvent.js +18 -0
- package/lib/cjs/appui-react/syncui/UiSyncEvent.js.map +1 -0
- package/lib/cjs/appui-react/uistate/AppUiSettings.d.ts.map +1 -1
- package/lib/cjs/appui-react/uistate/AppUiSettings.js.map +1 -1
- package/lib/cjs/appui-react/uistate/useUiStateStorage.d.ts.map +1 -1
- package/lib/cjs/appui-react/uistate/useUiStateStorage.js.map +1 -1
- package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts +7 -29
- package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
- package/lib/cjs/appui-react/widget-panels/Frontstage.js +101 -434
- package/lib/cjs/appui-react/widget-panels/Frontstage.js.map +1 -1
- package/lib/cjs/appui-react/widget-panels/ToolSettings.d.ts.map +1 -1
- package/lib/cjs/appui-react/widget-panels/ToolSettings.js +16 -3
- package/lib/cjs/appui-react/widget-panels/ToolSettings.js.map +1 -1
- package/lib/cjs/appui-react/widgets/Widget.d.ts +10 -4
- package/lib/cjs/appui-react/widgets/Widget.d.ts.map +1 -1
- package/lib/cjs/appui-react/widgets/Widget.js.map +1 -1
- package/lib/cjs/appui-react/widgets/WidgetDef.d.ts +9 -29
- package/lib/cjs/appui-react/widgets/WidgetDef.d.ts.map +1 -1
- package/lib/cjs/appui-react/widgets/WidgetDef.js +89 -46
- package/lib/cjs/appui-react/widgets/WidgetDef.js.map +1 -1
- package/lib/cjs/appui-react.d.ts +1 -0
- package/lib/cjs/appui-react.d.ts.map +1 -1
- package/lib/cjs/appui-react.js +1 -0
- package/lib/cjs/appui-react.js.map +1 -1
- package/lib/esm/appui-react/accudraw/MenuButton.d.ts +2 -2
- package/lib/esm/appui-react/accudraw/MenuButton.d.ts.map +1 -1
- package/lib/esm/appui-react/accudraw/MenuButton.js.map +1 -1
- package/lib/esm/appui-react/backstage/BackstageComposer.d.ts.map +1 -1
- package/lib/esm/appui-react/backstage/BackstageComposer.js.map +1 -1
- package/lib/esm/appui-react/childwindow/CopyStyles.d.ts.map +1 -1
- package/lib/esm/appui-react/childwindow/CopyStyles.js +3 -1
- package/lib/esm/appui-react/childwindow/CopyStyles.js.map +1 -1
- package/lib/esm/appui-react/childwindow/InternalChildWindowManager.d.ts.map +1 -1
- package/lib/esm/appui-react/childwindow/InternalChildWindowManager.js +2 -1
- package/lib/esm/appui-react/childwindow/InternalChildWindowManager.js.map +1 -1
- package/lib/esm/appui-react/cursor/CursorInformation.d.ts +6 -6
- package/lib/esm/appui-react/cursor/CursorInformation.d.ts.map +1 -1
- package/lib/esm/appui-react/cursor/CursorInformation.js.map +1 -1
- package/lib/esm/appui-react/cursor/cursormenu/CursorMenu.d.ts.map +1 -1
- package/lib/esm/appui-react/cursor/cursormenu/CursorMenu.js.map +1 -1
- package/lib/esm/appui-react/cursor/cursorpopup/CursorPopup.d.ts +4 -4
- package/lib/esm/appui-react/cursor/cursorpopup/CursorPopup.d.ts.map +1 -1
- package/lib/esm/appui-react/cursor/cursorpopup/CursorPopup.js.map +1 -1
- package/lib/esm/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts +5 -5
- package/lib/esm/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts.map +1 -1
- package/lib/esm/appui-react/cursor/cursorpopup/CursorPopupManager.js.map +1 -1
- package/lib/esm/appui-react/cursor/cursorprompt/CursorPrompt.d.ts +2 -2
- package/lib/esm/appui-react/cursor/cursorprompt/CursorPrompt.d.ts.map +1 -1
- package/lib/esm/appui-react/cursor/cursorprompt/CursorPrompt.js.map +1 -1
- package/lib/esm/appui-react/dialog/ContentDialog.js.map +1 -1
- package/lib/esm/appui-react/feedback/ElementTooltip.d.ts +1 -2
- package/lib/esm/appui-react/feedback/ElementTooltip.d.ts.map +1 -1
- package/lib/esm/appui-react/feedback/ElementTooltip.js.map +1 -1
- package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts +22 -26
- package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
- package/lib/esm/appui-react/frontstage/FrontstageDef.js +189 -258
- package/lib/esm/appui-react/frontstage/FrontstageDef.js.map +1 -1
- package/lib/esm/appui-react/frontstage/InternalFrontstageManager.d.ts +1 -7
- package/lib/esm/appui-react/frontstage/InternalFrontstageManager.d.ts.map +1 -1
- package/lib/esm/appui-react/frontstage/InternalFrontstageManager.js +0 -6
- package/lib/esm/appui-react/frontstage/InternalFrontstageManager.js.map +1 -1
- package/lib/esm/appui-react/hooks/useActiveIModelConnection.d.ts.map +1 -1
- package/lib/esm/appui-react/hooks/useActiveIModelConnection.js.map +1 -1
- package/lib/esm/appui-react/hooks/useActiveViewport.d.ts.map +1 -1
- package/lib/esm/appui-react/hooks/useActiveViewport.js.map +1 -1
- package/lib/esm/appui-react/keyboardshortcut/InternalKeyboardShortcut.d.ts.map +1 -1
- package/lib/esm/appui-react/keyboardshortcut/InternalKeyboardShortcut.js.map +1 -1
- package/lib/esm/appui-react/messages/MessageManager.d.ts +0 -1
- package/lib/esm/appui-react/messages/MessageManager.d.ts.map +1 -1
- package/lib/esm/appui-react/messages/MessageManager.js +1 -2
- package/lib/esm/appui-react/messages/MessageManager.js.map +1 -1
- package/lib/esm/appui-react/messages/Pointer.d.ts +1 -2
- package/lib/esm/appui-react/messages/Pointer.d.ts.map +1 -1
- package/lib/esm/appui-react/messages/Pointer.js +1 -1
- package/lib/esm/appui-react/messages/Pointer.js.map +1 -1
- package/lib/esm/appui-react/popup/PositionPopup.d.ts +2 -2
- package/lib/esm/appui-react/popup/PositionPopup.d.ts.map +1 -1
- package/lib/esm/appui-react/popup/PositionPopup.js.map +1 -1
- package/lib/esm/appui-react/settings/ui/UiSettingsPage.js.map +1 -1
- package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts +16 -20
- package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
- package/lib/esm/appui-react/stagepanels/StagePanelDef.js +78 -114
- package/lib/esm/appui-react/stagepanels/StagePanelDef.js.map +1 -1
- package/lib/esm/appui-react/statusfields/MessageCenter.d.ts.map +1 -1
- package/lib/esm/appui-react/statusfields/MessageCenter.js +1 -2
- package/lib/esm/appui-react/statusfields/MessageCenter.js.map +1 -1
- package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts +36 -0
- package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts.map +1 -0
- package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.js +130 -0
- package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.js.map +1 -0
- package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.d.ts +1 -1
- package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.d.ts.map +1 -1
- package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.js +2 -2
- package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.js.map +1 -1
- package/lib/esm/appui-react/syncui/UiSyncEvent.d.ts +16 -0
- package/lib/esm/appui-react/syncui/UiSyncEvent.d.ts.map +1 -0
- package/lib/esm/appui-react/syncui/UiSyncEvent.js +14 -0
- package/lib/esm/appui-react/syncui/UiSyncEvent.js.map +1 -0
- package/lib/esm/appui-react/uistate/AppUiSettings.d.ts.map +1 -1
- package/lib/esm/appui-react/uistate/AppUiSettings.js.map +1 -1
- package/lib/esm/appui-react/uistate/useUiStateStorage.d.ts.map +1 -1
- package/lib/esm/appui-react/uistate/useUiStateStorage.js.map +1 -1
- package/lib/esm/appui-react/widget-panels/Frontstage.d.ts +7 -29
- package/lib/esm/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
- package/lib/esm/appui-react/widget-panels/Frontstage.js +104 -433
- package/lib/esm/appui-react/widget-panels/Frontstage.js.map +1 -1
- package/lib/esm/appui-react/widget-panels/ToolSettings.d.ts.map +1 -1
- package/lib/esm/appui-react/widget-panels/ToolSettings.js +16 -3
- package/lib/esm/appui-react/widget-panels/ToolSettings.js.map +1 -1
- package/lib/esm/appui-react/widgets/Widget.d.ts +10 -4
- package/lib/esm/appui-react/widgets/Widget.d.ts.map +1 -1
- package/lib/esm/appui-react/widgets/Widget.js.map +1 -1
- package/lib/esm/appui-react/widgets/WidgetDef.d.ts +9 -29
- package/lib/esm/appui-react/widgets/WidgetDef.d.ts.map +1 -1
- package/lib/esm/appui-react/widgets/WidgetDef.js +89 -46
- package/lib/esm/appui-react/widgets/WidgetDef.js.map +1 -1
- package/lib/esm/appui-react.d.ts +1 -0
- package/lib/esm/appui-react.d.ts.map +1 -1
- package/lib/esm/appui-react.js +1 -0
- package/lib/esm/appui-react.js.map +1 -1
- package/package.json +10 -10
|
@@ -10,10 +10,11 @@ import "./Frontstage.scss";
|
|
|
10
10
|
import produce from "immer";
|
|
11
11
|
import * as React from "react";
|
|
12
12
|
import { unstable_batchedUpdates } from "react-dom";
|
|
13
|
-
import {
|
|
14
|
-
import { Rectangle,
|
|
13
|
+
import { Logger, ProcessDetector } from "@itwin/core-bentley";
|
|
14
|
+
import { Rectangle, UiStateStorageStatus } from "@itwin/core-react";
|
|
15
15
|
import { ToolbarPopupAutoHideContext } from "@itwin/components-react";
|
|
16
|
-
import { addDockedToolSettings, addFloatingWidget, addPanelWidget, addTab, addTabToWidget,
|
|
16
|
+
import { addDockedToolSettings, addFloatingWidget, addPanelWidget, addRemovedTab, addTab, addTabToWidget, createLayoutStore, createNineZoneState, floatingWidgetBringToFront, FloatingWidgets, getTabLocation, getUniqueId, getWidgetPanelSectionId, isFloatingTabLocation, isPanelTabLocation, NineZone, NineZoneStateReducer, removeTab, WidgetPanels, } from "@itwin/appui-layout-react";
|
|
17
|
+
import { useActiveFrontstageDef, } from "../frontstage/FrontstageDef";
|
|
17
18
|
import { StagePanelState, toPanelSide } from "../stagepanels/StagePanelDef";
|
|
18
19
|
import { UiFramework } from "../UiFramework";
|
|
19
20
|
import { useUiStateStorageHandler } from "../uistate/useUiStateStorage";
|
|
@@ -50,30 +51,19 @@ const widgetContent = React.createElement(WidgetContent, null);
|
|
|
50
51
|
const toolSettingsContent = React.createElement(ToolSettingsContent, null);
|
|
51
52
|
const widgetPanelsFrontstage = React.createElement(WidgetPanelsFrontstageComponent, null);
|
|
52
53
|
/** @internal */
|
|
53
|
-
export function useLayoutStore() {
|
|
54
|
-
const
|
|
55
|
-
const [layout, setLayout] = React.useState(() => createLayoutStore(def?.nineZoneState));
|
|
56
|
-
React.useEffect(() => {
|
|
57
|
-
return UiFramework.frontstages.onFrontstageActivatedEvent.addListener((args) => {
|
|
58
|
-
unstable_batchedUpdates(() => {
|
|
59
|
-
setDef(args.activatedFrontstageDef);
|
|
60
|
-
setLayout(createLayoutStore(args.activatedFrontstageDef.nineZoneState));
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
}, []);
|
|
54
|
+
export function useLayoutStore(frontstageDef) {
|
|
55
|
+
const layoutStore = React.useMemo(() => createLayoutStore(frontstageDef?.nineZoneState), [frontstageDef]);
|
|
64
56
|
React.useEffect(() => {
|
|
65
57
|
return InternalFrontstageManager.onFrontstageNineZoneStateChangedEvent.addListener((args) => {
|
|
66
|
-
if (args.frontstageDef !==
|
|
67
|
-
def.isStageClosing ||
|
|
68
|
-
def.isApplicationClosing)
|
|
58
|
+
if (args.frontstageDef !== frontstageDef)
|
|
69
59
|
return;
|
|
70
60
|
unstable_batchedUpdates(() => {
|
|
71
61
|
// https://github.com/pmndrs/zustand/blob/main/docs/guides/event-handler-in-pre-react-18.md
|
|
72
|
-
|
|
62
|
+
layoutStore.setState(args.state || defaultNineZone);
|
|
73
63
|
});
|
|
74
64
|
});
|
|
75
|
-
}, [
|
|
76
|
-
return
|
|
65
|
+
}, [frontstageDef, layoutStore]);
|
|
66
|
+
return layoutStore;
|
|
77
67
|
}
|
|
78
68
|
/** Update in-memory NineZoneState of newly activated frontstage with up to date size.
|
|
79
69
|
* @internal
|
|
@@ -81,65 +71,30 @@ export function useLayoutStore() {
|
|
|
81
71
|
export function useUpdateNineZoneSize(frontstageDef) {
|
|
82
72
|
React.useEffect(() => {
|
|
83
73
|
const size = InternalFrontstageManager.nineZoneSize;
|
|
84
|
-
|
|
74
|
+
const state = frontstageDef.nineZoneState;
|
|
85
75
|
if (!size || !state)
|
|
86
76
|
return;
|
|
87
|
-
|
|
77
|
+
frontstageDef.dispatch({
|
|
88
78
|
type: "RESIZE",
|
|
89
79
|
size: {
|
|
90
80
|
height: size.height,
|
|
91
81
|
width: size.width,
|
|
92
82
|
},
|
|
93
|
-
}, frontstageDef);
|
|
94
|
-
frontstageDef.nineZoneState = state;
|
|
95
|
-
}, [frontstageDef]);
|
|
96
|
-
}
|
|
97
|
-
/** @internal */
|
|
98
|
-
export function FrameworkStateReducer(state, action, frontstageDef) {
|
|
99
|
-
state = NineZoneStateReducer(state, action);
|
|
100
|
-
if (action.type === "RESIZE") {
|
|
101
|
-
state = produce(state, (draft) => {
|
|
102
|
-
for (const panelSide of panelSides) {
|
|
103
|
-
const panel = draft.panels[panelSide];
|
|
104
|
-
const location = toStagePanelLocation(panelSide);
|
|
105
|
-
const panelDef = frontstageDef.getStagePanelDef(location);
|
|
106
|
-
if (panelDef?.maxSizeSpec) {
|
|
107
|
-
panel.maxSize = getPanelMaxSize(panelDef.maxSizeSpec, panelSide, action.size);
|
|
108
|
-
if (panel.size) {
|
|
109
|
-
panel.size = Math.min(Math.max(panel.size, panel.minSize), panel.maxSize);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
83
|
});
|
|
114
|
-
}
|
|
115
|
-
return state;
|
|
84
|
+
}, [frontstageDef]);
|
|
116
85
|
}
|
|
117
86
|
/** @internal */
|
|
118
87
|
export function useNineZoneDispatch(frontstageDef) {
|
|
119
|
-
|
|
120
|
-
if (action.type === "RESIZE") {
|
|
121
|
-
InternalFrontstageManager.nineZoneSize = Size.create(action.size);
|
|
122
|
-
}
|
|
123
|
-
if (action.type === "WIDGET_TAB_POPOUT") {
|
|
124
|
-
const tabId = action.id;
|
|
125
|
-
frontstageDef.popoutWidget(tabId);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
const state = frontstageDef.nineZoneState;
|
|
129
|
-
if (!state)
|
|
130
|
-
return;
|
|
131
|
-
frontstageDef.nineZoneState = FrameworkStateReducer(state, action, frontstageDef);
|
|
132
|
-
}, [frontstageDef]);
|
|
133
|
-
return dispatch;
|
|
88
|
+
return React.useMemo(() => frontstageDef.dispatch, [frontstageDef]);
|
|
134
89
|
}
|
|
135
90
|
/** @internal */
|
|
136
91
|
export function WidgetPanelsFrontstage() {
|
|
137
|
-
const
|
|
92
|
+
const frontstageDef = useActiveFrontstageDef();
|
|
93
|
+
const layout = useLayoutStore(frontstageDef);
|
|
138
94
|
React.useEffect(() => {
|
|
139
95
|
const triggerWidowCloseProcessing = () => {
|
|
140
96
|
frontstageDef && frontstageDef.setIsApplicationClosing(true);
|
|
141
97
|
};
|
|
142
|
-
frontstageDef && frontstageDef.setIsApplicationClosing(false);
|
|
143
98
|
window.addEventListener("unload", triggerWidowCloseProcessing);
|
|
144
99
|
return () => {
|
|
145
100
|
window.removeEventListener("unload", triggerWidowCloseProcessing);
|
|
@@ -198,16 +153,17 @@ export function useLabels() {
|
|
|
198
153
|
}
|
|
199
154
|
function toTabArgs(widget) {
|
|
200
155
|
const label = getWidgetLabel(widget.label);
|
|
201
|
-
|
|
156
|
+
const args = {
|
|
202
157
|
allowedPanelTargets: widget.allowedPanelTargets?.map((location) => toPanelSide(location)),
|
|
203
158
|
hideWithUiWhenFloating: !!widget.hideWithUiWhenFloating,
|
|
204
159
|
canPopout: widget.canPopout,
|
|
205
160
|
iconSpec: widget.iconSpec,
|
|
206
|
-
|
|
161
|
+
isFloatingWidgetResizable: widget.isFloatingStateWindowResizable,
|
|
207
162
|
label,
|
|
208
163
|
preferredFloatingWidgetSize: widget.defaultFloatingSize,
|
|
209
164
|
preferredPanelWidgetSize: widget.preferredPanelSize,
|
|
210
165
|
};
|
|
166
|
+
return args;
|
|
211
167
|
}
|
|
212
168
|
/** @internal */
|
|
213
169
|
export function addWidgets(state, widgets, side, widgetId) {
|
|
@@ -255,9 +211,15 @@ export function appendWidgets(state, widgetDefs, location, section) {
|
|
|
255
211
|
preferredPanelWidgetSize,
|
|
256
212
|
userSized,
|
|
257
213
|
});
|
|
258
|
-
|
|
214
|
+
const savedTab = state.savedTabs.byId[widgetDef.id];
|
|
215
|
+
if (savedTab) {
|
|
216
|
+
state = addRemovedTab(state, widgetDef.id);
|
|
217
|
+
}
|
|
218
|
+
else if (widgetDef.isFloatingStateSupported &&
|
|
259
219
|
widgetDef.defaultState === WidgetState.Floating) {
|
|
260
|
-
const floatingContainerId = widgetDef.floatingContainerId
|
|
220
|
+
const floatingContainerId = widgetDef.floatingContainerId
|
|
221
|
+
? widgetDef.floatingContainerId
|
|
222
|
+
: getUniqueId();
|
|
261
223
|
const widgetContainerId = getWidgetId(location, section);
|
|
262
224
|
const home = {
|
|
263
225
|
side,
|
|
@@ -286,8 +248,6 @@ export function appendWidgets(state, widgetDefs, location, section) {
|
|
|
286
248
|
bounds: containedBounds.toProps(),
|
|
287
249
|
home,
|
|
288
250
|
userSized,
|
|
289
|
-
}, {
|
|
290
|
-
isFloatingStateWindowResizable: widgetDef.isFloatingStateWindowResizable,
|
|
291
251
|
});
|
|
292
252
|
}
|
|
293
253
|
}
|
|
@@ -311,24 +271,29 @@ export function appendWidgets(state, widgetDefs, location, section) {
|
|
|
311
271
|
}
|
|
312
272
|
}
|
|
313
273
|
}
|
|
274
|
+
if (widgetDef.defaultState === WidgetState.Hidden) {
|
|
275
|
+
state = NineZoneStateReducer(state, {
|
|
276
|
+
type: "WIDGET_TAB_HIDE",
|
|
277
|
+
id: widgetDef.id,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
314
280
|
}
|
|
315
281
|
return state;
|
|
316
282
|
}
|
|
317
|
-
function processPopoutWidgets(
|
|
318
|
-
//
|
|
319
|
-
if (
|
|
320
|
-
return
|
|
321
|
-
// istanbul ignore next - not unit testing electron case that reopens popout windows
|
|
322
|
-
if (initialState.popoutWidgets && ProcessDetector.isElectronAppFrontend) {
|
|
323
|
-
if (initialState.popoutWidgets.allIds.length &&
|
|
324
|
-
ProcessDetector.isElectronAppFrontend) {
|
|
325
|
-
for (const widgetContainerId of initialState.popoutWidgets.allIds) {
|
|
326
|
-
frontstageDef.openPopoutWidgetContainer(initialState, widgetContainerId);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
return initialState;
|
|
283
|
+
function processPopoutWidgets(state) {
|
|
284
|
+
// Electron reopens popout windows
|
|
285
|
+
if (ProcessDetector.isElectronAppFrontend) {
|
|
286
|
+
return state;
|
|
330
287
|
}
|
|
331
|
-
|
|
288
|
+
for (const popoutWidgetId of state.popoutWidgets.allIds) {
|
|
289
|
+
const widget = state.widgets[popoutWidgetId];
|
|
290
|
+
const id = widget.tabs[0];
|
|
291
|
+
state = NineZoneStateReducer(state, {
|
|
292
|
+
type: "WIDGET_TAB_FLOAT",
|
|
293
|
+
id,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return state;
|
|
332
297
|
}
|
|
333
298
|
/** Adds frontstageDef widgets that are missing in NineZoneState.
|
|
334
299
|
* @internal
|
|
@@ -367,7 +332,10 @@ function hideWidgets(state, frontstageDef) {
|
|
|
367
332
|
if (!widgetDef)
|
|
368
333
|
continue;
|
|
369
334
|
if (widgetDef.defaultState === WidgetState.Hidden) {
|
|
370
|
-
state =
|
|
335
|
+
state = NineZoneStateReducer(state, {
|
|
336
|
+
type: "WIDGET_TAB_HIDE",
|
|
337
|
+
id: widgetDef.id,
|
|
338
|
+
});
|
|
371
339
|
}
|
|
372
340
|
}
|
|
373
341
|
return state;
|
|
@@ -375,7 +343,7 @@ function hideWidgets(state, frontstageDef) {
|
|
|
375
343
|
/** Removes NineZoneState widgets that are missing in frontstageDef.
|
|
376
344
|
* @internal
|
|
377
345
|
*/
|
|
378
|
-
|
|
346
|
+
function removeMissingWidgets(frontstageDef, state) {
|
|
379
347
|
const toolSettingsTabId = state.toolSettings?.tabId;
|
|
380
348
|
for (const [, tab] of Object.entries(state.tabs)) {
|
|
381
349
|
if (tab.id === toolSettingsTabId)
|
|
@@ -383,6 +351,10 @@ export function removeMissingWidgets(frontstageDef, state) {
|
|
|
383
351
|
const widgetDef = frontstageDef.findWidgetDef(tab.id);
|
|
384
352
|
if (widgetDef)
|
|
385
353
|
continue;
|
|
354
|
+
state = NineZoneStateReducer(state, {
|
|
355
|
+
type: "WIDGET_TAB_HIDE",
|
|
356
|
+
id: tab.id,
|
|
357
|
+
});
|
|
386
358
|
state = removeTab(state, tab.id);
|
|
387
359
|
}
|
|
388
360
|
return state;
|
|
@@ -390,18 +362,6 @@ export function removeMissingWidgets(frontstageDef, state) {
|
|
|
390
362
|
function getWidgetLabel(label) {
|
|
391
363
|
return label === "" ? "Widget" : label;
|
|
392
364
|
}
|
|
393
|
-
function toStagePanelLocation(side) {
|
|
394
|
-
switch (side) {
|
|
395
|
-
case "bottom":
|
|
396
|
-
return StagePanelLocation.Bottom;
|
|
397
|
-
case "left":
|
|
398
|
-
return StagePanelLocation.Left;
|
|
399
|
-
case "right":
|
|
400
|
-
return StagePanelLocation.Right;
|
|
401
|
-
case "top":
|
|
402
|
-
return StagePanelLocation.Top;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
365
|
/** @internal */
|
|
406
366
|
export function getWidgetId(location, section) {
|
|
407
367
|
switch (location) {
|
|
@@ -452,36 +412,27 @@ export function isFrontstageStateSettingResult(settingsResult) {
|
|
|
452
412
|
}
|
|
453
413
|
/** @internal */
|
|
454
414
|
export function initializePanel(state, frontstageDef, location) {
|
|
455
|
-
const
|
|
415
|
+
const side = toPanelSide(location);
|
|
456
416
|
state = addPanelWidgets(state, frontstageDef, location);
|
|
457
417
|
const panelDef = frontstageDef.getStagePanelDef(location);
|
|
458
418
|
state = produce(state, (draft) => {
|
|
459
|
-
const panel = draft.panels[
|
|
460
|
-
panel.minSize = panelDef?.minSize ?? panel.minSize;
|
|
419
|
+
const panel = draft.panels[side];
|
|
420
|
+
panel.minSize = panelDef?.initialConfig?.minSize ?? panel.minSize;
|
|
461
421
|
panel.pinned = panelDef?.pinned ?? panel.pinned;
|
|
462
422
|
panel.resizable = panelDef?.resizable ?? panel.resizable;
|
|
463
|
-
|
|
464
|
-
panel.maxSize = getPanelMaxSize(panelDef.maxSizeSpec, panelSide, state.size);
|
|
465
|
-
}
|
|
466
|
-
const size = panelDef?.size;
|
|
467
|
-
panel.size =
|
|
468
|
-
size === undefined
|
|
469
|
-
? size
|
|
470
|
-
: Math.min(Math.max(size, panel.minSize), panel.maxSize);
|
|
423
|
+
panel.maxSize = panelDef?.initialConfig?.maxSize ?? panel.maxSize;
|
|
471
424
|
});
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
425
|
+
if (panelDef?.size !== undefined) {
|
|
426
|
+
state = NineZoneStateReducer(state, {
|
|
427
|
+
type: "PANEL_SET_SIZE",
|
|
428
|
+
side,
|
|
429
|
+
size: panelDef.size,
|
|
430
|
+
});
|
|
477
431
|
}
|
|
478
|
-
|
|
479
|
-
? nineZoneSize.height
|
|
480
|
-
: nineZoneSize.width;
|
|
481
|
-
return (maxSizeSpec.percentage / 100) * size;
|
|
432
|
+
return state;
|
|
482
433
|
}
|
|
483
434
|
/** @internal */
|
|
484
|
-
export const stateVersion =
|
|
435
|
+
export const stateVersion = 16; // this needs to be bumped when NineZoneState is changed (to recreate the layout).
|
|
485
436
|
/** @internal */
|
|
486
437
|
export function initializeNineZoneState(frontstageDef) {
|
|
487
438
|
let nineZone = defaultNineZone;
|
|
@@ -519,7 +470,7 @@ export function initializeNineZoneState(frontstageDef) {
|
|
|
519
470
|
nineZone = addDockedToolSettings(nineZone, toolSettingsTabId);
|
|
520
471
|
}
|
|
521
472
|
nineZone = hideWidgets(nineZone, frontstageDef);
|
|
522
|
-
nineZone = processPopoutWidgets(nineZone
|
|
473
|
+
nineZone = processPopoutWidgets(nineZone);
|
|
523
474
|
return nineZone;
|
|
524
475
|
}
|
|
525
476
|
/** Converts from saved NineZoneState to NineZoneState.
|
|
@@ -528,23 +479,23 @@ export function initializeNineZoneState(frontstageDef) {
|
|
|
528
479
|
* @internal
|
|
529
480
|
*/
|
|
530
481
|
export function restoreNineZoneState(frontstageDef, saved) {
|
|
531
|
-
let
|
|
482
|
+
let state = {
|
|
532
483
|
...saved,
|
|
533
484
|
tabs: {},
|
|
534
485
|
};
|
|
535
486
|
for (const [, tab] of Object.entries(saved.tabs)) {
|
|
536
487
|
// Re-add the placeholder tab in order to correctly remove it from the state if WidgetDef is not found.
|
|
537
|
-
|
|
488
|
+
state = addTab(state, tab.id);
|
|
538
489
|
const widgetDef = frontstageDef.findWidgetDef(tab.id);
|
|
539
490
|
if (!widgetDef) {
|
|
540
491
|
Logger.logInfo(UiFramework.loggerCategory(restoreNineZoneState), "WidgetDef is not found for saved tab.", () => ({
|
|
541
492
|
frontstageId: frontstageDef.id,
|
|
542
493
|
tabId: tab.id,
|
|
543
494
|
}));
|
|
544
|
-
|
|
495
|
+
state = removeTab(state, tab.id);
|
|
545
496
|
continue;
|
|
546
497
|
}
|
|
547
|
-
|
|
498
|
+
state = produce(state, (draft) => {
|
|
548
499
|
draft.tabs[tab.id] = {
|
|
549
500
|
...tab,
|
|
550
501
|
...toTabArgs(widgetDef),
|
|
@@ -553,7 +504,7 @@ export function restoreNineZoneState(frontstageDef, saved) {
|
|
|
553
504
|
};
|
|
554
505
|
});
|
|
555
506
|
}
|
|
556
|
-
|
|
507
|
+
state = produce(state, (draft) => {
|
|
557
508
|
// remove center panel section if one is found in left or right panels
|
|
558
509
|
const oldLeftMiddleIndex = saved.panels.left.widgets.findIndex((value) => value === "leftMiddle");
|
|
559
510
|
// istanbul ignore next
|
|
@@ -584,15 +535,18 @@ export function restoreNineZoneState(frontstageDef, saved) {
|
|
|
584
535
|
if (InternalFrontstageManager.nineZoneSize &&
|
|
585
536
|
(0 !== InternalFrontstageManager.nineZoneSize.height ||
|
|
586
537
|
0 !== InternalFrontstageManager.nineZoneSize.width)) {
|
|
587
|
-
|
|
538
|
+
state = NineZoneStateReducer(state, {
|
|
588
539
|
type: "RESIZE",
|
|
589
540
|
size: {
|
|
590
541
|
height: InternalFrontstageManager.nineZoneSize.height,
|
|
591
542
|
width: InternalFrontstageManager.nineZoneSize.width,
|
|
592
543
|
},
|
|
593
|
-
}
|
|
544
|
+
});
|
|
594
545
|
}
|
|
595
|
-
|
|
546
|
+
state = addMissingWidgets(frontstageDef, state);
|
|
547
|
+
state = hideWidgets(state, frontstageDef);
|
|
548
|
+
state = processPopoutWidgets(state);
|
|
549
|
+
return state;
|
|
596
550
|
}
|
|
597
551
|
/** Prepares NineZoneState to be saved.
|
|
598
552
|
* @note Removes toolSettings tab.
|
|
@@ -615,220 +569,10 @@ export function packNineZoneState(state) {
|
|
|
615
569
|
});
|
|
616
570
|
return packed;
|
|
617
571
|
}
|
|
618
|
-
// istanbul ignore next
|
|
619
|
-
function packSavedWidgets(frontstageDef) {
|
|
620
|
-
let savedWidgets = [];
|
|
621
|
-
for (const widgetDef of frontstageDef.widgetDefs) {
|
|
622
|
-
const id = widgetDef.id;
|
|
623
|
-
const initialWidget = {
|
|
624
|
-
id,
|
|
625
|
-
};
|
|
626
|
-
const widget = produce(initialWidget, (draft) => {
|
|
627
|
-
if (widgetDef.tabLocation) {
|
|
628
|
-
draft.tabLocation = { ...widgetDef.tabLocation };
|
|
629
|
-
}
|
|
630
|
-
if (widgetDef.popoutBounds) {
|
|
631
|
-
draft.popoutBounds = widgetDef.popoutBounds.toProps();
|
|
632
|
-
}
|
|
633
|
-
});
|
|
634
|
-
if (widget === initialWidget)
|
|
635
|
-
continue;
|
|
636
|
-
savedWidgets.push(widget);
|
|
637
|
-
}
|
|
638
|
-
// Add previously saved widgets.
|
|
639
|
-
const prevSavedWidgets = frontstageDef.savedWidgetDefs || [];
|
|
640
|
-
for (const prevWidget of prevSavedWidgets) {
|
|
641
|
-
if (savedWidgets.find((w) => w.id === prevWidget.id))
|
|
642
|
-
continue;
|
|
643
|
-
savedWidgets.push(prevWidget);
|
|
644
|
-
}
|
|
645
|
-
// Limit number of saved widgets.
|
|
646
|
-
const maxWidgets = 100;
|
|
647
|
-
if (savedWidgets.length > maxWidgets)
|
|
648
|
-
savedWidgets = savedWidgets.slice(0, maxWidgets);
|
|
649
|
-
return savedWidgets;
|
|
650
|
-
}
|
|
651
|
-
// istanbul ignore next
|
|
652
|
-
function restoreSavedWidgets(frontstage) {
|
|
653
|
-
const savedWidgets = frontstage.savedWidgetDefs || [];
|
|
654
|
-
for (const savedWidget of savedWidgets) {
|
|
655
|
-
const widgetId = savedWidget.id;
|
|
656
|
-
const widgetDef = frontstage.findWidgetDef(widgetId);
|
|
657
|
-
if (!widgetDef)
|
|
658
|
-
continue;
|
|
659
|
-
if (savedWidget.tabLocation) {
|
|
660
|
-
widgetDef.tabLocation = { ...savedWidget.tabLocation };
|
|
661
|
-
}
|
|
662
|
-
if (savedWidget.popoutBounds) {
|
|
663
|
-
widgetDef.popoutBounds = Rectangle.create(savedWidget.popoutBounds);
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
572
|
/** @internal */
|
|
668
573
|
export function isPanelCollapsed(panelState) {
|
|
669
574
|
return panelState !== StagePanelState.Open;
|
|
670
575
|
}
|
|
671
|
-
function addHiddenWidget(state, widgetDef) {
|
|
672
|
-
const tabLocation = widgetDef.tabLocation || widgetDef.defaultTabLocation;
|
|
673
|
-
const tabId = widgetDef.id;
|
|
674
|
-
const { widgetId, tabIndex } = tabLocation;
|
|
675
|
-
if (widgetId in state.widgets) {
|
|
676
|
-
// Add to an existing widget (by widget id).
|
|
677
|
-
return insertTabToWidget(state, tabId, widgetId, tabIndex);
|
|
678
|
-
}
|
|
679
|
-
else if (tabLocation.floatingWidget) {
|
|
680
|
-
const floatingWidget = tabLocation.floatingWidget;
|
|
681
|
-
assert(widgetId === floatingWidget.id);
|
|
682
|
-
// Add to a new floating widget.
|
|
683
|
-
const nzBounds = Rectangle.createFromSize(state.size);
|
|
684
|
-
const bounds = Rectangle.create(floatingWidget.bounds).containIn(nzBounds);
|
|
685
|
-
return addFloatingWidget(state, floatingWidget.id, [tabId], {
|
|
686
|
-
...floatingWidget,
|
|
687
|
-
bounds: bounds.toProps(),
|
|
688
|
-
});
|
|
689
|
-
}
|
|
690
|
-
// Add to a panel section.
|
|
691
|
-
const panel = state.panels[tabLocation.side];
|
|
692
|
-
// Add to existing panel section.
|
|
693
|
-
if (panel.widgets.length >= panel.maxWidgetCount) {
|
|
694
|
-
const sectionIndex = Math.min(panel.maxWidgetCount - 1, tabLocation.widgetIndex);
|
|
695
|
-
const sectionId = panel.widgets[sectionIndex];
|
|
696
|
-
return insertTabToWidget(state, tabId, sectionId, tabLocation.tabIndex);
|
|
697
|
-
}
|
|
698
|
-
// Create a new panel section.
|
|
699
|
-
const newSectionId = getUniqueId();
|
|
700
|
-
return insertPanelWidget(state, panel.side, newSectionId, [tabId], tabLocation.widgetIndex);
|
|
701
|
-
}
|
|
702
|
-
/** @internal */
|
|
703
|
-
export function setWidgetState(state, widgetDef, widgetState) {
|
|
704
|
-
if (widgetState === WidgetState.Hidden) {
|
|
705
|
-
return hideWidget(state, widgetDef);
|
|
706
|
-
}
|
|
707
|
-
else if (widgetState === WidgetState.Open) {
|
|
708
|
-
const id = widgetDef.id;
|
|
709
|
-
if (widgetDef.isToolSettings) {
|
|
710
|
-
if (!state.toolSettings && !widgetDef.tabLocation) {
|
|
711
|
-
state = addDockedToolSettings(state, id);
|
|
712
|
-
}
|
|
713
|
-
if (state.toolSettings?.type === "docked")
|
|
714
|
-
return state;
|
|
715
|
-
}
|
|
716
|
-
let location = getTabLocation(state, id);
|
|
717
|
-
if (!location) {
|
|
718
|
-
state = addHiddenWidget(state, widgetDef);
|
|
719
|
-
location = getTabLocation(state, id);
|
|
720
|
-
if (widgetDef.isToolSettings) {
|
|
721
|
-
state = addWidgetToolSettings(state, id);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
return produce(state, (draft) => {
|
|
725
|
-
assert(!!location);
|
|
726
|
-
const widget = draft.widgets[location.widgetId];
|
|
727
|
-
widget.minimized = false;
|
|
728
|
-
widget.activeTabId = id;
|
|
729
|
-
if (isFloatingTabLocation(location)) {
|
|
730
|
-
const floatingWidget = draft.floatingWidgets.byId[location.floatingWidgetId];
|
|
731
|
-
floatingWidget.hidden = false;
|
|
732
|
-
// istanbul ignore else
|
|
733
|
-
}
|
|
734
|
-
else if (isPanelTabLocation(location)) {
|
|
735
|
-
const panel = draft.panels[location.side];
|
|
736
|
-
panel.collapsed = false;
|
|
737
|
-
if (undefined === panel.size || 0 === panel.size) {
|
|
738
|
-
// istanbul ignore next
|
|
739
|
-
panel.size = panel.minSize ?? 200;
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
else if (widgetState === WidgetState.Closed) {
|
|
745
|
-
const id = widgetDef.id;
|
|
746
|
-
if (widgetDef.isToolSettings && state.toolSettings?.type !== "widget") {
|
|
747
|
-
return state;
|
|
748
|
-
}
|
|
749
|
-
let location = getTabLocation(state, id);
|
|
750
|
-
if (!location) {
|
|
751
|
-
state = addHiddenWidget(state, widgetDef);
|
|
752
|
-
location = getTabLocation(state, id);
|
|
753
|
-
}
|
|
754
|
-
// TODO: should change activeTabId of a widget with multiple tabs.
|
|
755
|
-
return produce(state, (draft) => {
|
|
756
|
-
assert(!!location);
|
|
757
|
-
const widget = draft.widgets[location.widgetId];
|
|
758
|
-
if (isFloatingTabLocation(location)) {
|
|
759
|
-
if (id === widget.activeTabId) {
|
|
760
|
-
widget.minimized = true;
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
else if (widgetState === WidgetState.Floating) {
|
|
766
|
-
const id = widgetDef.id;
|
|
767
|
-
let location = getTabLocation(state, id);
|
|
768
|
-
if (!location) {
|
|
769
|
-
state = addHiddenWidget(state, widgetDef);
|
|
770
|
-
location = getTabLocation(state, id);
|
|
771
|
-
}
|
|
772
|
-
assert(!!location);
|
|
773
|
-
if (isFloatingTabLocation(location))
|
|
774
|
-
return state;
|
|
775
|
-
// Widget is not floating.
|
|
776
|
-
state = removeTabFromWidget(state, id);
|
|
777
|
-
const bounds = widgetDef.tabLocation?.floatingWidget?.bounds;
|
|
778
|
-
state = addFloatingWidget(state, getUniqueId(), [id], { bounds });
|
|
779
|
-
if (widgetDef.isToolSettings) {
|
|
780
|
-
if (state.toolSettings?.type === "docked") {
|
|
781
|
-
state = removeToolSettings(state);
|
|
782
|
-
}
|
|
783
|
-
if (!state.toolSettings) {
|
|
784
|
-
state = addWidgetToolSettings(state, id);
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
return state;
|
|
789
|
-
}
|
|
790
|
-
/** Stores widget location and hides it in the UI. */
|
|
791
|
-
function hideWidget(state, widgetDef) {
|
|
792
|
-
const toolSettingsTabId = state.toolSettings?.tabId;
|
|
793
|
-
if (widgetDef.id === toolSettingsTabId) {
|
|
794
|
-
widgetDef.tabLocation = undefined;
|
|
795
|
-
state = produce(state, (draft) => {
|
|
796
|
-
draft.toolSettings = undefined;
|
|
797
|
-
});
|
|
798
|
-
if (state.toolSettings?.type === "docked")
|
|
799
|
-
return state;
|
|
800
|
-
}
|
|
801
|
-
const location = getTabLocation(state, widgetDef.id);
|
|
802
|
-
if (!location)
|
|
803
|
-
return state;
|
|
804
|
-
// istanbul ignore else
|
|
805
|
-
if (isFloatingTabLocation(location)) {
|
|
806
|
-
const floatingWidget = state.floatingWidgets.byId[location.widgetId];
|
|
807
|
-
widgetDef.setFloatingContainerId(location.floatingWidgetId);
|
|
808
|
-
widgetDef.tabLocation = {
|
|
809
|
-
side: floatingWidget.home.side,
|
|
810
|
-
tabIndex: floatingWidget.home.widgetIndex,
|
|
811
|
-
widgetId: floatingWidget.id,
|
|
812
|
-
widgetIndex: floatingWidget.home.widgetIndex,
|
|
813
|
-
floatingWidget,
|
|
814
|
-
};
|
|
815
|
-
}
|
|
816
|
-
else if (!isPopoutTabLocation(location)) {
|
|
817
|
-
const widgetId = location.widgetId;
|
|
818
|
-
const side = isPanelTabLocation(location) ? location.side : "left";
|
|
819
|
-
const widgetIndex = isPanelTabLocation(location)
|
|
820
|
-
? state.panels[side].widgets.indexOf(widgetId)
|
|
821
|
-
: 0;
|
|
822
|
-
const tabIndex = state.widgets[location.widgetId].tabs.indexOf(widgetDef.id);
|
|
823
|
-
widgetDef.tabLocation = {
|
|
824
|
-
side,
|
|
825
|
-
tabIndex,
|
|
826
|
-
widgetId,
|
|
827
|
-
widgetIndex,
|
|
828
|
-
};
|
|
829
|
-
}
|
|
830
|
-
return removeTabFromWidget(state, widgetDef.id);
|
|
831
|
-
}
|
|
832
576
|
/** @internal */
|
|
833
577
|
export function showWidget(state, id) {
|
|
834
578
|
const location = getTabLocation(state, id);
|
|
@@ -866,15 +610,6 @@ export function expandWidget(state, id) {
|
|
|
866
610
|
});
|
|
867
611
|
}
|
|
868
612
|
/** @internal */
|
|
869
|
-
export function setWidgetLabel(state, id, label) {
|
|
870
|
-
if (!(id in state.tabs))
|
|
871
|
-
return state;
|
|
872
|
-
return produce(state, (draft) => {
|
|
873
|
-
const tab = draft.tabs[id];
|
|
874
|
-
tab.label = label;
|
|
875
|
-
});
|
|
876
|
-
}
|
|
877
|
-
/** @internal */
|
|
878
613
|
export function useSavedFrontstageState(frontstageDef) {
|
|
879
614
|
const uiStateStorage = useUiStateStorageHandler();
|
|
880
615
|
const uiStateStorageRef = React.useRef(uiStateStorage);
|
|
@@ -891,7 +626,7 @@ export function useSavedFrontstageState(frontstageDef) {
|
|
|
891
626
|
React.useEffect(() => {
|
|
892
627
|
async function fetchFrontstageState() {
|
|
893
628
|
if (frontstageDef.nineZoneState) {
|
|
894
|
-
frontstageDef.nineZoneState = processPopoutWidgets(frontstageDef.nineZoneState
|
|
629
|
+
frontstageDef.nineZoneState = processPopoutWidgets(frontstageDef.nineZoneState);
|
|
895
630
|
return;
|
|
896
631
|
}
|
|
897
632
|
const id = frontstageDef.id;
|
|
@@ -903,13 +638,7 @@ export function useSavedFrontstageState(frontstageDef) {
|
|
|
903
638
|
const setting = settingResult.setting;
|
|
904
639
|
if (setting.version === version &&
|
|
905
640
|
setting.stateVersion === stateVersion) {
|
|
906
|
-
|
|
907
|
-
frontstageDef.savedWidgetDefs = setting.widgets;
|
|
908
|
-
restoreSavedWidgets(frontstageDef);
|
|
909
|
-
let state = addMissingWidgets(frontstageDef, restored);
|
|
910
|
-
state = hideWidgets(state, frontstageDef);
|
|
911
|
-
state = processPopoutWidgets(state, frontstageDef);
|
|
912
|
-
frontstageDef.nineZoneState = state;
|
|
641
|
+
frontstageDef.nineZoneState = restoreNineZoneState(frontstageDef, setting.nineZone);
|
|
913
642
|
return;
|
|
914
643
|
}
|
|
915
644
|
}
|
|
@@ -924,14 +653,11 @@ export function useSaveFrontstageSettings(frontstageDef, store) {
|
|
|
924
653
|
const saveSetting = React.useMemo(() => {
|
|
925
654
|
const debounced = debounce(async (frontstage, state) => {
|
|
926
655
|
const id = frontstage.id;
|
|
927
|
-
const widgets = packSavedWidgets(frontstage);
|
|
928
|
-
frontstage.savedWidgetDefs = widgets;
|
|
929
656
|
const setting = {
|
|
930
657
|
id,
|
|
931
658
|
version: frontstage.version,
|
|
932
659
|
stateVersion,
|
|
933
660
|
nineZone: packNineZoneState(state),
|
|
934
|
-
widgets,
|
|
935
661
|
};
|
|
936
662
|
await uiSettingsStorage.saveSetting(FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(id), setting);
|
|
937
663
|
}, 1000);
|
|
@@ -979,49 +705,11 @@ function debounce(func, duration) {
|
|
|
979
705
|
};
|
|
980
706
|
return debounced;
|
|
981
707
|
}
|
|
982
|
-
const createListener = (frontstageDef, listener) => {
|
|
983
|
-
return (...args) => {
|
|
984
|
-
if (!frontstageDef.nineZoneState)
|
|
985
|
-
return;
|
|
986
|
-
listener(...args);
|
|
987
|
-
};
|
|
988
|
-
};
|
|
989
708
|
/** @internal */
|
|
990
709
|
export function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel) {
|
|
991
|
-
React.useEffect(() => {
|
|
992
|
-
return UiFramework.frontstages.onWidgetStateChangedEvent.addListener(({ widgetDef, widgetState }) => {
|
|
993
|
-
if (!frontstageDef.nineZoneState)
|
|
994
|
-
return;
|
|
995
|
-
frontstageDef.nineZoneState = setWidgetState(frontstageDef.nineZoneState, widgetDef, widgetState);
|
|
996
|
-
});
|
|
997
|
-
}, [frontstageDef]);
|
|
998
|
-
React.useEffect(() => {
|
|
999
|
-
const listener = createListener(frontstageDef, ({ widgetDef }) => {
|
|
1000
|
-
assert(!!frontstageDef.nineZoneState);
|
|
1001
|
-
const nineZoneState = setWidgetState(frontstageDef.nineZoneState, widgetDef, WidgetState.Open);
|
|
1002
|
-
frontstageDef.nineZoneState = showWidget(nineZoneState, widgetDef.id);
|
|
1003
|
-
});
|
|
1004
|
-
InternalFrontstageManager.onWidgetShowEvent.addListener(listener);
|
|
1005
|
-
return () => {
|
|
1006
|
-
InternalFrontstageManager.onWidgetShowEvent.removeListener(listener);
|
|
1007
|
-
};
|
|
1008
|
-
}, [frontstageDef]);
|
|
1009
|
-
React.useEffect(() => {
|
|
1010
|
-
const listener = createListener(frontstageDef, ({ widgetDef }) => {
|
|
1011
|
-
assert(!!frontstageDef.nineZoneState);
|
|
1012
|
-
let nineZoneState = setWidgetState(frontstageDef.nineZoneState, widgetDef, WidgetState.Open);
|
|
1013
|
-
nineZoneState = showWidget(nineZoneState, widgetDef.id);
|
|
1014
|
-
nineZoneState = expandWidget(nineZoneState, widgetDef.id);
|
|
1015
|
-
frontstageDef.nineZoneState = nineZoneState;
|
|
1016
|
-
});
|
|
1017
|
-
InternalFrontstageManager.onWidgetExpandEvent.addListener(listener);
|
|
1018
|
-
return () => {
|
|
1019
|
-
InternalFrontstageManager.onWidgetExpandEvent.removeListener(listener);
|
|
1020
|
-
};
|
|
1021
|
-
}, [frontstageDef]);
|
|
1022
710
|
const uiSettingsStorage = useUiStateStorageHandler();
|
|
1023
711
|
React.useEffect(() => {
|
|
1024
|
-
|
|
712
|
+
return InternalFrontstageManager.onFrontstageRestoreLayoutEvent.addListener((args) => {
|
|
1025
713
|
// TODO: track restoring frontstages to support workflows: i.e. prevent loading frontstage OR saving layout when delete is pending
|
|
1026
714
|
void uiSettingsStorage.deleteSetting(FRONTSTAGE_SETTINGS_NAMESPACE, getFrontstageStateSettingName(args.frontstageDef.id));
|
|
1027
715
|
if (frontstageDef.id === args.frontstageDef.id) {
|
|
@@ -1031,52 +719,36 @@ export function useFrontstageManager(frontstageDef, useToolAsToolSettingsLabel)
|
|
|
1031
719
|
else {
|
|
1032
720
|
args.frontstageDef.nineZoneState = undefined;
|
|
1033
721
|
}
|
|
1034
|
-
};
|
|
1035
|
-
InternalFrontstageManager.onFrontstageRestoreLayoutEvent.addListener(listener);
|
|
1036
|
-
return () => {
|
|
1037
|
-
InternalFrontstageManager.onFrontstageRestoreLayoutEvent.removeListener(listener);
|
|
1038
|
-
};
|
|
1039
|
-
}, [uiSettingsStorage, frontstageDef]);
|
|
1040
|
-
React.useEffect(() => {
|
|
1041
|
-
const listener = createListener(frontstageDef, ({ widgetDef }) => {
|
|
1042
|
-
assert(!!frontstageDef.nineZoneState);
|
|
1043
|
-
const label = widgetDef.label;
|
|
1044
|
-
frontstageDef.nineZoneState = setWidgetLabel(frontstageDef.nineZoneState, widgetDef.id, label);
|
|
1045
722
|
});
|
|
1046
|
-
|
|
1047
|
-
return () => {
|
|
1048
|
-
InternalFrontstageManager.onWidgetLabelChangedEvent.removeListener(listener);
|
|
1049
|
-
};
|
|
1050
|
-
}, [frontstageDef]);
|
|
723
|
+
}, [uiSettingsStorage, frontstageDef]);
|
|
1051
724
|
const defaultLabel = React.useMemo(() => UiFramework.translate("widget.labels.toolSettings"), []);
|
|
1052
725
|
React.useEffect(() => {
|
|
1053
|
-
const updateLabel =
|
|
726
|
+
const updateLabel = () => {
|
|
727
|
+
const state = frontstageDef.nineZoneState;
|
|
728
|
+
if (!state)
|
|
729
|
+
return;
|
|
730
|
+
const toolSettingsTabId = state.toolSettings?.tabId;
|
|
731
|
+
if (!toolSettingsTabId)
|
|
732
|
+
return;
|
|
1054
733
|
const toolId = UiFramework.frontstages.activeToolId;
|
|
1055
|
-
assert(!!frontstageDef.nineZoneState);
|
|
1056
734
|
const label = useToolAsToolSettingsLabel
|
|
1057
735
|
? IModelApp.tools.find(toolId)?.flyover || defaultLabel
|
|
1058
736
|
: defaultLabel;
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
737
|
+
frontstageDef.dispatch({
|
|
738
|
+
type: "WIDGET_TAB_SET_LABEL",
|
|
739
|
+
id: toolSettingsTabId,
|
|
740
|
+
label,
|
|
741
|
+
});
|
|
742
|
+
};
|
|
1064
743
|
// Whenever the frontstageDef or the useTool... changes, keep the label up to date.
|
|
1065
744
|
updateLabel();
|
|
745
|
+
const removeListenerFuncs = [];
|
|
1066
746
|
// If useTool... is true, listen for events to keep up the label up to date.
|
|
1067
747
|
if (useToolAsToolSettingsLabel) {
|
|
1068
|
-
UiFramework.frontstages.onFrontstageReadyEvent.addListener(updateLabel);
|
|
1069
|
-
InternalFrontstageManager.onFrontstageRestoreLayoutEvent.addListener(updateLabel);
|
|
1070
|
-
UiFramework.frontstages.onToolActivatedEvent.addListener(updateLabel);
|
|
1071
|
-
UiFramework.frontstages.onToolSettingsReloadEvent.addListener(updateLabel);
|
|
748
|
+
removeListenerFuncs.push(UiFramework.frontstages.onFrontstageReadyEvent.addListener(updateLabel), InternalFrontstageManager.onFrontstageRestoreLayoutEvent.addListener(updateLabel), UiFramework.frontstages.onToolActivatedEvent.addListener(updateLabel), UiFramework.frontstages.onToolSettingsReloadEvent.addListener(updateLabel));
|
|
1072
749
|
}
|
|
1073
750
|
return () => {
|
|
1074
|
-
|
|
1075
|
-
UiFramework.frontstages.onFrontstageReadyEvent.removeListener(updateLabel);
|
|
1076
|
-
InternalFrontstageManager.onFrontstageRestoreLayoutEvent.removeListener(updateLabel);
|
|
1077
|
-
UiFramework.frontstages.onToolActivatedEvent.removeListener(updateLabel);
|
|
1078
|
-
UiFramework.frontstages.onToolSettingsReloadEvent.removeListener(updateLabel);
|
|
1079
|
-
}
|
|
751
|
+
removeListenerFuncs.forEach((removeListener) => removeListener());
|
|
1080
752
|
};
|
|
1081
753
|
}, [frontstageDef, useToolAsToolSettingsLabel, defaultLabel]);
|
|
1082
754
|
}
|
|
@@ -1086,23 +758,22 @@ export function useItemsManager(frontstageDef) {
|
|
|
1086
758
|
const refreshNineZoneState = (def) => {
|
|
1087
759
|
// Fired for both registered/unregistered. Update definitions and remove/add missing widgets.
|
|
1088
760
|
def.updateWidgetDefs();
|
|
1089
|
-
restoreSavedWidgets(def);
|
|
1090
761
|
let state = def.nineZoneState;
|
|
1091
762
|
if (!state)
|
|
1092
763
|
return;
|
|
1093
764
|
state = addMissingWidgets(def, state);
|
|
1094
765
|
state = removeMissingWidgets(def, state);
|
|
1095
|
-
state = hideWidgets(state, def); // TODO: should only apply to widgets provided by registered provider in onUiProviderRegisteredEvent.
|
|
1096
766
|
def.nineZoneState = state;
|
|
1097
767
|
};
|
|
1098
768
|
React.useEffect(() => {
|
|
1099
|
-
const remove = UiItemsManager.onUiProviderRegisteredEvent.addListener(() => {
|
|
1100
|
-
refreshNineZoneState(frontstageDef);
|
|
1101
|
-
});
|
|
1102
769
|
// Need to refresh anytime frontstageDef changes because uiItemsProvider may have added something to
|
|
1103
770
|
// another stage before it was possibly unloaded in this stage.
|
|
1104
771
|
refreshNineZoneState(frontstageDef);
|
|
1105
|
-
|
|
772
|
+
}, [frontstageDef]);
|
|
773
|
+
React.useEffect(() => {
|
|
774
|
+
return UiItemsManager.onUiProviderRegisteredEvent.addListener(() => {
|
|
775
|
+
refreshNineZoneState(frontstageDef);
|
|
776
|
+
});
|
|
1106
777
|
}, [frontstageDef]);
|
|
1107
778
|
}
|
|
1108
779
|
// istanbul ignore next
|