@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.
Files changed (194) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/lib/cjs/appui-react/accudraw/MenuButton.d.ts +2 -2
  3. package/lib/cjs/appui-react/accudraw/MenuButton.d.ts.map +1 -1
  4. package/lib/cjs/appui-react/accudraw/MenuButton.js.map +1 -1
  5. package/lib/cjs/appui-react/backstage/BackstageComposer.d.ts.map +1 -1
  6. package/lib/cjs/appui-react/backstage/BackstageComposer.js.map +1 -1
  7. package/lib/cjs/appui-react/childwindow/CopyStyles.d.ts.map +1 -1
  8. package/lib/cjs/appui-react/childwindow/CopyStyles.js +3 -1
  9. package/lib/cjs/appui-react/childwindow/CopyStyles.js.map +1 -1
  10. package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.d.ts.map +1 -1
  11. package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.js +2 -1
  12. package/lib/cjs/appui-react/childwindow/InternalChildWindowManager.js.map +1 -1
  13. package/lib/cjs/appui-react/cursor/CursorInformation.d.ts +6 -6
  14. package/lib/cjs/appui-react/cursor/CursorInformation.d.ts.map +1 -1
  15. package/lib/cjs/appui-react/cursor/CursorInformation.js.map +1 -1
  16. package/lib/cjs/appui-react/cursor/cursormenu/CursorMenu.d.ts.map +1 -1
  17. package/lib/cjs/appui-react/cursor/cursormenu/CursorMenu.js.map +1 -1
  18. package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopup.d.ts +4 -4
  19. package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopup.d.ts.map +1 -1
  20. package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopup.js.map +1 -1
  21. package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts +5 -5
  22. package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts.map +1 -1
  23. package/lib/cjs/appui-react/cursor/cursorpopup/CursorPopupManager.js.map +1 -1
  24. package/lib/cjs/appui-react/cursor/cursorprompt/CursorPrompt.d.ts +2 -2
  25. package/lib/cjs/appui-react/cursor/cursorprompt/CursorPrompt.d.ts.map +1 -1
  26. package/lib/cjs/appui-react/cursor/cursorprompt/CursorPrompt.js.map +1 -1
  27. package/lib/cjs/appui-react/dialog/ContentDialog.js.map +1 -1
  28. package/lib/cjs/appui-react/feedback/ElementTooltip.d.ts +1 -2
  29. package/lib/cjs/appui-react/feedback/ElementTooltip.d.ts.map +1 -1
  30. package/lib/cjs/appui-react/feedback/ElementTooltip.js.map +1 -1
  31. package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts +22 -26
  32. package/lib/cjs/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
  33. package/lib/cjs/appui-react/frontstage/FrontstageDef.js +185 -254
  34. package/lib/cjs/appui-react/frontstage/FrontstageDef.js.map +1 -1
  35. package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.d.ts +1 -7
  36. package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.d.ts.map +1 -1
  37. package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.js +0 -6
  38. package/lib/cjs/appui-react/frontstage/InternalFrontstageManager.js.map +1 -1
  39. package/lib/cjs/appui-react/hooks/useActiveIModelConnection.d.ts.map +1 -1
  40. package/lib/cjs/appui-react/hooks/useActiveIModelConnection.js.map +1 -1
  41. package/lib/cjs/appui-react/hooks/useActiveViewport.d.ts.map +1 -1
  42. package/lib/cjs/appui-react/hooks/useActiveViewport.js.map +1 -1
  43. package/lib/cjs/appui-react/keyboardshortcut/InternalKeyboardShortcut.d.ts.map +1 -1
  44. package/lib/cjs/appui-react/keyboardshortcut/InternalKeyboardShortcut.js.map +1 -1
  45. package/lib/cjs/appui-react/messages/MessageManager.d.ts +0 -1
  46. package/lib/cjs/appui-react/messages/MessageManager.d.ts.map +1 -1
  47. package/lib/cjs/appui-react/messages/MessageManager.js +1 -2
  48. package/lib/cjs/appui-react/messages/MessageManager.js.map +1 -1
  49. package/lib/cjs/appui-react/messages/Pointer.d.ts +1 -2
  50. package/lib/cjs/appui-react/messages/Pointer.d.ts.map +1 -1
  51. package/lib/cjs/appui-react/messages/Pointer.js +1 -1
  52. package/lib/cjs/appui-react/messages/Pointer.js.map +1 -1
  53. package/lib/cjs/appui-react/popup/PositionPopup.d.ts +2 -2
  54. package/lib/cjs/appui-react/popup/PositionPopup.d.ts.map +1 -1
  55. package/lib/cjs/appui-react/popup/PositionPopup.js.map +1 -1
  56. package/lib/cjs/appui-react/settings/ui/UiSettingsPage.js.map +1 -1
  57. package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts +16 -20
  58. package/lib/cjs/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
  59. package/lib/cjs/appui-react/stagepanels/StagePanelDef.js +80 -115
  60. package/lib/cjs/appui-react/stagepanels/StagePanelDef.js.map +1 -1
  61. package/lib/cjs/appui-react/statusfields/MessageCenter.d.ts.map +1 -1
  62. package/lib/cjs/appui-react/statusfields/MessageCenter.js +1 -2
  63. package/lib/cjs/appui-react/statusfields/MessageCenter.js.map +1 -1
  64. package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts +36 -0
  65. package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts.map +1 -0
  66. package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.js +134 -0
  67. package/lib/cjs/appui-react/syncui/InternalSyncUiEventDispatcher.js.map +1 -0
  68. package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.d.ts +1 -1
  69. package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.d.ts.map +1 -1
  70. package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.js +2 -2
  71. package/lib/cjs/appui-react/syncui/SyncUiEventDispatcher.js.map +1 -1
  72. package/lib/cjs/appui-react/syncui/UiSyncEvent.d.ts +16 -0
  73. package/lib/cjs/appui-react/syncui/UiSyncEvent.d.ts.map +1 -0
  74. package/lib/cjs/appui-react/syncui/UiSyncEvent.js +18 -0
  75. package/lib/cjs/appui-react/syncui/UiSyncEvent.js.map +1 -0
  76. package/lib/cjs/appui-react/uistate/AppUiSettings.d.ts.map +1 -1
  77. package/lib/cjs/appui-react/uistate/AppUiSettings.js.map +1 -1
  78. package/lib/cjs/appui-react/uistate/useUiStateStorage.d.ts.map +1 -1
  79. package/lib/cjs/appui-react/uistate/useUiStateStorage.js.map +1 -1
  80. package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts +7 -29
  81. package/lib/cjs/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
  82. package/lib/cjs/appui-react/widget-panels/Frontstage.js +101 -434
  83. package/lib/cjs/appui-react/widget-panels/Frontstage.js.map +1 -1
  84. package/lib/cjs/appui-react/widget-panels/ToolSettings.d.ts.map +1 -1
  85. package/lib/cjs/appui-react/widget-panels/ToolSettings.js +16 -3
  86. package/lib/cjs/appui-react/widget-panels/ToolSettings.js.map +1 -1
  87. package/lib/cjs/appui-react/widgets/Widget.d.ts +10 -4
  88. package/lib/cjs/appui-react/widgets/Widget.d.ts.map +1 -1
  89. package/lib/cjs/appui-react/widgets/Widget.js.map +1 -1
  90. package/lib/cjs/appui-react/widgets/WidgetDef.d.ts +9 -29
  91. package/lib/cjs/appui-react/widgets/WidgetDef.d.ts.map +1 -1
  92. package/lib/cjs/appui-react/widgets/WidgetDef.js +89 -46
  93. package/lib/cjs/appui-react/widgets/WidgetDef.js.map +1 -1
  94. package/lib/cjs/appui-react.d.ts +1 -0
  95. package/lib/cjs/appui-react.d.ts.map +1 -1
  96. package/lib/cjs/appui-react.js +1 -0
  97. package/lib/cjs/appui-react.js.map +1 -1
  98. package/lib/esm/appui-react/accudraw/MenuButton.d.ts +2 -2
  99. package/lib/esm/appui-react/accudraw/MenuButton.d.ts.map +1 -1
  100. package/lib/esm/appui-react/accudraw/MenuButton.js.map +1 -1
  101. package/lib/esm/appui-react/backstage/BackstageComposer.d.ts.map +1 -1
  102. package/lib/esm/appui-react/backstage/BackstageComposer.js.map +1 -1
  103. package/lib/esm/appui-react/childwindow/CopyStyles.d.ts.map +1 -1
  104. package/lib/esm/appui-react/childwindow/CopyStyles.js +3 -1
  105. package/lib/esm/appui-react/childwindow/CopyStyles.js.map +1 -1
  106. package/lib/esm/appui-react/childwindow/InternalChildWindowManager.d.ts.map +1 -1
  107. package/lib/esm/appui-react/childwindow/InternalChildWindowManager.js +2 -1
  108. package/lib/esm/appui-react/childwindow/InternalChildWindowManager.js.map +1 -1
  109. package/lib/esm/appui-react/cursor/CursorInformation.d.ts +6 -6
  110. package/lib/esm/appui-react/cursor/CursorInformation.d.ts.map +1 -1
  111. package/lib/esm/appui-react/cursor/CursorInformation.js.map +1 -1
  112. package/lib/esm/appui-react/cursor/cursormenu/CursorMenu.d.ts.map +1 -1
  113. package/lib/esm/appui-react/cursor/cursormenu/CursorMenu.js.map +1 -1
  114. package/lib/esm/appui-react/cursor/cursorpopup/CursorPopup.d.ts +4 -4
  115. package/lib/esm/appui-react/cursor/cursorpopup/CursorPopup.d.ts.map +1 -1
  116. package/lib/esm/appui-react/cursor/cursorpopup/CursorPopup.js.map +1 -1
  117. package/lib/esm/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts +5 -5
  118. package/lib/esm/appui-react/cursor/cursorpopup/CursorPopupManager.d.ts.map +1 -1
  119. package/lib/esm/appui-react/cursor/cursorpopup/CursorPopupManager.js.map +1 -1
  120. package/lib/esm/appui-react/cursor/cursorprompt/CursorPrompt.d.ts +2 -2
  121. package/lib/esm/appui-react/cursor/cursorprompt/CursorPrompt.d.ts.map +1 -1
  122. package/lib/esm/appui-react/cursor/cursorprompt/CursorPrompt.js.map +1 -1
  123. package/lib/esm/appui-react/dialog/ContentDialog.js.map +1 -1
  124. package/lib/esm/appui-react/feedback/ElementTooltip.d.ts +1 -2
  125. package/lib/esm/appui-react/feedback/ElementTooltip.d.ts.map +1 -1
  126. package/lib/esm/appui-react/feedback/ElementTooltip.js.map +1 -1
  127. package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts +22 -26
  128. package/lib/esm/appui-react/frontstage/FrontstageDef.d.ts.map +1 -1
  129. package/lib/esm/appui-react/frontstage/FrontstageDef.js +189 -258
  130. package/lib/esm/appui-react/frontstage/FrontstageDef.js.map +1 -1
  131. package/lib/esm/appui-react/frontstage/InternalFrontstageManager.d.ts +1 -7
  132. package/lib/esm/appui-react/frontstage/InternalFrontstageManager.d.ts.map +1 -1
  133. package/lib/esm/appui-react/frontstage/InternalFrontstageManager.js +0 -6
  134. package/lib/esm/appui-react/frontstage/InternalFrontstageManager.js.map +1 -1
  135. package/lib/esm/appui-react/hooks/useActiveIModelConnection.d.ts.map +1 -1
  136. package/lib/esm/appui-react/hooks/useActiveIModelConnection.js.map +1 -1
  137. package/lib/esm/appui-react/hooks/useActiveViewport.d.ts.map +1 -1
  138. package/lib/esm/appui-react/hooks/useActiveViewport.js.map +1 -1
  139. package/lib/esm/appui-react/keyboardshortcut/InternalKeyboardShortcut.d.ts.map +1 -1
  140. package/lib/esm/appui-react/keyboardshortcut/InternalKeyboardShortcut.js.map +1 -1
  141. package/lib/esm/appui-react/messages/MessageManager.d.ts +0 -1
  142. package/lib/esm/appui-react/messages/MessageManager.d.ts.map +1 -1
  143. package/lib/esm/appui-react/messages/MessageManager.js +1 -2
  144. package/lib/esm/appui-react/messages/MessageManager.js.map +1 -1
  145. package/lib/esm/appui-react/messages/Pointer.d.ts +1 -2
  146. package/lib/esm/appui-react/messages/Pointer.d.ts.map +1 -1
  147. package/lib/esm/appui-react/messages/Pointer.js +1 -1
  148. package/lib/esm/appui-react/messages/Pointer.js.map +1 -1
  149. package/lib/esm/appui-react/popup/PositionPopup.d.ts +2 -2
  150. package/lib/esm/appui-react/popup/PositionPopup.d.ts.map +1 -1
  151. package/lib/esm/appui-react/popup/PositionPopup.js.map +1 -1
  152. package/lib/esm/appui-react/settings/ui/UiSettingsPage.js.map +1 -1
  153. package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts +16 -20
  154. package/lib/esm/appui-react/stagepanels/StagePanelDef.d.ts.map +1 -1
  155. package/lib/esm/appui-react/stagepanels/StagePanelDef.js +78 -114
  156. package/lib/esm/appui-react/stagepanels/StagePanelDef.js.map +1 -1
  157. package/lib/esm/appui-react/statusfields/MessageCenter.d.ts.map +1 -1
  158. package/lib/esm/appui-react/statusfields/MessageCenter.js +1 -2
  159. package/lib/esm/appui-react/statusfields/MessageCenter.js.map +1 -1
  160. package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts +36 -0
  161. package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.d.ts.map +1 -0
  162. package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.js +130 -0
  163. package/lib/esm/appui-react/syncui/InternalSyncUiEventDispatcher.js.map +1 -0
  164. package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.d.ts +1 -1
  165. package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.d.ts.map +1 -1
  166. package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.js +2 -2
  167. package/lib/esm/appui-react/syncui/SyncUiEventDispatcher.js.map +1 -1
  168. package/lib/esm/appui-react/syncui/UiSyncEvent.d.ts +16 -0
  169. package/lib/esm/appui-react/syncui/UiSyncEvent.d.ts.map +1 -0
  170. package/lib/esm/appui-react/syncui/UiSyncEvent.js +14 -0
  171. package/lib/esm/appui-react/syncui/UiSyncEvent.js.map +1 -0
  172. package/lib/esm/appui-react/uistate/AppUiSettings.d.ts.map +1 -1
  173. package/lib/esm/appui-react/uistate/AppUiSettings.js.map +1 -1
  174. package/lib/esm/appui-react/uistate/useUiStateStorage.d.ts.map +1 -1
  175. package/lib/esm/appui-react/uistate/useUiStateStorage.js.map +1 -1
  176. package/lib/esm/appui-react/widget-panels/Frontstage.d.ts +7 -29
  177. package/lib/esm/appui-react/widget-panels/Frontstage.d.ts.map +1 -1
  178. package/lib/esm/appui-react/widget-panels/Frontstage.js +104 -433
  179. package/lib/esm/appui-react/widget-panels/Frontstage.js.map +1 -1
  180. package/lib/esm/appui-react/widget-panels/ToolSettings.d.ts.map +1 -1
  181. package/lib/esm/appui-react/widget-panels/ToolSettings.js +16 -3
  182. package/lib/esm/appui-react/widget-panels/ToolSettings.js.map +1 -1
  183. package/lib/esm/appui-react/widgets/Widget.d.ts +10 -4
  184. package/lib/esm/appui-react/widgets/Widget.d.ts.map +1 -1
  185. package/lib/esm/appui-react/widgets/Widget.js.map +1 -1
  186. package/lib/esm/appui-react/widgets/WidgetDef.d.ts +9 -29
  187. package/lib/esm/appui-react/widgets/WidgetDef.d.ts.map +1 -1
  188. package/lib/esm/appui-react/widgets/WidgetDef.js +89 -46
  189. package/lib/esm/appui-react/widgets/WidgetDef.js.map +1 -1
  190. package/lib/esm/appui-react.d.ts +1 -0
  191. package/lib/esm/appui-react.d.ts.map +1 -1
  192. package/lib/esm/appui-react.js +1 -0
  193. package/lib/esm/appui-react.js.map +1 -1
  194. package/package.json +10 -10
@@ -9,16 +9,15 @@
9
9
  import * as React from "react";
10
10
  import { IModelApp } from "@itwin/core-frontend";
11
11
  import { UiError } from "@itwin/appui-abstract";
12
- import { Rectangle } from "@itwin/core-react";
13
- import { dockWidgetContainer, floatWidget, getTabLocation, getWidgetLocation, isFloatingTabLocation, isPanelTabLocation, isPopoutTabLocation, isPopoutWidgetLocation, panelSides, popoutWidgetToChildWindow, } from "@itwin/appui-layout-react";
12
+ import { Rectangle, Size } from "@itwin/core-react";
13
+ import { getTabLocation, getWidgetLocation, isFloatingTabLocation, isFloatingWidgetLocation, isPanelTabLocation, isPopoutTabLocation, isPopoutWidgetLocation, NineZoneStateReducer, panelSides, } from "@itwin/appui-layout-react";
14
14
  import { ContentGroupProvider } from "../content/ContentGroup";
15
- import { StagePanelDef, StagePanelState, toPanelSide, } from "../stagepanels/StagePanelDef";
15
+ import { StagePanelDef, StagePanelState } from "../stagepanels/StagePanelDef";
16
16
  import { UiFramework } from "../UiFramework";
17
17
  import { WidgetDef, WidgetType } from "../widgets/WidgetDef";
18
18
  import { TimeTracker } from "../configurableui/TimeTracker";
19
19
  import { PopoutWidget } from "../childwindow/PopoutWidget";
20
- import { FrameworkStateReducer } from "../widget-panels/Frontstage";
21
- import { assert, BentleyStatus, ProcessDetector } from "@itwin/core-bentley";
20
+ import { BentleyStatus, ProcessDetector } from "@itwin/core-bentley";
22
21
  import { StageUsage } from "./StageUsage";
23
22
  import { StagePanelLocation } from "../stagepanels/StagePanelLocation";
24
23
  import { WidgetState } from "../widgets/WidgetState";
@@ -101,101 +100,90 @@ export class FrontstageDef {
101
100
  const panel = nineZone.panels[panelSide];
102
101
  const location = this.toStagePanelLocation(panelSide);
103
102
  const panelDef = this.getStagePanelDef(location);
104
- if (panelDef) {
105
- const panelState = panel.collapsed
106
- ? StagePanelState.Minimized
107
- : StagePanelState.Open;
108
- panelMap.set(panelDef, panelState);
109
- }
110
- for (const widgetId of panel.widgets) {
111
- const widget = nineZone.widgets[widgetId];
112
- // istanbul ignore else
113
- if (widget) {
114
- for (const tabId of widget.tabs) {
115
- const widgetDef = this.findWidgetDef(tabId);
116
- if (widgetDef) {
117
- let widgetState = WidgetState.Open;
118
- if (widget.minimized || tabId !== widget.activeTabId)
119
- widgetState = WidgetState.Closed;
120
- widgetMap.set(widgetDef, widgetState);
121
- }
122
- }
123
- }
124
- }
103
+ if (!panelDef)
104
+ continue;
105
+ const panelState = panel.collapsed
106
+ ? StagePanelState.Minimized
107
+ : StagePanelState.Open;
108
+ panelMap.set(panelDef, panelState);
125
109
  }
126
- // istanbul ignore next
127
- for (const widgetId of nineZone.floatingWidgets.allIds) {
128
- const widget = nineZone.widgets[widgetId];
129
- if (widget) {
130
- for (const tabId of widget.tabs) {
131
- const widgetDef = this.findWidgetDef(tabId);
132
- if (widgetDef) {
133
- let widgetState = WidgetState.Open;
134
- if (widget.minimized || tabId !== widget.activeTabId)
135
- widgetState = WidgetState.Closed;
136
- widgetMap.set(widgetDef, widgetState);
137
- }
110
+ for (const widgetDef of this.widgetDefs) {
111
+ const widgetId = widgetDef.id;
112
+ if (widgetDef === this.toolSettings) {
113
+ if (!nineZone.toolSettings) {
114
+ widgetMap.set(widgetDef, WidgetState.Hidden);
115
+ continue;
116
+ }
117
+ else if (nineZone.toolSettings.type === "docked") {
118
+ widgetMap.set(widgetDef, WidgetState.Open);
119
+ continue;
138
120
  }
139
121
  }
140
- }
141
- const toolSettingsDef = this.toolSettings;
142
- if (toolSettingsDef) {
143
- if (!nineZone.toolSettings) {
144
- widgetMap.set(toolSettingsDef, WidgetState.Hidden);
145
- }
146
- else if (nineZone.toolSettings.type === "docked") {
147
- widgetMap.set(toolSettingsDef, WidgetState.Open);
122
+ const tabLocation = getTabLocation(nineZone, widgetId);
123
+ if (!tabLocation) {
124
+ widgetMap.set(widgetDef, WidgetState.Hidden);
125
+ continue;
148
126
  }
127
+ const widget = nineZone.widgets[tabLocation.widgetId];
128
+ let widgetState = WidgetState.Open;
129
+ if (widget.minimized || widgetId !== widget.activeTabId)
130
+ widgetState = WidgetState.Closed;
131
+ widgetMap.set(widgetDef, widgetState);
149
132
  }
150
133
  }
151
- triggerStateChangeEventForWidgetsAndPanels(state) {
152
- // istanbul ignore else
153
- if (!(this._isStageClosing || this._isApplicationClosing)) {
154
- if (state) {
155
- const originalPanelStateMap = new Map();
156
- const originalWidgetStateMap = new Map();
157
- const newPanelStateMap = new Map();
158
- const newWidgetStateMap = new Map();
159
- this._nineZoneState &&
160
- this.populateStateMaps(this._nineZoneState, originalPanelStateMap, originalWidgetStateMap);
161
- this.populateStateMaps(state, newPanelStateMap, newWidgetStateMap);
162
- // set internal state value before triggering events
163
- this._nineZoneState = state;
164
- // now walk and trigger set state events
165
- newWidgetStateMap.forEach((stateValue, widgetDef) => {
166
- const originalState = originalWidgetStateMap.get(widgetDef);
167
- if (originalState !== stateValue) {
168
- UiFramework.frontstages.onWidgetStateChangedEvent.emit({
169
- widgetDef,
170
- widgetState: stateValue,
171
- });
172
- widgetDef.onWidgetStateChanged();
173
- }
174
- });
175
- newPanelStateMap.forEach((stateValue, panelDef) => {
176
- const originalState = originalPanelStateMap.get(panelDef);
177
- if (originalState !== stateValue) {
178
- UiFramework.frontstages.onPanelStateChangedEvent.emit({
179
- panelDef,
180
- panelState: stateValue,
181
- });
182
- }
183
- });
184
- for (const panelSide of panelSides) {
185
- const panel = state.panels[panelSide];
186
- const location = this.toStagePanelLocation(panelSide);
187
- const panelDef = this.getStagePanelDef(location);
188
- if (panelDef) {
189
- panelDef.size = panel.size;
190
- panelDef.pinned = panel.pinned;
191
- }
192
- }
134
+ triggerStateChangeEvents(oldState) {
135
+ const newState = this.nineZoneState;
136
+ if (!newState)
137
+ return;
138
+ if (this._isStageClosing || this._isApplicationClosing)
139
+ return;
140
+ const originalPanelStateMap = new Map();
141
+ const originalWidgetStateMap = new Map();
142
+ const newPanelStateMap = new Map();
143
+ const newWidgetStateMap = new Map();
144
+ this.populateStateMaps(oldState, originalPanelStateMap, originalWidgetStateMap);
145
+ this.populateStateMaps(newState, newPanelStateMap, newWidgetStateMap);
146
+ // Now walk and trigger set state events
147
+ newWidgetStateMap.forEach((newWidgetState, widgetDef) => {
148
+ const originalState = originalWidgetStateMap.get(widgetDef);
149
+ if (originalState === newWidgetState)
150
+ return;
151
+ widgetDef.handleWidgetStateChanged(newWidgetState);
152
+ });
153
+ newPanelStateMap.forEach((newPanelState, panelDef) => {
154
+ const originalState = originalPanelStateMap.get(panelDef);
155
+ if (originalState === newPanelState)
156
+ return;
157
+ panelDef.handlePanelStateChanged(newPanelState);
158
+ });
159
+ for (const panelSide of panelSides) {
160
+ const panel = newState.panels[panelSide];
161
+ const oldPanel = oldState.panels[panelSide];
162
+ const location = this.toStagePanelLocation(panelSide);
163
+ const panelDef = this.getStagePanelDef(location);
164
+ if (!panelDef)
165
+ continue;
166
+ if (panel.size !== oldPanel.size) {
167
+ panelDef.handleSizeChanged(panel.size);
193
168
  }
194
- else {
195
- this._nineZoneState = state;
169
+ if (panel.pinned !== oldPanel.pinned) {
170
+ panelDef.handlePinnedChanged(panel.pinned);
196
171
  }
197
172
  }
198
173
  }
174
+ handlePopouts(oldState) {
175
+ const newState = this.nineZoneState;
176
+ const oldPopouts = oldState?.popoutWidgets.allIds || [];
177
+ const newPopouts = newState?.popoutWidgets.allIds || [];
178
+ const popoutsToClose = oldPopouts.filter((p) => !newPopouts.includes(p));
179
+ const popoutsToOpen = newPopouts.filter((p) => !oldPopouts.includes(p));
180
+ for (const popoutId of popoutsToClose) {
181
+ UiFramework.childWindows.close(popoutId, true);
182
+ }
183
+ for (const popoutId of popoutsToOpen) {
184
+ this.openPopoutWidgetContainer(popoutId);
185
+ }
186
+ }
199
187
  /** @internal */
200
188
  get nineZoneState() {
201
189
  return this._nineZoneState;
@@ -203,26 +191,31 @@ export class FrontstageDef {
203
191
  set nineZoneState(state) {
204
192
  if (this._nineZoneState === state)
205
193
  return;
206
- if (!this._nineZoneState) {
207
- this._nineZoneState = state;
208
- }
209
- else {
210
- this.triggerStateChangeEventForWidgetsAndPanels(state);
211
- }
212
- // istanbul ignore next - don't trigger any side effects until stage "isReady"
213
- if (!(this._isStageClosing || this._isApplicationClosing) || this.isReady) {
214
- InternalFrontstageManager.onFrontstageNineZoneStateChangedEvent.emit({
215
- frontstageDef: this,
216
- state,
217
- });
218
- }
194
+ const oldState = this._nineZoneState;
195
+ this._nineZoneState = state;
196
+ this.handlePopouts(oldState);
197
+ if (oldState) {
198
+ this.triggerStateChangeEvents(oldState);
199
+ }
200
+ const isClosing = this._isStageClosing || this._isApplicationClosing;
201
+ if (isClosing && !this.isReady)
202
+ return;
203
+ InternalFrontstageManager.onFrontstageNineZoneStateChangedEvent.emit({
204
+ frontstageDef: this,
205
+ state,
206
+ });
219
207
  }
220
208
  /** @internal */
221
- get savedWidgetDefs() {
222
- return this._savedWidgetDefs;
223
- }
224
- set savedWidgetDefs(widgets) {
225
- this._savedWidgetDefs = widgets;
209
+ get dispatch() {
210
+ return (this._dispatch ??= (action) => {
211
+ if (action.type === "RESIZE") {
212
+ InternalFrontstageManager.nineZoneSize = Size.create(action.size);
213
+ }
214
+ const state = this.nineZoneState;
215
+ if (!state)
216
+ return;
217
+ this.nineZoneState = NineZoneStateReducer(state, action);
218
+ });
226
219
  }
227
220
  /** @internal */
228
221
  get timeTracker() {
@@ -512,7 +505,9 @@ export class FrontstageDef {
512
505
  frontstageDef: this,
513
506
  });
514
507
  }
515
- /** @beta */
508
+ /** Restores frontstage layout to initial configuration.
509
+ * @beta
510
+ */
516
511
  restoreLayout() {
517
512
  for (const panelDef of this.panelDefs) {
518
513
  panelDef.size = panelDef.defaultSize;
@@ -542,11 +537,7 @@ export class FrontstageDef {
542
537
  if (!location)
543
538
  return WidgetState.Hidden;
544
539
  if (isFloatingTabLocation(location)) {
545
- const floatingWidget = state.floatingWidgets.byId[location.floatingWidgetId];
546
- if (floatingWidget && floatingWidget.hidden)
547
- return WidgetState.Hidden;
548
- else
549
- return WidgetState.Floating;
540
+ return WidgetState.Floating;
550
541
  }
551
542
  let collapsedPanel = false;
552
543
  // istanbul ignore else
@@ -563,24 +554,6 @@ export class FrontstageDef {
563
554
  }
564
555
  return widgetDef.defaultState;
565
556
  }
566
- /** Used only in UI 2.0 to determine StagePanelState and size from NinezoneState
567
- * @internal
568
- */
569
- getPanelCurrentState(panelDef) {
570
- // istanbul ignore next
571
- if (this.nineZoneState) {
572
- const side = toPanelSide(panelDef.location);
573
- const panel = this.nineZoneState.panels[side];
574
- if (panel)
575
- return [
576
- panel.collapsed ? StagePanelState.Minimized : StagePanelState.Open,
577
- panel.size ?? 0,
578
- panel.pinned,
579
- ];
580
- return [StagePanelState.Off, 0, false];
581
- }
582
- return [panelDef.defaultState, panelDef.defaultSize ?? 0, true];
583
- }
584
557
  isPopoutWidget(widgetId) {
585
558
  // istanbul ignore else
586
559
  if (this.nineZoneState) {
@@ -604,89 +577,65 @@ export class FrontstageDef {
604
577
  /** Create a new floating panel that contains the widget specified by its Id. Supported only when in
605
578
  * UI 2.0 or higher.
606
579
  * @param widgetId case sensitive Widget Id
607
- * @param point Position of top left corner of floating panel in pixels. If undefined {x:50, y:100} is used.
580
+ * @param position Position of top left corner of floating panel in pixels. If undefined {x:50, y:100} is used.
608
581
  * @param size defines the width and height of the floating panel. If undefined and widget has been floated before
609
582
  * the previous size is used, else {height:400, width:400} is used.
610
583
  * @beta
611
584
  */
612
- floatWidget(widgetId, point, size) {
613
- // istanbul ignore else
614
- if (this.nineZoneState) {
615
- const location = getTabLocation(this.nineZoneState, widgetId);
616
- if (location) {
617
- let popoutWidgetContainerId;
618
- if (isPopoutTabLocation(location)) {
619
- popoutWidgetContainerId = location.popoutWidgetId;
620
- }
621
- const state = floatWidget(this.nineZoneState, widgetId, point, size);
622
- // istanbul ignore else
623
- if (state) {
624
- this.nineZoneState = state;
625
- setTimeout(() => {
626
- popoutWidgetContainerId &&
627
- UiFramework.childWindows.close(popoutWidgetContainerId, true);
628
- }, 600);
629
- }
630
- }
631
- }
585
+ floatWidget(widgetId, position, size) {
586
+ const state = this.nineZoneState;
587
+ if (!state)
588
+ return;
589
+ const widgetDef = this.findWidgetDef(widgetId);
590
+ if (!widgetDef)
591
+ return;
592
+ this.dispatch({
593
+ type: "WIDGET_TAB_FLOAT",
594
+ id: widgetId,
595
+ position,
596
+ size,
597
+ });
632
598
  }
633
599
  /** Check widget and panel state to determine whether the widget is currently displayed
634
600
  * @param widgetId case-sensitive Widget Id
635
601
  * @public
636
602
  */
637
603
  isWidgetDisplayed(widgetId) {
638
- let widgetIsVisible = false;
639
- // istanbul ignore else
640
- if (this.nineZoneState) {
641
- const tabLocation = getTabLocation(this.nineZoneState, widgetId);
642
- // istanbul ignore else
643
- if (tabLocation) {
644
- if (isFloatingTabLocation(tabLocation)) {
645
- const floatingWidget = this.nineZoneState.floatingWidgets.byId[tabLocation.floatingWidgetId];
646
- // istanbul ignore else
647
- if (!!!floatingWidget.hidden)
648
- widgetIsVisible = true;
649
- }
650
- else if (isPopoutTabLocation(tabLocation)) {
651
- widgetIsVisible = true;
652
- }
653
- else {
654
- // istanbul ignore else
655
- if (isPanelTabLocation(tabLocation)) {
656
- const panel = this.nineZoneState.panels[tabLocation.side];
657
- const widgetDef = this.findWidgetDef(widgetId);
658
- if (widgetDef &&
659
- widgetDef.state === WidgetState.Open &&
660
- !panel.collapsed)
661
- widgetIsVisible = true;
662
- }
663
- }
664
- }
604
+ if (!this.nineZoneState)
605
+ return false;
606
+ const tabLocation = getTabLocation(this.nineZoneState, widgetId);
607
+ if (!tabLocation)
608
+ return false;
609
+ if (isPanelTabLocation(tabLocation)) {
610
+ const panel = this.nineZoneState.panels[tabLocation.side];
611
+ const widgetDef = this.findWidgetDef(widgetId);
612
+ const isVisible = !!widgetDef && widgetDef.state === WidgetState.Open && !panel.collapsed;
613
+ return isVisible;
665
614
  }
666
- return widgetIsVisible;
615
+ return true;
667
616
  }
668
617
  /** Opens window for specified PopoutWidget container. Used to reopen popout when running in Electron.
669
- * @internal */
670
- openPopoutWidgetContainer(state, widgetContainerId) {
618
+ * @internal
619
+ */
620
+ openPopoutWidgetContainer(widgetContainerId) {
621
+ const state = this.nineZoneState;
622
+ if (!state)
623
+ return;
671
624
  const location = getWidgetLocation(state, widgetContainerId);
672
- // istanbul ignore next
673
625
  if (!location)
674
626
  return;
675
- // istanbul ignore next
676
627
  if (!isPopoutWidgetLocation(location))
677
628
  return;
678
629
  const widget = state.widgets[widgetContainerId];
679
- const popoutWidget = state.popoutWidgets.byId[location.popoutWidgetId];
680
630
  // Popout widget should only contain a single tab.
681
- // istanbul ignore next
682
631
  if (widget.tabs.length !== 1)
683
632
  return;
684
633
  const tabId = widget.tabs[0];
685
634
  const widgetDef = this.findWidgetDef(tabId);
686
- // istanbul ignore next
687
635
  if (!widgetDef)
688
636
  return;
689
637
  const popoutContent = (React.createElement(PopoutWidget, { widgetContainerId: widgetContainerId, widgetDef: widgetDef }));
638
+ const popoutWidget = state.popoutWidgets.byId[location.popoutWidgetId];
690
639
  const bounds = Rectangle.create(popoutWidget.bounds);
691
640
  const position = {
692
641
  width: bounds.getWidth(),
@@ -699,48 +648,23 @@ export class FrontstageDef {
699
648
  /** Create a new popout/child window that contains the widget specified by its Id. Supported only when in
700
649
  * UI 2.0 or higher.
701
650
  * @param widgetId case sensitive Widget Id
702
- * @param point Position of top left corner of floating panel in pixels. If undefined {x:0, y:0} is used.
651
+ * @param position Position of top left corner of floating panel in pixels. If undefined {x:0, y:0} is used.
703
652
  * @param size defines the width and height of the floating panel. If undefined and widget has been floated before
704
653
  * the previous size is used, else {height:800, width:600} is used.
705
654
  * @beta
706
655
  */
707
- popoutWidget(widgetId, point, size) {
708
- // istanbul ignore next
709
- if (!this.nineZoneState)
710
- return;
711
- let location = getTabLocation(this.nineZoneState, widgetId);
712
- if (!location || isPopoutTabLocation(location))
656
+ popoutWidget(widgetId, position, size) {
657
+ const state = this.nineZoneState;
658
+ if (!state)
713
659
  return;
714
660
  const widgetDef = this.findWidgetDef(widgetId);
715
- // istanbul ignore next
716
661
  if (!widgetDef)
717
662
  return;
718
- // get the state to apply that will pop-out the specified WidgetTab to child window.
719
- let preferredBounds = Rectangle.createFromSize({ height: 800, width: 600 });
720
- // istanbul ignore next
721
- if (widgetDef.popoutBounds)
722
- preferredBounds = widgetDef.popoutBounds;
723
- if (size)
724
- preferredBounds = preferredBounds.setSize(size);
725
- if (point)
726
- preferredBounds = preferredBounds.setPosition(point);
727
- const state = popoutWidgetToChildWindow(this.nineZoneState, widgetId, preferredBounds);
728
- this.nineZoneState = state;
729
- // now that the state is updated get the id of the container that houses the widgetTab/widgetId
730
- location = getTabLocation(state, widgetId);
731
- assert(!!location && isPopoutTabLocation(location));
732
- const widgetContainerId = location.widgetId;
733
- const popoutWidget = state.popoutWidgets.byId[widgetContainerId];
734
- const bounds = Rectangle.create(popoutWidget.bounds);
735
- setTimeout(() => {
736
- const popoutContent = (React.createElement(PopoutWidget, { widgetContainerId: widgetContainerId, widgetDef: widgetDef }));
737
- const position = {
738
- width: bounds.getWidth(),
739
- height: bounds.getHeight(),
740
- left: bounds.left,
741
- top: bounds.top,
742
- };
743
- UiFramework.childWindows.open(widgetContainerId, widgetDef.label, popoutContent, position, UiFramework.useDefaultPopoutUrl);
663
+ this.dispatch({
664
+ type: "WIDGET_TAB_POPOUT",
665
+ id: widgetId,
666
+ position,
667
+ size,
744
668
  });
745
669
  }
746
670
  get isStageClosing() {
@@ -754,12 +678,13 @@ export class FrontstageDef {
754
678
  }
755
679
  /** @internal */
756
680
  saveChildWindowSizeAndPosition(childWindowId, childWindow) {
757
- if (!this.nineZoneState)
681
+ const state = this.nineZoneState;
682
+ if (!state)
758
683
  return;
759
- const location = getWidgetLocation(this.nineZoneState, childWindowId);
684
+ const location = getWidgetLocation(state, childWindowId);
760
685
  if (!location || !isPopoutWidgetLocation(location))
761
686
  return;
762
- const widget = this.nineZoneState.widgets[location.popoutWidgetId];
687
+ const widget = state.widgets[location.popoutWidgetId];
763
688
  const tabId = widget.tabs[0];
764
689
  const widgetDef = this.findWidgetDef(tabId);
765
690
  if (!widgetDef)
@@ -772,23 +697,34 @@ export class FrontstageDef {
772
697
  x: childWindow.screenX,
773
698
  y: childWindow.screenY,
774
699
  });
775
- widgetDef.popoutBounds = bounds;
700
+ this.dispatch({
701
+ type: "WIDGET_TAB_SET_POPOUT_BOUNDS",
702
+ id: tabId,
703
+ bounds,
704
+ });
776
705
  }
777
- /** Method used to possibly change a Popout Widget back to a docked widget if the user was the one closing the popout's child
778
- * window.
779
- * @internal
780
- */
781
- dockPopoutWidgetContainer(widgetContainerId) {
782
- if (!this.nineZoneState)
706
+ /** @internal */
707
+ dockWidgetContainerByContainerId(widgetContainerId) {
708
+ const state = this.nineZoneState;
709
+ if (!state)
783
710
  return;
784
- // Make sure the widgetContainerId is still in popout state. We don't want to set it to docked if the window is being closed because
785
- // an API call has moved the widget from a popout state to a floating state.
786
- // istanbul ignore else
787
- const location = getWidgetLocation(this.nineZoneState, widgetContainerId);
788
- if (!location || !isPopoutWidgetLocation(location))
711
+ const location = getWidgetLocation(state, widgetContainerId);
712
+ if (!location)
713
+ return;
714
+ if (isFloatingWidgetLocation(location)) {
715
+ this.dispatch({
716
+ type: "FLOATING_WIDGET_SEND_BACK",
717
+ id: location.floatingWidgetId,
718
+ });
719
+ return;
720
+ }
721
+ if (isPopoutWidgetLocation(location)) {
722
+ this.dispatch({
723
+ type: "POPOUT_WIDGET_SEND_BACK",
724
+ id: location.popoutWidgetId,
725
+ });
789
726
  return;
790
- const state = dockWidgetContainer(this.nineZoneState, widgetContainerId, true);
791
- this.nineZoneState = state;
727
+ }
792
728
  }
793
729
  /** Finds the container with the specified widget and re-docks all widgets
794
730
  * back to the panel zone location that was used when the floating container
@@ -797,34 +733,28 @@ export class FrontstageDef {
797
733
  * @beta
798
734
  */
799
735
  dockWidgetContainer(widgetId) {
800
- // istanbul ignore else
801
- if (this.nineZoneState) {
802
- const location = getTabLocation(this.nineZoneState, widgetId);
803
- if (location) {
804
- const widgetContainerId = location.widgetId;
805
- const state = dockWidgetContainer(this.nineZoneState, widgetContainerId, true);
806
- state && (this.nineZoneState = state);
807
- if (isPopoutTabLocation(location)) {
808
- UiFramework.childWindows.close(location.widgetId, true);
809
- }
810
- }
811
- }
736
+ const state = this.nineZoneState;
737
+ if (!state)
738
+ return;
739
+ const location = getTabLocation(state, widgetId);
740
+ if (!location)
741
+ return;
742
+ this.dockWidgetContainerByContainerId(location.widgetId);
812
743
  }
813
744
  setFloatingWidgetContainerBounds(floatingWidgetId, bounds) {
814
745
  if (!this.nineZoneState ||
815
746
  !(floatingWidgetId in this.nineZoneState.floatingWidgets.byId))
816
747
  return false;
817
- let state = FrameworkStateReducer(this.nineZoneState, {
748
+ this.dispatch({
818
749
  type: "FLOATING_WIDGET_SET_BOUNDS",
819
750
  id: floatingWidgetId,
820
751
  bounds,
821
- }, this);
822
- state = FrameworkStateReducer(state, {
752
+ });
753
+ this.dispatch({
823
754
  type: "FLOATING_WIDGET_SET_USER_SIZED",
824
755
  id: floatingWidgetId,
825
756
  userSized: true,
826
- }, this);
827
- this.nineZoneState = state;
757
+ });
828
758
  return true;
829
759
  }
830
760
  getFloatingWidgetContainerIds() {
@@ -920,8 +850,9 @@ export const useActiveFrontstageId = () => {
920
850
  const id = React.useMemo(() => (def ? /* istanbul ignore next */ def.id : ""), [def]);
921
851
  return id;
922
852
  };
923
- /** Hook to return the active Frontstage def */
924
- /** @public */
853
+ /** Hook to return the active Frontstage def.
854
+ * @public
855
+ */
925
856
  export function useActiveFrontstageDef() {
926
857
  const [def, setDef] = React.useState(UiFramework.frontstages.activeFrontstageDef);
927
858
  React.useEffect(() => {