@finsemble/finsemble-ui 8.0.2 → 8.1.0-beta.2
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/FEA.d.ts +48 -3
- package/FEA.d.ts.map +1 -1
- package/FEA.js.map +1 -1
- package/clients/Interop/FinsembleDesktopAgent.js +1 -1
- package/clients/Startup/FSBLDesktop.d.ts +2 -14
- package/clients/Startup/FSBLDesktop.d.ts.map +1 -1
- package/clients/Startup/FSBLDesktop.js +4 -21
- package/clients/Startup/FSBLDesktop.js.map +1 -1
- package/clients/Startup/types.d.ts +17 -0
- package/clients/Startup/types.d.ts.map +1 -1
- package/clients/Startup/windowStartup.d.ts.map +1 -1
- package/clients/Startup/windowStartup.js +16 -14
- package/clients/Startup/windowStartup.js.map +1 -1
- package/clients/routerClient.d.ts +2 -169
- package/clients/routerClient.d.ts.map +1 -1
- package/clients/routerClient.js +4 -7
- package/clients/routerClient.js.map +1 -1
- package/common/Desktop.d.ts +8 -0
- package/common/Desktop.d.ts.map +1 -1
- package/common/Desktop.js +23 -0
- package/common/Desktop.js.map +1 -1
- package/common/FinsembleWindow.d.ts +1 -2
- package/common/FinsembleWindow.d.ts.map +1 -1
- package/common/FinsembleWindow.js +1 -1
- package/common/FinsembleWindow.js.map +1 -1
- package/common/Monitors.d.ts +6 -0
- package/common/Monitors.d.ts.map +1 -1
- package/common/Monitors.js +22 -0
- package/common/Monitors.js.map +1 -1
- package/common/system.d.ts +1 -1
- package/common/system.d.ts.map +1 -1
- package/main.d.ts +29 -29
- package/package.json +44 -44
- package/platform/services/Interop/types.d.ts +1 -0
- package/platform/services/Interop/types.d.ts.map +1 -1
- package/platform/services/Interop/types.js.map +1 -1
- package/platform/services/router/routerTransport.d.ts.map +1 -1
- package/platform/services/router/routerTransport.js +5 -7
- package/platform/services/router/routerTransport.js.map +1 -1
- package/platform/services/router/types.d.ts +214 -0
- package/platform/services/router/types.d.ts.map +1 -0
- package/platform/services/router/types.js +2 -0
- package/platform/services/router/types.js.map +1 -0
- package/platform/services/types.d.ts +1 -0
- package/platform/services/types.d.ts.map +1 -1
- package/platform/services/types.js +1 -0
- package/platform/services/types.js.map +1 -1
- package/platform/services/window/Common/Pools/ObjectPool.d.ts +11 -0
- package/platform/services/window/Common/Pools/ObjectPool.d.ts.map +1 -0
- package/platform/services/window/Common/Pools/ObjectPool.js +43 -0
- package/platform/services/window/Common/Pools/ObjectPool.js.map +1 -0
- package/platform/services/window/Common/Pools/PoolSingletons.d.ts +10 -0
- package/platform/services/window/Common/Pools/PoolSingletons.d.ts.map +1 -0
- package/platform/services/window/Common/Pools/PoolSingletons.js +10 -0
- package/platform/services/window/Common/Pools/PoolSingletons.js.map +1 -0
- package/platform/services/window/Common/Pools/WindowPool.d.ts +7 -0
- package/platform/services/window/Common/Pools/WindowPool.d.ts.map +1 -0
- package/platform/services/window/Common/Pools/WindowPool.js +16 -0
- package/platform/services/window/Common/Pools/WindowPool.js.map +1 -0
- package/platform/services/window/Docking/boxMath.d.ts +144 -0
- package/platform/services/window/Docking/boxMath.d.ts.map +1 -0
- package/platform/services/window/Docking/boxMath.js +511 -0
- package/platform/services/window/Docking/boxMath.js.map +1 -0
- package/platform/services/window/Docking/constants.d.ts +29 -0
- package/platform/services/window/Docking/constants.d.ts.map +1 -0
- package/platform/services/window/Docking/constants.js +29 -0
- package/platform/services/window/Docking/constants.js.map +1 -0
- package/platform/services/window/Docking/dockableBox.d.ts +117 -0
- package/platform/services/window/Docking/dockableBox.d.ts.map +1 -0
- package/platform/services/window/Docking/dockableBox.js +525 -0
- package/platform/services/window/Docking/dockableBox.js.map +1 -0
- package/platform/services/window/Docking/dockableGroup.d.ts +252 -0
- package/platform/services/window/Docking/dockableGroup.d.ts.map +1 -0
- package/platform/services/window/Docking/dockableGroup.js +1054 -0
- package/platform/services/window/Docking/dockableGroup.js.map +1 -0
- package/platform/services/window/Docking/dockableMonitor.d.ts +99 -0
- package/platform/services/window/Docking/dockableMonitor.d.ts.map +1 -0
- package/platform/services/window/Docking/dockableMonitor.js +427 -0
- package/platform/services/window/Docking/dockableMonitor.js.map +1 -0
- package/platform/services/window/Docking/dockableWindow.d.ts +272 -0
- package/platform/services/window/Docking/dockableWindow.d.ts.map +1 -0
- package/platform/services/window/Docking/dockableWindow.js +1239 -0
- package/platform/services/window/Docking/dockableWindow.js.map +1 -0
- package/platform/services/window/Docking/dockingCalculator.d.ts +749 -0
- package/platform/services/window/Docking/dockingCalculator.d.ts.map +1 -0
- package/platform/services/window/Docking/dockingCalculator.js +3473 -0
- package/platform/services/window/Docking/dockingCalculator.js.map +1 -0
- package/platform/services/window/Docking/dockingMain.d.ts +349 -0
- package/platform/services/window/Docking/dockingMain.d.ts.map +1 -0
- package/platform/services/window/Docking/dockingMain.js +2584 -0
- package/platform/services/window/Docking/dockingMain.js.map +1 -0
- package/platform/services/window/Docking/maskBoundsCalculator.d.ts +28 -0
- package/platform/services/window/Docking/maskBoundsCalculator.d.ts.map +1 -0
- package/platform/services/window/Docking/maskBoundsCalculator.js +67 -0
- package/platform/services/window/Docking/maskBoundsCalculator.js.map +1 -0
- package/platform/services/window/Docking/monitorUpdateHandler.d.ts +32 -0
- package/platform/services/window/Docking/monitorUpdateHandler.d.ts.map +1 -0
- package/platform/services/window/Docking/monitorUpdateHandler.js +117 -0
- package/platform/services/window/Docking/monitorUpdateHandler.js.map +1 -0
- package/platform/services/window/Docking/types.d.ts +334 -0
- package/platform/services/window/Docking/types.d.ts.map +1 -0
- package/platform/services/window/Docking/types.js +12 -0
- package/platform/services/window/Docking/types.js.map +1 -0
- package/platform/services/window/MultiWindowFeatures/autoArrange.d.ts +90 -0
- package/platform/services/window/MultiWindowFeatures/autoArrange.d.ts.map +1 -0
- package/platform/services/window/MultiWindowFeatures/autoArrange.js +510 -0
- package/platform/services/window/MultiWindowFeatures/autoArrange.js.map +1 -0
- package/platform/services/window/StackedWindowManager/stackedWindowManager.d.ts +411 -0
- package/platform/services/window/StackedWindowManager/stackedWindowManager.d.ts.map +1 -0
- package/platform/services/window/StackedWindowManager/stackedWindowManager.js +1641 -0
- package/platform/services/window/StackedWindowManager/stackedWindowManager.js.map +1 -0
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.d.ts +9 -0
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.d.ts.map +1 -0
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.js +23 -0
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.js.map +1 -0
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.d.ts +227 -0
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.d.ts.map +1 -0
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.js +1168 -0
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.js.map +1 -0
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.d.ts +121 -0
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.d.ts.map +1 -0
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.js +591 -0
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.js.map +1 -0
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.d.ts +194 -0
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.d.ts.map +1 -0
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.js +680 -0
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.js.map +1 -0
- package/platform/services/window/types.d.ts +13 -13
- package/platform/services/window/windowGroup.d.ts +86 -0
- package/platform/services/window/windowGroup.d.ts.map +1 -0
- package/platform/services/window/windowGroup.js +323 -0
- package/platform/services/window/windowGroup.js.map +1 -0
- package/platform/services/workspace/windowStorageManager.d.ts +178 -0
- package/platform/services/workspace/windowStorageManager.d.ts.map +1 -0
- package/platform/services/workspace/windowStorageManager.js +195 -0
- package/platform/services/workspace/windowStorageManager.js.map +1 -0
- package/platform/services/workspace/workspaceAdminAPI.d.ts +1 -1
- package/platform/services/workspace/workspaceAdminAPI.d.ts.map +1 -1
- package/react/actions/smartDesktopDesignerActions.d.ts +2 -0
- package/react/actions/smartDesktopDesignerActions.d.ts.map +1 -1
- package/react/actions/smartDesktopDesignerActions.js +1 -0
- package/react/actions/smartDesktopDesignerActions.js.map +1 -1
- package/react/assets/css/download.css +119 -0
- package/react/assets/css/userPreferences.css +50 -0
- package/react/assets/css/windowTitleBar.css +2 -1
- package/react/assets/icons/cancel.svg +15 -0
- package/react/assets/icons/gear.svg +9 -0
- package/react/assets/icons/pause.svg +15 -0
- package/react/assets/icons/resume.svg +17 -0
- package/react/assets/img/Finsemble-installation.gif +0 -0
- package/react/components/common/Button.d.ts +1 -0
- package/react/components/common/Button.d.ts.map +1 -1
- package/react/components/common/Button.js.map +1 -1
- package/react/components/common/ButtonIcon.d.ts.map +1 -1
- package/react/components/common/ButtonIcon.js +3 -2
- package/react/components/common/ButtonIcon.js.map +1 -1
- package/react/components/common/FinsembleIcon.d.ts +1 -1
- package/react/components/common/FinsembleIcon.d.ts.map +1 -1
- package/react/components/common/FinsembleIcon.js +8 -0
- package/react/components/common/FinsembleIcon.js.map +1 -1
- package/react/components/common/css/button.css +8 -2
- package/react/components/downloadManager/DownloadItem.d.ts +16 -0
- package/react/components/downloadManager/DownloadItem.d.ts.map +1 -0
- package/react/components/downloadManager/DownloadItem.js +74 -0
- package/react/components/downloadManager/DownloadItem.js.map +1 -0
- package/react/components/downloadManager/DownloadManager.d.ts +10 -0
- package/react/components/downloadManager/DownloadManager.d.ts.map +1 -0
- package/react/components/downloadManager/DownloadManager.js +42 -0
- package/react/components/downloadManager/DownloadManager.js.map +1 -0
- package/react/components/downloadManager/index.d.ts +2 -0
- package/react/components/downloadManager/index.d.ts.map +1 -0
- package/react/components/downloadManager/index.js +2 -0
- package/react/components/downloadManager/index.js.map +1 -0
- package/react/components/fdc3Resolver/ResolverDialog.css +1 -1
- package/react/components/index.d.ts +1 -0
- package/react/components/index.d.ts.map +1 -1
- package/react/components/index.js +1 -0
- package/react/components/index.js.map +1 -1
- package/react/components/processMonitor/ProcessMonitor.d.ts.map +1 -1
- package/react/components/processMonitor/ProcessMonitor.js +56 -75
- package/react/components/processMonitor/ProcessMonitor.js.map +1 -1
- package/react/components/processMonitor/components/ChildWindow.d.ts +5 -7
- package/react/components/processMonitor/components/ChildWindow.d.ts.map +1 -1
- package/react/components/processMonitor/components/ChildWindow.js +30 -33
- package/react/components/processMonitor/components/ChildWindow.js.map +1 -1
- package/react/components/processMonitor/components/ListHeader.d.ts +4 -16
- package/react/components/processMonitor/components/ListHeader.d.ts.map +1 -1
- package/react/components/processMonitor/components/ListHeader.js +30 -39
- package/react/components/processMonitor/components/ListHeader.js.map +1 -1
- package/react/components/processMonitor/components/ProcessStatistics.d.ts +3 -6
- package/react/components/processMonitor/components/ProcessStatistics.d.ts.map +1 -1
- package/react/components/processMonitor/components/ProcessStatistics.js +18 -23
- package/react/components/processMonitor/components/ProcessStatistics.js.map +1 -1
- package/react/components/sdd/Dashboard.css +21 -0
- package/react/components/sdd/css/export.css +33 -3
- package/react/components/sdd/css/nav.css +1 -1
- package/react/components/shared/DefaultDropdownButton.js +1 -1
- package/react/components/shared/DefaultDropdownButton.js.map +1 -1
- package/react/components/toolbar/DownloadButton.d.ts +8 -0
- package/react/components/toolbar/DownloadButton.d.ts.map +1 -0
- package/react/components/toolbar/DownloadButton.js +30 -0
- package/react/components/toolbar/DownloadButton.js.map +1 -0
- package/react/components/toolbar/advancedAppLauncher/stores/StoreActions.d.ts.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/stores/StoreActions.js +6 -0
- package/react/components/toolbar/advancedAppLauncher/stores/StoreActions.js.map +1 -1
- package/react/components/toolbar/appLauncher/AppLauncherMenu.js +1 -1
- package/react/components/toolbar/appLauncher/AppLauncherMenu.js.map +1 -1
- package/react/components/toolbar/dashbar/Dashbar.d.ts.map +1 -1
- package/react/components/toolbar/dashbar/Dashbar.js +72 -47
- package/react/components/toolbar/dashbar/Dashbar.js.map +1 -1
- package/react/components/toolbar/dashbar/DashbarItem.d.ts +1 -1
- package/react/components/toolbar/dashbar/DashbarItem.d.ts.map +1 -1
- package/react/components/toolbar/dashbar/DashbarItem.js +25 -4
- package/react/components/toolbar/dashbar/DashbarItem.js.map +1 -1
- package/react/components/toolbar/index.d.ts +1 -0
- package/react/components/toolbar/index.d.ts.map +1 -1
- package/react/components/toolbar/index.js +1 -0
- package/react/components/toolbar/index.js.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceActions.d.ts +3 -4
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceActions.d.ts.map +1 -1
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceActions.js +3 -10
- package/react/components/toolbar/workspaceManagementMenu/components/WorkspaceActions.js.map +1 -1
- package/react/components/userPreferences/components/content/General.d.ts.map +1 -1
- package/react/components/userPreferences/components/content/General.js +3 -0
- package/react/components/userPreferences/components/content/General.js.map +1 -1
- package/react/components/userPreferences/components/general/DownloadPreferences.d.ts +10 -0
- package/react/components/userPreferences/components/general/DownloadPreferences.d.ts.map +1 -0
- package/react/components/userPreferences/components/general/DownloadPreferences.js +111 -0
- package/react/components/userPreferences/components/general/DownloadPreferences.js.map +1 -0
- package/react/components/userPreferences/stores/UserPreferencesStore.d.ts +6 -0
- package/react/components/userPreferences/stores/UserPreferencesStore.d.ts.map +1 -1
- package/react/components/userPreferences/stores/UserPreferencesStore.js +11 -0
- package/react/components/userPreferences/stores/UserPreferencesStore.js.map +1 -1
- package/react/components/windowTitleBar/components/right/CloseButton.d.ts +2 -26
- package/react/components/windowTitleBar/components/right/CloseButton.d.ts.map +1 -1
- package/react/components/windowTitleBar/components/right/CloseButton.js +8 -25
- package/react/components/windowTitleBar/components/right/CloseButton.js.map +1 -1
- package/react/hooks/useDownloadItems.d.ts +24 -0
- package/react/hooks/useDownloadItems.d.ts.map +1 -0
- package/react/hooks/useDownloadItems.js +68 -0
- package/react/hooks/useDownloadItems.js.map +1 -0
- package/react/hooks/useNotifications.d.ts +1 -1
- package/react/reducers/rootReducer.d.ts +4 -0
- package/react/reducers/rootReducer.d.ts.map +1 -1
- package/react/reducers/smartDesktopDesignerReducer.d.ts.map +1 -1
- package/react/reducers/smartDesktopDesignerReducer.js +4 -0
- package/react/reducers/smartDesktopDesignerReducer.js.map +1 -1
- package/react/store.d.ts +8 -0
- package/react/store.d.ts.map +1 -1
- package/react/types/dashbarTypes.d.ts +3 -1
- package/react/types/dashbarTypes.d.ts.map +1 -1
- package/react/types/smartDesktopDesignerTypes.d.ts +2 -0
- package/react/types/smartDesktopDesignerTypes.d.ts.map +1 -1
- package/react/types/smartDesktopDesignerTypes.js.map +1 -1
|
@@ -0,0 +1,1641 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright 2017 - 2020 by ChartIQ, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*/
|
|
5
|
+
// This file contains the service to manage all stacked windows.
|
|
6
|
+
// The common/window/stackedWindow wrapper contains the primary interface. Also, common/StackedWindowManager contains interface to createStackedWindow used by Launcher.
|
|
7
|
+
import { RouterClient } from "../../../../clients/routerClient";
|
|
8
|
+
import { Logger } from "../../../../clients/logger";
|
|
9
|
+
import { FinsembleWindowInternal } from "../WindowAbstractions/FinsembleWindowInternal";
|
|
10
|
+
import { ConfigUtilInstance as ConfigUtil } from "../../../../common/configUtil";
|
|
11
|
+
import * as constants from "../../../../common/constants";
|
|
12
|
+
import { GroupPoolSingleton, MonitorPoolSingleton } from "../Common/Pools/PoolSingletons";
|
|
13
|
+
import { BaseWindow } from "../WindowAbstractions/BaseWindow";
|
|
14
|
+
import { each as asyncEach } from "async";
|
|
15
|
+
import _throttle from "lodash/throttle";
|
|
16
|
+
import BoxMath from "../Docking/boxMath";
|
|
17
|
+
import { getMonitorByBounds } from "../../../../common/Monitors";
|
|
18
|
+
/**
|
|
19
|
+
* Constructor for stackedWindow record -- this is what's saved in the store
|
|
20
|
+
*
|
|
21
|
+
* @param {any} stackedWindowIdentifier
|
|
22
|
+
* @memberof StackedWindowManager
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
class WindowRecord {
|
|
26
|
+
constructor(stackedWindowIdentifier) {
|
|
27
|
+
this.identifier = stackedWindowIdentifier;
|
|
28
|
+
this.childWindowIdentifiers = [];
|
|
29
|
+
this.visibleWindowIdentifier = null;
|
|
30
|
+
this.bounds = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class StackedWindowManager {
|
|
34
|
+
constructor(params) {
|
|
35
|
+
this.params = params; // keeps any params that ware passed in
|
|
36
|
+
this.childWindow = {}; // holds the wrapper for each child window
|
|
37
|
+
this.storeCache = {}; // maintains a local cache by window name of what what this service keeps in the global store; stays in sync because only this service writes to store
|
|
38
|
+
this.stackedWindowListeners = {}; // saves handles for listeners so can be removed (indexed by stacked window name)
|
|
39
|
+
this.stackedWindowWrappers = {}; // each stacked window has a wrapper so can invoke saveWindowOptions() to save workspace state
|
|
40
|
+
this.eventHandlerFunction = {}; // holds event handlers functions (needed to remove listeners)
|
|
41
|
+
this.childNameToSID = {}; // mapping from child window name to it parent stackedWindowIdentifier
|
|
42
|
+
/**
|
|
43
|
+
* The following events (and these only) should be propagated from the children to the stack.
|
|
44
|
+
*/
|
|
45
|
+
this.childEventsToHandle = [
|
|
46
|
+
"maximized",
|
|
47
|
+
"minimized",
|
|
48
|
+
"restored",
|
|
49
|
+
"shown",
|
|
50
|
+
"hidden",
|
|
51
|
+
"focused",
|
|
52
|
+
"broughtToFront",
|
|
53
|
+
"setBounds",
|
|
54
|
+
"alwaysOnTop",
|
|
55
|
+
"setOpacity",
|
|
56
|
+
"bounds-change-request",
|
|
57
|
+
"bounds-change-end",
|
|
58
|
+
"bounds-changed",
|
|
59
|
+
"system-bounds-changed",
|
|
60
|
+
];
|
|
61
|
+
this.bindAllFunctions();
|
|
62
|
+
window.StackedWindowManager = this;
|
|
63
|
+
}
|
|
64
|
+
initialize(finsembleConfig, callback = Function.prototype) {
|
|
65
|
+
// addReadyTimeout default should be larger than the router failover time (i.e. when failover goes to cross-domain) -- default fail over time adds up to 6 seconds
|
|
66
|
+
this.addReadyTimeout = ConfigUtil.getDefault(finsembleConfig, "finsembleConfig.stackedWindow.addReadyTimeout", 6500);
|
|
67
|
+
Logger.system.debug(`"StackedWindowManager addReadyTimeout ${this.addReadyTimeout}`);
|
|
68
|
+
this.setupStackedWindowServiceListeners();
|
|
69
|
+
this.listenForWorkspaceChanges();
|
|
70
|
+
callback();
|
|
71
|
+
}
|
|
72
|
+
bindAllFunctions() {
|
|
73
|
+
const self = this;
|
|
74
|
+
for (const name of Object.getOwnPropertyNames(Object.getPrototypeOf(self))) {
|
|
75
|
+
const method = self[name];
|
|
76
|
+
// skip constructor
|
|
77
|
+
if (!(method instanceof Function) || method === StackedWindowManager)
|
|
78
|
+
continue;
|
|
79
|
+
self[name] = self[name].bind(self);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// When the workspace is changed, we need to create a new queue. Without that, the system will wait until the old queue is complete (when it times out...).
|
|
83
|
+
listenForWorkspaceChanges() {
|
|
84
|
+
// RouterClient.addListener("WorkspaceService.switch", this.onWorkspaceChanging);
|
|
85
|
+
}
|
|
86
|
+
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
87
|
+
// "Hidden" External Interfaces
|
|
88
|
+
// RouterClient.publish(`Finsemble.parentChange.${windowIdentifier.windowName}`, { type: "Added", stackedWindowIdentifier });
|
|
89
|
+
// RouterClient.publish(`Finsemble.parentChange.${windowIdentifier.windowName}`, { type: "Remove", stackedWindowIdentifier });
|
|
90
|
+
//
|
|
91
|
+
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
92
|
+
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
93
|
+
// Utility Functions
|
|
94
|
+
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
95
|
+
/**
|
|
96
|
+
* Return true if the specified window in specified stack is showing
|
|
97
|
+
*
|
|
98
|
+
* @param {any} params
|
|
99
|
+
* @returns
|
|
100
|
+
* @memberof StackedWindowManager
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
isShowing(params) {
|
|
104
|
+
const { stackedWindowIdentifier, windowIdentifier } = params;
|
|
105
|
+
const thisStackRecord = this.storeCache[stackedWindowIdentifier.windowName];
|
|
106
|
+
//
|
|
107
|
+
return (windowIdentifier &&
|
|
108
|
+
thisStackRecord.visibleWindowIdentifier &&
|
|
109
|
+
windowIdentifier.windowName === thisStackRecord.visibleWindowIdentifier.windowName); // returns true if window is visible in stack
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Return true if the specified window name is in the specified stack
|
|
113
|
+
*
|
|
114
|
+
* @param {any} params
|
|
115
|
+
* @returns
|
|
116
|
+
* @memberof StackedWindowManager
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
ifWindowInStack(params) {
|
|
120
|
+
const { thisStackRecord, windowName } = params;
|
|
121
|
+
let result = false;
|
|
122
|
+
for (let i = 0; i < thisStackRecord.childWindowIdentifiers.length; i++) {
|
|
123
|
+
if (thisStackRecord.childWindowIdentifiers[i].name === windowName) {
|
|
124
|
+
result = true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return result; // true if the specified window name is in the stack
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Return true if the params indication the wrap operation was invoked directly on the window, as opposed to directly on the childWindow
|
|
131
|
+
*
|
|
132
|
+
* @param {any} params
|
|
133
|
+
* @returns
|
|
134
|
+
* @memberof StackedWindowManager
|
|
135
|
+
* @private
|
|
136
|
+
*/
|
|
137
|
+
operatingDirectlyOnStackedWindow(params) {
|
|
138
|
+
let result;
|
|
139
|
+
let { stackedWindowIdentifier, windowIdentifier } = params;
|
|
140
|
+
stackedWindowIdentifier = stackedWindowIdentifier || {};
|
|
141
|
+
if (!windowIdentifier || stackedWindowIdentifier.windowName === windowIdentifier.windowName) {
|
|
142
|
+
result = true; // must be a stacked window
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
result = false; // must be operating on a child of a stacked window
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Return current monitor for the given window bounds
|
|
151
|
+
* @param windowBounds
|
|
152
|
+
* @returns
|
|
153
|
+
* @private
|
|
154
|
+
*/
|
|
155
|
+
getMonitor(windowBounds) {
|
|
156
|
+
var _a;
|
|
157
|
+
const overlaps = [];
|
|
158
|
+
for (const monitor of MonitorPoolSingleton.iterator()) {
|
|
159
|
+
const overlap = BoxMath.getOverlap(windowBounds, ((_a = monitor.rawMonitor) === null || _a === void 0 ? void 0 : _a.monitorRect) || monitor.availableRect);
|
|
160
|
+
overlaps.push({
|
|
161
|
+
monitor,
|
|
162
|
+
overlap,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
// Gets the monitor with the greatest overlap. The reduce function pulls the proper object with the greats overlap value. We return the monitor property of that object.
|
|
166
|
+
return overlaps.reduce((prev, current) => (prev.overlap > current.overlap ? prev : current)).monitor;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Update child windows options on restore event
|
|
170
|
+
* @param stackWindow the parent stacked window
|
|
171
|
+
* @param restoredBounds the bounds after restoring
|
|
172
|
+
* @private
|
|
173
|
+
*/
|
|
174
|
+
restoreChildren(stackWindow, restoredBounds) {
|
|
175
|
+
stackWindow.childWindowIdentifiers.forEach((childIdentifier) => {
|
|
176
|
+
const childWindow = this.childWindow[childIdentifier.windowName];
|
|
177
|
+
if (childWindow) {
|
|
178
|
+
childWindow.ignoreSystemRestore = false;
|
|
179
|
+
if (childWindow.windowState !== constants.WINDOWSTATE.NORMAL) {
|
|
180
|
+
childWindow._restore({ invokedByParent: true });
|
|
181
|
+
}
|
|
182
|
+
childWindow._setBounds({ bounds: restoredBounds, invokedByParent: true });
|
|
183
|
+
if (childWindow.name !== stackWindow.visibleWindowIdentifier.windowName) {
|
|
184
|
+
childWindow._hide({ invokedByParent: true });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Update child windows options on maximize event
|
|
191
|
+
* @param stackWindow the parent stacked window
|
|
192
|
+
* @private
|
|
193
|
+
*/
|
|
194
|
+
maximizeChildren(stackWindow) {
|
|
195
|
+
const monitor = getMonitorByBounds(stackWindow.bounds);
|
|
196
|
+
stackWindow.childWindowIdentifiers.forEach((childIdentifier) => {
|
|
197
|
+
const childWindow = this.childWindow[childIdentifier.windowName];
|
|
198
|
+
if (childWindow) {
|
|
199
|
+
/**
|
|
200
|
+
* Work around for a bug in which a switching tabs is triggering a system restore that would restore the window to its original size.
|
|
201
|
+
* The ignoreSystemRestore flag is added before childWrapper._show to indicate that we are in a maximized state and *only* switching
|
|
202
|
+
* tabs and therefore we do not want to restore the window.
|
|
203
|
+
*/
|
|
204
|
+
childWindow.ignoreSystemRestore = true;
|
|
205
|
+
if (childWindow.windowState !== constants.WINDOWSTATE.MAXIMIZED) {
|
|
206
|
+
childWindow._maximize({ invokedByParent: true });
|
|
207
|
+
}
|
|
208
|
+
childWindow._setBounds({ bounds: monitor.availableRect, invokedByParent: true });
|
|
209
|
+
if (childWindow.name !== stackWindow.visibleWindowIdentifier.windowName) {
|
|
210
|
+
childWindow._hide({ invokedByParent: true });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
216
|
+
// Setup router listeners to handing incoming service requests and events from child windows
|
|
217
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
218
|
+
eventChannelName(stackedWindowName, channelTopic) {
|
|
219
|
+
return `StackedWindow-${stackedWindowName}-${channelTopic}`;
|
|
220
|
+
}
|
|
221
|
+
setupInterfaceListener(methodName, methodFunction) {
|
|
222
|
+
RouterClient.addResponder(`StackedWindow.${methodName}`, (err, queryMessage) => {
|
|
223
|
+
if (err) {
|
|
224
|
+
Logger.system.error(`StackedWindow.${methodName} addResponder failed: ${err}`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
if (queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.data.windowIdentifier) {
|
|
228
|
+
// Ensure that the WI has matching windowName and name (in case a client sends the wrong one).
|
|
229
|
+
if (queryMessage.data.windowIdentifier.windowName) {
|
|
230
|
+
queryMessage.data.windowIdentifier.name = queryMessage.data.windowIdentifier.windowName;
|
|
231
|
+
}
|
|
232
|
+
else if (queryMessage.data.windowIdentifier.name) {
|
|
233
|
+
queryMessage.data.windowIdentifier.windowName = queryMessage.data.windowIdentifier.name;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const callback = (error, response) => {
|
|
237
|
+
queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.sendQueryResponse(error, response);
|
|
238
|
+
};
|
|
239
|
+
methodFunction(queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.data, callback);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
setupStackedWindowServiceListeners() {
|
|
244
|
+
// window wrapper entry points
|
|
245
|
+
this.setupInterfaceListener("minimize", this.minimize);
|
|
246
|
+
this.setupInterfaceListener("maximize", this.maximize);
|
|
247
|
+
this.setupInterfaceListener("restore", this.restore);
|
|
248
|
+
this.setupInterfaceListener("focus", this.focus);
|
|
249
|
+
this.setupInterfaceListener("bringToFront", this.bringToFront);
|
|
250
|
+
this.setupInterfaceListener("saveWindowOptions", this.saveWindowStateToStore);
|
|
251
|
+
this.setupInterfaceListener("setBounds", this.setBounds);
|
|
252
|
+
this.setupInterfaceListener("getBounds", this.getBounds);
|
|
253
|
+
this.setupInterfaceListener("getBoundsFromSystem", this.getBoundsFromSystem);
|
|
254
|
+
this.setupInterfaceListener("startMove", this.startMove);
|
|
255
|
+
this.setupInterfaceListener("stopMove", this.stopMove);
|
|
256
|
+
// this.setupInterfaceListener("updateOptions", this.updateOptions);
|
|
257
|
+
this.setupInterfaceListener("hide", this.hide);
|
|
258
|
+
this.setupInterfaceListener("show", this.show);
|
|
259
|
+
this.setupInterfaceListener("close", this.close);
|
|
260
|
+
this.setupInterfaceListener("reorder", this.reorder);
|
|
261
|
+
this.setupInterfaceListener("alwaysOnTop", this.setAlwaysOnTop);
|
|
262
|
+
// this.setupInterfaceListener("setOpacity", this.setOpacity);
|
|
263
|
+
RouterClient.addResponder("StackedWindow.setOpacity", (err, queryMessage) => {
|
|
264
|
+
if (err) {
|
|
265
|
+
Logger.system.error(`StackedWindow.setOpacity addResponder failed: ${err}`);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
this.setOpacity(queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.data, (setOpacityError, response) => {
|
|
269
|
+
queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.sendQueryResponse(setOpacityError, response);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
RouterClient.addResponder("StackedWindow.updateOptions", (err, queryMessage) => {
|
|
274
|
+
if (err) {
|
|
275
|
+
Logger.system.error(`StackedWindow.updateOptions addResponder failed: ${err}`);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this.updateOptions(queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.data, (updateOptionsError, response) => {
|
|
279
|
+
queryMessage === null || queryMessage === void 0 ? void 0 : queryMessage.sendQueryResponse(updateOptionsError, response);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
async visibleChildEventHandler(stackedWindowName, stackWrap, event) {
|
|
285
|
+
const stackedWindowIdentifier = {
|
|
286
|
+
windowName: stackedWindowName,
|
|
287
|
+
name: stackedWindowName,
|
|
288
|
+
windowType: "StackedWindow",
|
|
289
|
+
};
|
|
290
|
+
const thisStackRecord = this.storeCache[stackedWindowName];
|
|
291
|
+
// Sometimes removal of visible Child events never happens. Not sure why. Under normal circumstances, this is not an issue because you generally don't get here
|
|
292
|
+
// However in the case of evergreen components, this prevents the evergreen component from moving when launched in another workspace.
|
|
293
|
+
// So cleanup listeners if we somehow managed to get here and the stack doesn't exist.
|
|
294
|
+
if (!this.storeCache[stackedWindowName]) {
|
|
295
|
+
const { wrap: childWrap } = await BaseWindow.getInstance({ name: event.source });
|
|
296
|
+
this.removeChildEventListener(stackedWindowName, event.source, childWrap);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
switch (event.event) {
|
|
300
|
+
case "bounds-change-end":
|
|
301
|
+
this.saveWindowOptions({ closing: false }, stackedWindowIdentifier);
|
|
302
|
+
stackWrap.eventManager.trigger(event.event, event.data);
|
|
303
|
+
Logger.system.verbose("StackedWindowManager transmitting event", event.event, this.eventChannelName(stackedWindowName, event.event), event);
|
|
304
|
+
break;
|
|
305
|
+
case "restored":
|
|
306
|
+
stackWrap.windowState = constants.WINDOWSTATE.NORMAL;
|
|
307
|
+
this.restoreChildren(thisStackRecord, event.data.bounds);
|
|
308
|
+
break;
|
|
309
|
+
case "maximized":
|
|
310
|
+
stackWrap.windowState = constants.WINDOWSTATE.MAXIMIZED;
|
|
311
|
+
this.maximizeChildren(thisStackRecord);
|
|
312
|
+
break;
|
|
313
|
+
case "alwaysOnTop": {
|
|
314
|
+
let alwaysOnTopValue = event.data.alwaysOnTop;
|
|
315
|
+
if (alwaysOnTopValue === undefined) {
|
|
316
|
+
const eventWindowName = event.data.windowName;
|
|
317
|
+
const activeChildWindow = this.childWindow[eventWindowName];
|
|
318
|
+
alwaysOnTopValue = !activeChildWindow.getParent().alwaysOnTop; // gets the parent alwaysOnTop value and toggles it
|
|
319
|
+
}
|
|
320
|
+
await this.setAlwaysOnTop({
|
|
321
|
+
stackedWindowIdentifier,
|
|
322
|
+
alwaysOnTop: alwaysOnTopValue,
|
|
323
|
+
});
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
default:
|
|
327
|
+
stackWrap.eventManager.trigger(event.event, event.data);
|
|
328
|
+
Logger.system.verbose("StackedWindowManager transmitting event", event.eventName, this.eventChannelName(stackedWindowName, event.event), event);
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
addChildEventListener(stackedWindowName, childName, childWrapper) {
|
|
333
|
+
Logger.system.debug("StackedWindowManagerService.addChildEventListener", stackedWindowName, childName);
|
|
334
|
+
FinsembleWindowInternal.getInstance({ name: stackedWindowName }, (err, stackWrap) => {
|
|
335
|
+
for (let i = 0; i < this.childEventsToHandle.length; i++) {
|
|
336
|
+
const eventName = this.childEventsToHandle[i];
|
|
337
|
+
let eventHandler = (eventObject) => {
|
|
338
|
+
this.visibleChildEventHandler(stackedWindowName, stackWrap, eventObject);
|
|
339
|
+
};
|
|
340
|
+
if (eventName === "bounds-change-request") {
|
|
341
|
+
eventHandler = _throttle(eventHandler, 10);
|
|
342
|
+
}
|
|
343
|
+
if (!this.eventHandlerFunction[stackedWindowName])
|
|
344
|
+
this.eventHandlerFunction[stackedWindowName] = {};
|
|
345
|
+
if (this.eventHandlerFunction[stackedWindowName][eventName]) {
|
|
346
|
+
Logger.system.warn("Avoiding Registering the same Listener Twice.");
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
Logger.system.debug("StackedWindowManager addChildEventListener", eventName, childName);
|
|
350
|
+
this.eventHandlerFunction[stackedWindowName][eventName] = eventHandler;
|
|
351
|
+
childWrapper.addEventListener(eventName, eventHandler);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
removeChildEventListener(stackedWindowName, childName, childWrapper) {
|
|
357
|
+
Logger.system.debug("StackedWindowManager.removeChildEventListener", stackedWindowName, childName);
|
|
358
|
+
// We may try to remove listeners before adding them. If so, don't error out.
|
|
359
|
+
if (!this.eventHandlerFunction[stackedWindowName])
|
|
360
|
+
this.eventHandlerFunction[stackedWindowName] = {};
|
|
361
|
+
for (let i = 0; i < this.childEventsToHandle.length; i++) {
|
|
362
|
+
const eventName = this.childEventsToHandle[i];
|
|
363
|
+
const handler = this.eventHandlerFunction[stackedWindowName][eventName];
|
|
364
|
+
if (handler) {
|
|
365
|
+
childWrapper.removeEventListener(eventName, handler);
|
|
366
|
+
delete this.eventHandlerFunction[stackedWindowName][eventName];
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
Logger.system.debug("StackedWindowManager.removeChildEventListener before the listener was added.");
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
374
|
+
// The next section of functions are oriented to managing Stacked Windows throughout the system.
|
|
375
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
376
|
+
// returns true if all the groupWindows are in the array of child windows
|
|
377
|
+
groupWindowsContainedInStacked(groupWindows, childWindows) {
|
|
378
|
+
let matchCount = 0;
|
|
379
|
+
let groupWindowCount = 0;
|
|
380
|
+
let groupWindow;
|
|
381
|
+
for (groupWindow in groupWindows) {
|
|
382
|
+
groupWindowCount++; // count the number of group windows
|
|
383
|
+
if (groupWindows.hasOwnProperty(groupWindow)) {
|
|
384
|
+
for (const childWindow of childWindows) {
|
|
385
|
+
if (groupWindow === childWindow.name) {
|
|
386
|
+
matchCount++; // count the matches found in child windows
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return groupWindowCount === matchCount; // return true if all group windows found in child windows
|
|
392
|
+
}
|
|
393
|
+
// when a new child window is added to the stack, this function determines if the stacked window should join any of the children groups
|
|
394
|
+
joinGroups(groups, stackedWindowIdentifier) {
|
|
395
|
+
const thisStackRecord = this.storeCache[stackedWindowIdentifier.windowName];
|
|
396
|
+
if (!thisStackRecord) {
|
|
397
|
+
Logger.system.error("stackedWindowManager.joinGroups unidentified stacked window", stackedWindowIdentifier);
|
|
398
|
+
}
|
|
399
|
+
else if (groups) {
|
|
400
|
+
for (const group of groups) {
|
|
401
|
+
const oneGroup = GroupPoolSingleton.get(group);
|
|
402
|
+
if (!this.groupWindowsContainedInStacked(oneGroup.windows, thisStackRecord.childWindowIdentifiers)) {
|
|
403
|
+
// if the group exists outside the stacked window, then join the group
|
|
404
|
+
RouterClient.transmit("DockingService.joinGroup", {
|
|
405
|
+
groupName: group,
|
|
406
|
+
name: stackedWindowIdentifier.windowName,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
getGroups(windowIdentifier) {
|
|
413
|
+
const promiseResolver = async (resolve) => {
|
|
414
|
+
RouterClient.query("DockingService.getGroupsForWindow", { name: windowIdentifier.name }, (err, response) => {
|
|
415
|
+
resolve(response.data);
|
|
416
|
+
});
|
|
417
|
+
};
|
|
418
|
+
return new Promise(promiseResolver);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Creates a new StackedWindow, returning its stackWindowIdentifier in the callback. Optionally initializes stack with a set of child windows.
|
|
422
|
+
*
|
|
423
|
+
* Invoked by Launcher Service when spawning a stacked window (e.g. LauncherClient.spawn()).
|
|
424
|
+
*
|
|
425
|
+
* @param {object} params Parameters
|
|
426
|
+
* @param {array=} params.windowIdentifiers array of windowIdentifiers to add to stack on creation.
|
|
427
|
+
* @param {boolean=} params.new if true then stacked window being defined for first time with no persistent state
|
|
428
|
+
* @param {function=} callback function(err, stackedWindowIdentifier)
|
|
429
|
+
* @memberof StackedWindowManager
|
|
430
|
+
* @private
|
|
431
|
+
*/
|
|
432
|
+
async createStackedWindow(params, callback = null) {
|
|
433
|
+
var _a, _b;
|
|
434
|
+
Logger.system.debug("StackedWindowManager.createStackedWindow", params);
|
|
435
|
+
if (params.customData)
|
|
436
|
+
params.customData.manifest = {};
|
|
437
|
+
const stackedWindowIdentifier = {
|
|
438
|
+
windowType: "StackedWindow",
|
|
439
|
+
windowName: params.windowName || params.name,
|
|
440
|
+
};
|
|
441
|
+
let thisStackRecord;
|
|
442
|
+
let subscribeID = null;
|
|
443
|
+
// TABBING TBD: need to finish before callback -- async
|
|
444
|
+
// if (true || params.new) { // being created for the first time (not from workspace with persistent state)
|
|
445
|
+
thisStackRecord = new WindowRecord(stackedWindowIdentifier); // blank initial record
|
|
446
|
+
Object.assign(thisStackRecord, params); // merge windowDescriptor into stackRecord
|
|
447
|
+
thisStackRecord.registeredWithDockingManager = false;
|
|
448
|
+
const windowIdentifiers = thisStackRecord.childWindowIdentifiers && thisStackRecord.childWindowIdentifiers.length
|
|
449
|
+
? thisStackRecord.childWindowIdentifiers
|
|
450
|
+
: (_b = (_a = thisStackRecord.customData) === null || _a === void 0 ? void 0 : _a.spawnData) === null || _b === void 0 ? void 0 : _b.windowIdentifiers;
|
|
451
|
+
thisStackRecord.childWindowIdentifiers = [];
|
|
452
|
+
// below commented out because don't want to save until complete state
|
|
453
|
+
// this.saveStore(stackedWindowIdentifier); // go ahead and save initial information before waiting on children
|
|
454
|
+
const wrapReadyCallback = async (err, response) => {
|
|
455
|
+
if (response.data && response.data.state === "open") {
|
|
456
|
+
RouterClient.unsubscribe(subscribeID); // no longer need subscription
|
|
457
|
+
for (let i = 0; i < windowIdentifiers.length; i++) {
|
|
458
|
+
const p = Object.assign({}, params);
|
|
459
|
+
p.windowIdentifier = windowIdentifiers[i];
|
|
460
|
+
if (i === 0) {
|
|
461
|
+
p.inheritGroups = true;
|
|
462
|
+
}
|
|
463
|
+
await this.addWindow(p);
|
|
464
|
+
}
|
|
465
|
+
// if not a newStack (i.e. spawned by workspace) the register here after children are added; otherwise for new stacks must dynamically register in addWindow. TBD: need better model here
|
|
466
|
+
if (!params.newStack) {
|
|
467
|
+
await this.registerWithDockingManager({
|
|
468
|
+
windowIdentifier: stackedWindowIdentifier,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
Logger.system.debug("StackedWindowManager.createStackedWindow all available windows added");
|
|
472
|
+
const isVisible = thisStackRecord.visibleWindowIdentifier &&
|
|
473
|
+
thisStackRecord.childWindowIdentifiers.length &&
|
|
474
|
+
!this.ifWindowInStack({
|
|
475
|
+
thisStackRecord,
|
|
476
|
+
windowName: thisStackRecord.visibleWindowIdentifier.windowName,
|
|
477
|
+
});
|
|
478
|
+
// if there is a visible window but the corresponding child window never became ready (for any reason) then set a new visible window
|
|
479
|
+
if (isVisible) {
|
|
480
|
+
Logger.system.error("StackedWindowManager.createStackedWindow resetting visible window to first child since previous visible window couldn't be added");
|
|
481
|
+
this.setVisibleWindow({
|
|
482
|
+
stackedWindowIdentifier,
|
|
483
|
+
windowIdentifier: thisStackRecord.childWindowIdentifiers[0],
|
|
484
|
+
}); // make the first window visible by default
|
|
485
|
+
}
|
|
486
|
+
if (!thisStackRecord.childWindowIdentifiers.length) {
|
|
487
|
+
// TBD: this should essentially mean the stacked-window creation failed, but this has side-effect so just put out error for now. Revisit on cleanup. But tested and roughly handled okay.
|
|
488
|
+
Logger.system.error("StackedWindowManager.createStackedWindow: no children became ready");
|
|
489
|
+
}
|
|
490
|
+
// send notification to LauncherClient that the window has been created (otherwise LauncherClient hangs)
|
|
491
|
+
RouterClient.publish(`Finsemble.${stackedWindowIdentifier.windowName}.componentReady`, {
|
|
492
|
+
name: stackedWindowIdentifier.windowName,
|
|
493
|
+
});
|
|
494
|
+
// note the LauncherService will add to the workspace after spawn completes (spawn is the main client of this function)
|
|
495
|
+
await this.saveWindowOptions({ closing: false }, stackedWindowIdentifier); // save again now children added
|
|
496
|
+
this.setVisibleWindow({
|
|
497
|
+
stackedWindowIdentifier,
|
|
498
|
+
windowIdentifier: thisStackRecord.visibleWindowIdentifier,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
Logger.system.debug("StackedWindowManager.createStackedWindow NewRecord", thisStackRecord);
|
|
503
|
+
this.storeCache[stackedWindowIdentifier.windowName] = thisStackRecord; // cache the stacked window data
|
|
504
|
+
if (windowIdentifiers) {
|
|
505
|
+
// if a list of initial windows provides, then now add them as children
|
|
506
|
+
params.noSave = true; // input to addWindow -- don't save in add because will do it once here after all added
|
|
507
|
+
params.stackedWindowIdentifier = stackedWindowIdentifier;
|
|
508
|
+
// wait for the wrap to be available before adding windows.
|
|
509
|
+
const wrapReadyChannel = `Finsemble.${stackedWindowIdentifier.windowName}.wrapReady`;
|
|
510
|
+
subscribeID = RouterClient.subscribe(wrapReadyChannel, wrapReadyCallback);
|
|
511
|
+
callback === null || callback === void 0 ? void 0 : callback(null, stackedWindowIdentifier);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Private utility function to sleep/wait for a specified time before accepting the returned promise.
|
|
516
|
+
* @private
|
|
517
|
+
*/
|
|
518
|
+
sleep(milliseconds) {
|
|
519
|
+
return new Promise((resolve) => setTimeout(() => {
|
|
520
|
+
resolve("Timeout");
|
|
521
|
+
}, milliseconds));
|
|
522
|
+
}
|
|
523
|
+
waitForWrapReady(windowName) {
|
|
524
|
+
const channel = `Finsemble.${windowName}.wrapReady`;
|
|
525
|
+
return new Promise((resolve) => {
|
|
526
|
+
const subscribeID = RouterClient.subscribe(channel, async (err, response) => {
|
|
527
|
+
var _a, _b;
|
|
528
|
+
RouterClient.unsubscribe(subscribeID);
|
|
529
|
+
const available = ((_a = response.data) === null || _a === void 0 ? void 0 : _a.name) === windowName && ((_b = response.data) === null || _b === void 0 ? void 0 : _b.state) === "open";
|
|
530
|
+
if (!available) {
|
|
531
|
+
Logger.system.debug("StackedWindowManager.addWindow waiting", windowName);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
resolve(null);
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Adds window as a child to a stacked window. Adds to the top of the stack, or if specified to a specific location in the stack;
|
|
540
|
+
*
|
|
541
|
+
* @param {object=} params Parameters
|
|
542
|
+
* @param {object} params.stackedWindowIdentifier stacked window to operate on stacked window to operate on
|
|
543
|
+
* @param {object} params.windowIdentifier window to add
|
|
544
|
+
* @param {number=} params.position the location in the stack to push the window. Location 0 is the bottom of the stack. Defaults to the top of stack.
|
|
545
|
+
* @param {boolean=} params.noSave if true then don't save the store after updating it (will be saved by caller)
|
|
546
|
+
* @param {boolean=} params.ignorePreviousState if true then ignore the previous state of the window being added (with in another stack and registered with docking handled elsewhere)
|
|
547
|
+
* @param {boolean=} params.noVisibility if true don't automatically set visibility when first window added to the stack (needed for ordered startup)
|
|
548
|
+
* @param {function=} callback function(err)
|
|
549
|
+
* @memberof StackedWindowManager
|
|
550
|
+
* @private
|
|
551
|
+
*/
|
|
552
|
+
async addWindow(params) {
|
|
553
|
+
Logger.system.debug("StackedWindowManager.addWindow", params);
|
|
554
|
+
const { windowName } = params.windowIdentifier;
|
|
555
|
+
// this handles when a window being added never reaches the ready state -- set timer to catch these cases and reject on timeout
|
|
556
|
+
const err = await Promise.race([this.sleep(this.addReadyTimeout), this.waitForWrapReady(windowName)]);
|
|
557
|
+
if (err) {
|
|
558
|
+
const error = `StackedWindowManager.addWindow() child ${params.windowIdentifier.windowName} never became ready`;
|
|
559
|
+
Logger.system.error(error);
|
|
560
|
+
return { err: error };
|
|
561
|
+
}
|
|
562
|
+
Logger.system.debug("StackedWindowManager.addWindow() continuing", params.windowIdentifier.windowName);
|
|
563
|
+
const { stackedWindowIdentifier, windowIdentifier, noSave } = params;
|
|
564
|
+
const thisStackRecord = this.storeCache[stackedWindowIdentifier.windowName];
|
|
565
|
+
if (!thisStackRecord) {
|
|
566
|
+
const error = "StackedWindowManager.addWindow() unknown stackedWindowIdentifier";
|
|
567
|
+
Logger.system.error(error);
|
|
568
|
+
return { err: error };
|
|
569
|
+
}
|
|
570
|
+
// position to add the window
|
|
571
|
+
const { position = thisStackRecord.childWindowIdentifiers.length } = params;
|
|
572
|
+
thisStackRecord.childWindowIdentifiers.splice(position, 0, windowIdentifier); // add to the child array
|
|
573
|
+
this.childNameToSID[windowIdentifier.windowName] = stackedWindowIdentifier; // add mapping to parent stackedWindowIdentifier
|
|
574
|
+
const { data: wrappedWindow } = await FinsembleWindowInternal.getInstanceStandardized(windowIdentifier);
|
|
575
|
+
if (!wrappedWindow) {
|
|
576
|
+
const error = `StackedWindowManager.addWindow() Cannot get wrap for ${windowName}`;
|
|
577
|
+
Logger.system.error(error);
|
|
578
|
+
return { err: error };
|
|
579
|
+
}
|
|
580
|
+
this.childWindow[windowIdentifier.windowName] = wrappedWindow; // save the wrapper for quick use
|
|
581
|
+
// save alwaysOnTop state so that when the window leaves the stack, its original alwaysOnTop state is restored
|
|
582
|
+
if (typeof windowIdentifier.alwaysOnTop !== "boolean")
|
|
583
|
+
windowIdentifier.alwaysOnTop = wrappedWindow._isAlwaysOnTop();
|
|
584
|
+
// if stacked window doesn't have a visible window, then make this window being added the visible window
|
|
585
|
+
if (!thisStackRecord.visibleWindowIdentifier) {
|
|
586
|
+
const { err: err2, data: bounds } = await wrappedWindow._getBounds({}, () => { });
|
|
587
|
+
if (err2 || !bounds) {
|
|
588
|
+
const error = `StackedWindowManager.addWindow() no bounds received ${err2}`;
|
|
589
|
+
Logger.system.error(error);
|
|
590
|
+
return { err: error };
|
|
591
|
+
}
|
|
592
|
+
// get the window bounds and save as the stackedWindow bounds
|
|
593
|
+
Logger.system.debug("StackedWindowManager.addWindow() got bounds", windowIdentifier, bounds);
|
|
594
|
+
this.mergeBounds(thisStackRecord, bounds);
|
|
595
|
+
thisStackRecord.bounds = bounds;
|
|
596
|
+
Object.assign(thisStackRecord, bounds);
|
|
597
|
+
this.setVisibleWindow({
|
|
598
|
+
stackedWindowIdentifier,
|
|
599
|
+
windowIdentifier,
|
|
600
|
+
noSave: params.noSave,
|
|
601
|
+
isAddingChildren: true,
|
|
602
|
+
});
|
|
603
|
+
// if stacked window has a predefined visibleWindow and it matches the window being added, then set this window to the visible window
|
|
604
|
+
}
|
|
605
|
+
else if (thisStackRecord.visibleWindowIdentifier &&
|
|
606
|
+
thisStackRecord.visibleWindowIdentifier.windowName === windowIdentifier.windowName) {
|
|
607
|
+
this.setVisibleWindow({
|
|
608
|
+
stackedWindowIdentifier,
|
|
609
|
+
windowIdentifier,
|
|
610
|
+
noSave: params.noSave,
|
|
611
|
+
isAddingChildren: true,
|
|
612
|
+
});
|
|
613
|
+
// if stacked window has a predefined visibleWindow and it does not match the window being added, then hide this window
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
Logger.system.debug("StackedWindowManager.addWindow hiding window", windowIdentifier);
|
|
617
|
+
// hide the window being added and set it bounds
|
|
618
|
+
wrappedWindow._hide({ invokedByParent: true }, () => {
|
|
619
|
+
Logger.system.debug("StackedWindowManager.addWindow setting bounds", windowIdentifier, thisStackRecord.bounds);
|
|
620
|
+
wrappedWindow._setBounds({
|
|
621
|
+
bounds: thisStackRecord.bounds,
|
|
622
|
+
invokedByParent: true,
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
// If the stack is maximized and we're adding a window to it,
|
|
627
|
+
// call to maximize the window
|
|
628
|
+
const { wrap: stackedWrapper } = await BaseWindow.getInstance(stackedWindowIdentifier);
|
|
629
|
+
const childWindow = this.childWindow[windowIdentifier.windowName];
|
|
630
|
+
if (stackedWrapper.windowState === constants.WINDOWSTATE.MAXIMIZED) {
|
|
631
|
+
childWindow._maximize();
|
|
632
|
+
}
|
|
633
|
+
else if (stackedWrapper.windowState === constants.WINDOWSTATE.NORMAL) {
|
|
634
|
+
childWindow._restore();
|
|
635
|
+
}
|
|
636
|
+
if (!params.noRemove) {
|
|
637
|
+
// if higher level (e.g. presentation components) isn't handling the previous state of the window
|
|
638
|
+
// handling the previous state of the window being added
|
|
639
|
+
const { parentWindow } = wrappedWindow;
|
|
640
|
+
if (parentWindow && parentWindow.name != thisStackRecord.name) {
|
|
641
|
+
// if the window being added was already in a stackedWindow, remove it from that stacked window (the window is already unregistered with docking)
|
|
642
|
+
Logger.system.debug("StackedWindowManager.addWindow removing from previous parentWindow", parentWindow.identifier);
|
|
643
|
+
// if adding a window to this stack that needs to be removed from another stack,
|
|
644
|
+
// then when removing don't automatically make the window visible; instead use normally visibility settings in new stacked window
|
|
645
|
+
await this.removeWindow({
|
|
646
|
+
stackedWindowIdentifier: parentWindow.identifier,
|
|
647
|
+
windowIdentifier,
|
|
648
|
+
noVisible: true,
|
|
649
|
+
noDocking: true,
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
// else window is standalone and registered with docking, so deregister with docking (since only stacked window is registered)
|
|
654
|
+
Logger.system.debug("StackedWindowManager.addWindow unregistering from docking (case 1)", windowIdentifier);
|
|
655
|
+
if (params.inheritGroups && params.newStack) {
|
|
656
|
+
await this.registerWithDockingManager({
|
|
657
|
+
windowIdentifier: stackedWindowIdentifier,
|
|
658
|
+
});
|
|
659
|
+
const groups = await this.getGroups(windowIdentifier);
|
|
660
|
+
this.joinGroups(groups, stackedWindowIdentifier);
|
|
661
|
+
}
|
|
662
|
+
this.deregisterWithDockingManager({ windowIdentifier }); // docking manager manage the parentWindow stacked window (not the individual children)
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
if (!noSave) {
|
|
666
|
+
await this.saveWindowOptions({ closing: false }, stackedWindowIdentifier); // update the cache and the global store
|
|
667
|
+
}
|
|
668
|
+
// Notify interested listeners (e.g. BaseWindow wrappers for added window) that window was added to the stack
|
|
669
|
+
Logger.system.debug("StackedWindowManager publish parent notification", windowIdentifier.windowName);
|
|
670
|
+
RouterClient.publish(`Finsemble.parentChange.${windowIdentifier.windowName}`, {
|
|
671
|
+
type: "Added",
|
|
672
|
+
stackedWindowIdentifier,
|
|
673
|
+
});
|
|
674
|
+
// Publish Exists event right after the Added event because windows use this event type to track parent state.
|
|
675
|
+
RouterClient.publish(`Finsemble.parentChange.${windowIdentifier.windowName}`, {
|
|
676
|
+
type: "Exists",
|
|
677
|
+
stackedWindowIdentifier,
|
|
678
|
+
});
|
|
679
|
+
await this.makeStackAlwaysOnTopIfNeeded({
|
|
680
|
+
stackedWindowIdentifier,
|
|
681
|
+
});
|
|
682
|
+
return {};
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* This will make a stack always on top if any child is always on top.
|
|
686
|
+
*/
|
|
687
|
+
async makeStackAlwaysOnTopIfNeeded(params) {
|
|
688
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
689
|
+
const alwaysOnTop = thisStackRecord.childWindowIdentifiers.some(({ windowName }) => this.childWindow[windowName]._isAlwaysOnTop());
|
|
690
|
+
if (alwaysOnTop) {
|
|
691
|
+
await this.setAlwaysOnTop({
|
|
692
|
+
stackedWindowIdentifier: params.stackedWindowIdentifier,
|
|
693
|
+
alwaysOnTop: alwaysOnTop,
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
triggerEvent(params, cb) {
|
|
698
|
+
FinsembleWindowInternal.getInstance({ stackedWindowManager: this, name: params.windowIdentifier.windowName }, (_err, wrap) => {
|
|
699
|
+
wrap.eventManager.trigger(params.event);
|
|
700
|
+
cb();
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Closes and deletes a stacked window. If specified (see params) then children will be closed; otherwise children will be signals they are removed from the stacked window.
|
|
705
|
+
*
|
|
706
|
+
* @param {object} params Parameters
|
|
707
|
+
* @param {object} params.stackedWindowIdentifier stacked window to operate on
|
|
708
|
+
* @param {object=} params.closeChildren if true then also close all children
|
|
709
|
+
* @param {object=} params.removeFromWorkspace if then remove stacked window and child windows from the workspace
|
|
710
|
+
* @param {boolean=} params.waitChildClose if true then wait for child wrapper to close before returned (needed for cleanly switching workspaces)
|
|
711
|
+
* @param {boolean=} params.noDocking if true then do not register removed window with docking (the workspace is unaffected)
|
|
712
|
+
* @param {any} callback
|
|
713
|
+
* @memberof StackedWindowManager
|
|
714
|
+
*/
|
|
715
|
+
closeStackedWindow(params, callback = Function.prototype) {
|
|
716
|
+
Logger.system.debug("StackedWindowManager.closeStackedWindow", params.stackedWindowIdentifier.windowName, params);
|
|
717
|
+
const promiseResolver = async (resolve) => {
|
|
718
|
+
let { stackedWindowIdentifier, removeFromWorkspace, closeChildren } = params;
|
|
719
|
+
if (!closeChildren && closeChildren !== false) {
|
|
720
|
+
closeChildren = removeFromWorkspace;
|
|
721
|
+
}
|
|
722
|
+
const thisStackRecord = this.storeCache[stackedWindowIdentifier.windowName];
|
|
723
|
+
Logger.system.debug("StackedWindowManager.closeStackedWindow saveStore done", params.stackedWindowIdentifier.windowName);
|
|
724
|
+
if (!thisStackRecord) {
|
|
725
|
+
const err = "StackedWindowManager.closeStackedWindow: no stacked record";
|
|
726
|
+
Logger.system.error(err, params);
|
|
727
|
+
resolve({ err });
|
|
728
|
+
callback(err);
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
// clear the pubsub state for the stacked window -- must set to empty (to match LaucherClient check)
|
|
732
|
+
RouterClient.publish(`Finsemble.${stackedWindowIdentifier.windowName}.componentReady`, {});
|
|
733
|
+
if (removeFromWorkspace) {
|
|
734
|
+
if (closeChildren) {
|
|
735
|
+
while (thisStackRecord.childWindowIdentifiers.length > 0) {
|
|
736
|
+
// the currently visible window is closed one at a time to support orderly close, which might require UI interaction
|
|
737
|
+
await this.deleteWindow({
|
|
738
|
+
noCloseStack: true,
|
|
739
|
+
waitChildClose: params.waitChildClose,
|
|
740
|
+
stackedWindowIdentifier,
|
|
741
|
+
windowIdentifier: thisStackRecord.visibleWindowIdentifier,
|
|
742
|
+
removeFromWorkspace,
|
|
743
|
+
fromSystem: params.fromSystem,
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
while (thisStackRecord.childWindowIdentifiers.length > 0) {
|
|
749
|
+
await this.removeWindow({
|
|
750
|
+
noCloseStack: true,
|
|
751
|
+
waitChildClose: params.waitChildClose,
|
|
752
|
+
stackedWindowIdentifier,
|
|
753
|
+
windowIdentifier: thisStackRecord.visibleWindowIdentifier,
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
this.deregisterWithDockingManager({
|
|
758
|
+
windowIdentifier: stackedWindowIdentifier,
|
|
759
|
+
removeFromWorkspace,
|
|
760
|
+
});
|
|
761
|
+
delete this.storeCache[stackedWindowIdentifier.windowName]; // remove stacked window from cache
|
|
762
|
+
resolve();
|
|
763
|
+
callback();
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
// clear the pubsub parent state for each child window (if not done, children will for some cases incorrectly have a parent specified);
|
|
767
|
+
// note removeWindow() will also clear this parent state, but this path doesn't invoke removeWindow
|
|
768
|
+
for (let i = 0; i < thisStackRecord.childWindowIdentifiers.length; i++) {
|
|
769
|
+
const childName = thisStackRecord.childWindowIdentifiers[i].name;
|
|
770
|
+
Logger.system.debug("StackedWindowManager.closeStackedWindow cleaning up parent state for child", childName);
|
|
771
|
+
RouterClient.publish(`Finsemble.parentChange.${childName}`, {});
|
|
772
|
+
}
|
|
773
|
+
// essentially shouldn't have to do anything else but cleanup local state -- workspace is closing children individually
|
|
774
|
+
if (thisStackRecord.visibleWindowIdentifier) {
|
|
775
|
+
const visibleChildWrapper = this.childWindow[thisStackRecord.visibleWindowIdentifier.windowName];
|
|
776
|
+
this.removeChildEventListener(stackedWindowIdentifier.windowName, thisStackRecord.visibleWindowIdentifier.windowName, visibleChildWrapper);
|
|
777
|
+
}
|
|
778
|
+
delete this.storeCache[stackedWindowIdentifier.windowName]; // remove stacked window from cache
|
|
779
|
+
resolve();
|
|
780
|
+
callback();
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
return new Promise(promiseResolver);
|
|
785
|
+
}
|
|
786
|
+
waitForWindowClosed(windowName) {
|
|
787
|
+
return new Promise((resolve) => {
|
|
788
|
+
const subscribeID = RouterClient.subscribe(`Finsemble.${windowName}.wrapReady`, (subscribeError, response) => {
|
|
789
|
+
const { data } = response;
|
|
790
|
+
const windowWasClosed = data.name === windowName && data.state === "closed";
|
|
791
|
+
if (!windowWasClosed) {
|
|
792
|
+
Logger.system.debug("StackedWindowManager.removeWindow waiting", windowName);
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
Logger.system.debug("StackedWindowManager.removeWindow continuing", windowName);
|
|
796
|
+
RouterClient.unsubscribe(subscribeID);
|
|
797
|
+
resolve(subscribeError);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
removeWindowFromCache(stackName, windowName) {
|
|
803
|
+
let stack = this.storeCache[stackName];
|
|
804
|
+
if (stack) {
|
|
805
|
+
for (let i = 0; i < stack.childWindowIdentifiers.length; i++) {
|
|
806
|
+
const item = stack.childWindowIdentifiers[i];
|
|
807
|
+
if (item.windowName === windowName) {
|
|
808
|
+
stack.childWindowIdentifiers.splice(i, 1);
|
|
809
|
+
return { wasAlwaysOnTop: item.alwaysOnTop, stack };
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
return { wasAlwaysOnTop: false, stack };
|
|
814
|
+
}
|
|
815
|
+
async closeStack(stackedWindowIdentifier) {
|
|
816
|
+
let stack = this.storeCache[stackedWindowIdentifier.windowName];
|
|
817
|
+
const lastChild = stack.childWindowIdentifiers[0];
|
|
818
|
+
const { err: getGroupsForWindowError, response } = await RouterClient.query("DockingService.getGroupsForWindow", {
|
|
819
|
+
name: stack.name,
|
|
820
|
+
});
|
|
821
|
+
await this.registerWithDockingManager({ windowIdentifier: lastChild });
|
|
822
|
+
const groups = response.data;
|
|
823
|
+
if (groups) {
|
|
824
|
+
for (const group of groups) {
|
|
825
|
+
RouterClient.transmit("DockingService.joinGroup", {
|
|
826
|
+
groupName: group,
|
|
827
|
+
name: lastChild.windowName,
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
const innerChildWrapper = this.childWindow[lastChild.windowName];
|
|
832
|
+
innerChildWrapper._show({ invokedByParent: true });
|
|
833
|
+
const { wrap } = await BaseWindow.getInstance(stackedWindowIdentifier);
|
|
834
|
+
// for now must call close on public wrapper to have wrapper cleanup happen correctly
|
|
835
|
+
Logger.system.debug("StackedWindowManager.removeWindowparent invoking public close", stackedWindowIdentifier, getGroupsForWindowError);
|
|
836
|
+
const { err } = await wrap.close({
|
|
837
|
+
closeChildren: false,
|
|
838
|
+
stackedWindowIdentifier,
|
|
839
|
+
removeFromWorkspace: true,
|
|
840
|
+
invokedByParent: true,
|
|
841
|
+
force: false,
|
|
842
|
+
});
|
|
843
|
+
return err;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Removes a child window from a stacked window. If removed window was visible, then the bottom child window (position 0) in stack will be made visible.
|
|
847
|
+
*
|
|
848
|
+
* @param {object} params Parameters
|
|
849
|
+
* @param {object} params.stackedWindowIdentifier stacked window to operate on
|
|
850
|
+
* @param {object} params.windowIdentifier window to remove
|
|
851
|
+
* @param {boolean=} params.noDocking if true then do not register removed window with docking (the workspace is unaffected)
|
|
852
|
+
* @param {boolean=} params.noVisible if true then do not make window visible when removing it
|
|
853
|
+
* @param {boolean=} params.waitChildClose if true then wait for child wrapper to close before returned (needed for cleanly switching workspaces)
|
|
854
|
+
* @param {boolean=false} params.closeWindow
|
|
855
|
+
* @param {boolean=false} params.noCloseStack if true don't close the stack window when only one child
|
|
856
|
+
* @param {function=} callback function(err)
|
|
857
|
+
* @memberof StackedWindowManager
|
|
858
|
+
* @returns promise
|
|
859
|
+
* @private
|
|
860
|
+
*/
|
|
861
|
+
async removeWindow(params, callback = Function.prototype) {
|
|
862
|
+
var _a;
|
|
863
|
+
const { noVisible, noCloseStack, stackedWindowIdentifier, windowIdentifier, noDocking } = params;
|
|
864
|
+
const { wasAlwaysOnTop, stack: thisStackRecord } = this.removeWindowFromCache(stackedWindowIdentifier.windowName, windowIdentifier.windowName);
|
|
865
|
+
Logger.system.debug("StackedWindowManager.removeWindow", params, thisStackRecord);
|
|
866
|
+
if (!thisStackRecord) {
|
|
867
|
+
const error = "StackedWindowManager.removeWindow unknown stackedWindowIdentifier";
|
|
868
|
+
Logger.system.warn(error, params);
|
|
869
|
+
callback(error);
|
|
870
|
+
return { err: error };
|
|
871
|
+
}
|
|
872
|
+
const childWrapper = this.childWindow[windowIdentifier.windowName];
|
|
873
|
+
childWrapper._alwaysOnTop({ alwaysOnTop: wasAlwaysOnTop });
|
|
874
|
+
childWrapper.clearParent(); // remove parent setting from child being remove
|
|
875
|
+
delete this.childNameToSID[windowIdentifier.windowName]; // remove child's mapping to parent stackedWindowIdentifier
|
|
876
|
+
if (((_a = thisStackRecord.visibleWindowIdentifier) === null || _a === void 0 ? void 0 : _a.windowName) === windowIdentifier.windowName) {
|
|
877
|
+
this.removeChildEventListener(thisStackRecord.identifier.windowName, windowIdentifier.windowName, childWrapper);
|
|
878
|
+
thisStackRecord.visibleWindowIdentifier = null;
|
|
879
|
+
}
|
|
880
|
+
// unless specified otherwise, register the remove window with docking
|
|
881
|
+
if (!noDocking) {
|
|
882
|
+
Logger.system.debug("StackedWindowManager.removeWindow registering with docking", stackedWindowIdentifier, windowIdentifier);
|
|
883
|
+
this.registerWithDockingManager({ windowIdentifier });
|
|
884
|
+
}
|
|
885
|
+
// go ahead and set visibility even if closing in order to finish this set of stackedWindow updates
|
|
886
|
+
if (thisStackRecord.childWindowIdentifiers.length && !thisStackRecord.visibleWindowIdentifier) {
|
|
887
|
+
this.setVisibleWindow({
|
|
888
|
+
stackedWindowIdentifier,
|
|
889
|
+
windowIdentifier: thisStackRecord.childWindowIdentifiers[0], // make the first window visible by default
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
// unless specified otherwise, show the window being removed from the stacked window (it might not be visible)
|
|
893
|
+
if (!noVisible) {
|
|
894
|
+
childWrapper._show({ invokedByParent: true });
|
|
895
|
+
}
|
|
896
|
+
await this.saveWindowOptions({ closing: false }, params.stackedWindowIdentifier);
|
|
897
|
+
// Notify interested listeners (e.g. BaseWindow wrappers of the removed window) that window was removed from the stack
|
|
898
|
+
Logger.system.debug("StackedWindowManager.removeWindow parent notification", windowIdentifier.windowName);
|
|
899
|
+
RouterClient.publish(`Finsemble.parentChange.${windowIdentifier.windowName}`, {
|
|
900
|
+
type: "Removed",
|
|
901
|
+
stackedWindowIdentifier,
|
|
902
|
+
});
|
|
903
|
+
RouterClient.publish(`Finsemble.parentChange.${windowIdentifier.windowName}`, {});
|
|
904
|
+
childWrapper._restore();
|
|
905
|
+
// if only one child window then the stack is empty and can be unregistered.
|
|
906
|
+
// Pull child out, and close stackedWindow;
|
|
907
|
+
// compare for <= 1 since might be concurrently removing multiple windows from stack for crashed components (i.e. this function is not fully reentrant yet)
|
|
908
|
+
if (!noCloseStack && thisStackRecord.childWindowIdentifiers.length <= 1) {
|
|
909
|
+
Logger.system.debug("StackedWindowManager.removeWindowparent closing stacked window", stackedWindowIdentifier);
|
|
910
|
+
const closeError = await this.closeStack(stackedWindowIdentifier);
|
|
911
|
+
// @early-exit. If you uncomment this return statement, the callback will be invoked twice. That causes errors and looks bad
|
|
912
|
+
// save the child value first because sometimes it's removed from the stackRecord before the query returns, but it still needs to be unregistered
|
|
913
|
+
callback(closeError);
|
|
914
|
+
return { err: closeError };
|
|
915
|
+
}
|
|
916
|
+
Logger.system.debug("StackedWindowManager.removeWindowparent NOT closing stacked window", noCloseStack, thisStackRecord);
|
|
917
|
+
let err = null;
|
|
918
|
+
if (params.waitChildClose) {
|
|
919
|
+
const error = await this.waitForWindowClosed(params.windowIdentifier.windowName);
|
|
920
|
+
if (error)
|
|
921
|
+
err = error.toString();
|
|
922
|
+
}
|
|
923
|
+
callback(err);
|
|
924
|
+
return { err };
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Removes a window from the stack then closes it. If removed window was visible, then the bottom child window (position 0) in stack will be made visible.
|
|
928
|
+
*
|
|
929
|
+
* @param {object} params Parameters
|
|
930
|
+
.* @param {object} params.stackedWindowIdentifier stacked window to operate on
|
|
931
|
+
* @param {object} params.windowIdentifier window to delete
|
|
932
|
+
* @param {function=} callback function(err)
|
|
933
|
+
* @memberof StackedWindowManager
|
|
934
|
+
* @private
|
|
935
|
+
*/
|
|
936
|
+
deleteWindow(params, callback = Function.prototype) {
|
|
937
|
+
const promiseResolver = async (resolve) => {
|
|
938
|
+
Logger.system.debug("StackedWindowManager.deleteWindow", params);
|
|
939
|
+
if (params.removeFromWorkspace === false) {
|
|
940
|
+
callback();
|
|
941
|
+
resolve();
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
params.noDocking = true;
|
|
945
|
+
await this.removeWindow(params);
|
|
946
|
+
const { wrap } = await BaseWindow.getInstance(params.windowIdentifier);
|
|
947
|
+
wrap.close({
|
|
948
|
+
/*
|
|
949
|
+
* If the close event is sent from the system (i.e. user is closing a stacked window from the taskbar), tell the wrapper to not show the error
|
|
950
|
+
* when attempting to close that window (because the window is already closed from the system).
|
|
951
|
+
* For now we're still calling this function even if it's a system close because we need some way to close a slacked window from the
|
|
952
|
+
* taskbar. We can also change the event name we pass into "this.setupSystemListener" in case of a system close in the WebWindowWrapper file from
|
|
953
|
+
* 'closed' to 'system-closed' so we don't have to close twice. But we decided it's a big change and we should go with a less risky approach in this bug fixing PR.
|
|
954
|
+
*/
|
|
955
|
+
suppressError: params.fromSystem,
|
|
956
|
+
invokedByParent: true,
|
|
957
|
+
force: false,
|
|
958
|
+
removeFromWorkspace: true,
|
|
959
|
+
}, (err) => {
|
|
960
|
+
callback(err);
|
|
961
|
+
resolve({ err });
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
return new Promise(promiseResolver);
|
|
966
|
+
}
|
|
967
|
+
getPreviouslyVisibleWindow(visibleWindowName, stackedWindowName) {
|
|
968
|
+
if (!visibleWindowName)
|
|
969
|
+
return null;
|
|
970
|
+
const previouslyVisibleWindow = this.childWindow[visibleWindowName]; // will use below to hide previous after setting next
|
|
971
|
+
if (previouslyVisibleWindow) {
|
|
972
|
+
this.removeChildEventListener(stackedWindowName, visibleWindowName, previouslyVisibleWindow);
|
|
973
|
+
}
|
|
974
|
+
return previouslyVisibleWindow;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Sets the visible window within the stack. The previously visible window in stack will be automatically hidden.
|
|
978
|
+
*
|
|
979
|
+
* @param {object} params Parameters
|
|
980
|
+
* @param {object} params.stackedWindowIdentifier stacked window to operate on
|
|
981
|
+
* @param {object} params.windowIdentifier
|
|
982
|
+
* @param {object} params.force if force is true then reset visible even if it is already marked as visible in store (this is for startup)
|
|
983
|
+
* @param {function=} callback function(err)
|
|
984
|
+
* @memberof StackedWindowManager
|
|
985
|
+
* @private
|
|
986
|
+
*/
|
|
987
|
+
async setVisibleWindow(params, cb) {
|
|
988
|
+
var _a;
|
|
989
|
+
Logger.system.debug("StackedWindowManager.setVisibleWindow", params);
|
|
990
|
+
const { stackedWindowIdentifier, windowIdentifier } = params;
|
|
991
|
+
const thisStackRecord = this.storeCache[stackedWindowIdentifier.windowName];
|
|
992
|
+
let err = null;
|
|
993
|
+
if (!thisStackRecord) {
|
|
994
|
+
err = "StackedWindowManager.setVisibleWindow unknown stackedWindowIdentifier";
|
|
995
|
+
Logger.system.warn(err, params);
|
|
996
|
+
cb === null || cb === void 0 ? void 0 : cb(err);
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
let previouslyVisibleWindow = this.getPreviouslyVisibleWindow((_a = thisStackRecord.visibleWindowIdentifier) === null || _a === void 0 ? void 0 : _a.windowName, stackedWindowIdentifier.windowName);
|
|
1000
|
+
thisStackRecord.visibleWindowIdentifier = windowIdentifier;
|
|
1001
|
+
const savedBounds = thisStackRecord.bounds;
|
|
1002
|
+
if (!previouslyVisibleWindow || (previouslyVisibleWindow === null || previouslyVisibleWindow === void 0 ? void 0 : previouslyVisibleWindow.windowState) !== constants.WINDOWSTATE.MAXIMIZED) {
|
|
1003
|
+
// set bounds on new visible window
|
|
1004
|
+
this.childWindow[windowIdentifier.windowName]._setBounds({
|
|
1005
|
+
bounds: thisStackRecord.bounds,
|
|
1006
|
+
invokedByParent: true,
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
const childWrapper = this.childWindow[windowIdentifier.windowName];
|
|
1010
|
+
childWrapper.disableFrame();
|
|
1011
|
+
this.addChildEventListener(stackedWindowIdentifier.windowName, thisStackRecord.visibleWindowIdentifier.windowName, childWrapper);
|
|
1012
|
+
Logger.system.debug("StackedWindowManager.setVisibleWindow showing", windowIdentifier);
|
|
1013
|
+
const notMinMax = childWrapper.windowOptions.windowState !== constants.WINDOWSTATE.MINIMIZED_WAS_NORMAL && !params.isAddingChildren;
|
|
1014
|
+
/* Workaround for an electron bug where calling show on a aero-snapped window restores the window to it's position prior to being aero-snapped.
|
|
1015
|
+
We can't prevent the window from moving, so after we show the child window we set it's bounds back to it's former position.
|
|
1016
|
+
aeroMode is used to track selecting a window from the preview after snapping. It needs to be set to false in this case as the aero-snap action has already completed.
|
|
1017
|
+
|
|
1018
|
+
This workaround, has the side effect of removing aero-snapped state from the window. However, since only the visible window when the stack was snapped was considered aero-snapped by the OS,
|
|
1019
|
+
the stack already did not respond to subsequent aero-snap commands if another tab was in focus.
|
|
1020
|
+
*/
|
|
1021
|
+
if (notMinMax)
|
|
1022
|
+
window.aeroMode = false;
|
|
1023
|
+
await childWrapper._show({
|
|
1024
|
+
invokedByParent: true,
|
|
1025
|
+
});
|
|
1026
|
+
// currently we'll handle a persisted MINIMIZED_WAS_NORMAL state in the stacked window, but not the MINIMIZED_WAS_MAXIMIZED (refactoring window management will address this)
|
|
1027
|
+
if (notMinMax) {
|
|
1028
|
+
if (childWrapper.windowState !== constants.WINDOWSTATE.MAXIMIZED) {
|
|
1029
|
+
childWrapper._setBounds({
|
|
1030
|
+
bounds: savedBounds,
|
|
1031
|
+
invokedByParent: true,
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
childWrapper._focus({ invokedByParent: true });
|
|
1035
|
+
Logger.system.debug("StackedWindowManager.setVisibleWindow shown", windowIdentifier);
|
|
1036
|
+
// Doing it this way so that the window in the back is visible when the one in the front hides. This reduces the flickering effect of switching tabs.
|
|
1037
|
+
if ((previouslyVisibleWindow === null || previouslyVisibleWindow === void 0 ? void 0 : previouslyVisibleWindow.windowName) !== childWrapper.windowName) {
|
|
1038
|
+
Logger.system.debug("StackedWindowManager.setVisibleWindow hiding previous", previouslyVisibleWindow);
|
|
1039
|
+
previouslyVisibleWindow === null || previouslyVisibleWindow === void 0 ? void 0 : previouslyVisibleWindow._hide({ invokedByParent: true }, () => {
|
|
1040
|
+
// sometimes (once every 5 tab switches or so) the window gets into a bad state where it is hidden as far as the system is concerned
|
|
1041
|
+
// but it is actually visible but cannot be interacted with. so call hide a second time to fix and really really hide.
|
|
1042
|
+
previouslyVisibleWindow === null || previouslyVisibleWindow === void 0 ? void 0 : previouslyVisibleWindow._hide({ invokedByParent: true });
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
// make sure the window is in front (use case: adding tab to window that isn't in front)
|
|
1047
|
+
childWrapper._bringToFront({ invokedByParent: true });
|
|
1048
|
+
if (!params.noSave) {
|
|
1049
|
+
this.saveWindowOptions({ closing: false }, params.stackedWindowIdentifier);
|
|
1050
|
+
}
|
|
1051
|
+
cb === null || cb === void 0 ? void 0 : cb(err);
|
|
1052
|
+
}
|
|
1053
|
+
// temporary code to workaround tabbing/tiling problem that reshows window when tabs are reordered
|
|
1054
|
+
hideInactiveChildren(thisStackRecord) {
|
|
1055
|
+
Logger.system.debug("StackedWindowManager.hideInactiveChildren");
|
|
1056
|
+
thisStackRecord.childWindowIdentifiers.forEach((identifier) => {
|
|
1057
|
+
// only rehide if not the the visible window
|
|
1058
|
+
if (thisStackRecord.visibleWindowIdentifier &&
|
|
1059
|
+
identifier.windowName !== thisStackRecord.visibleWindowIdentifier.windowName) {
|
|
1060
|
+
const wrap = this.childWindow[identifier.windowName];
|
|
1061
|
+
wrap._hide({ invokedByParent: true });
|
|
1062
|
+
}
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Reorders the stack, but odes not affect visibility
|
|
1067
|
+
*
|
|
1068
|
+
* @param {object} params Parameters
|
|
1069
|
+
* @param {object} params.stackedWindowIdentifier stacked window to operate on
|
|
1070
|
+
* @param {array} params.windowIdentifiers array of windowIdentifiers which provides the new order
|
|
1071
|
+
* @param {function=} callback function(err)
|
|
1072
|
+
* @memberof StackedWindowManager
|
|
1073
|
+
* @private
|
|
1074
|
+
*/
|
|
1075
|
+
reorder(params, callback = Function.prototype) {
|
|
1076
|
+
Logger.system.debug("StackedWindowManager.reorder", params);
|
|
1077
|
+
const { stackedWindowIdentifier, windowIdentifiers } = params;
|
|
1078
|
+
// TBD: verify list of identifiers are the same and if not generate error
|
|
1079
|
+
const thisStackRecord = this.storeCache[stackedWindowIdentifier.windowName];
|
|
1080
|
+
let err = null;
|
|
1081
|
+
if (thisStackRecord) {
|
|
1082
|
+
thisStackRecord.childWindowIdentifiers = windowIdentifiers;
|
|
1083
|
+
this.hideInactiveChildren(thisStackRecord); // this is to sidestep a bug in docking/tiling that reshows a moved tab
|
|
1084
|
+
this.saveWindowOptions({ closing: false }, stackedWindowIdentifier);
|
|
1085
|
+
}
|
|
1086
|
+
else {
|
|
1087
|
+
err = "StackedWindowManager.reorder unknown stackedWindowIdentifier";
|
|
1088
|
+
Logger.system.warn(err, params);
|
|
1089
|
+
}
|
|
1090
|
+
if (callback)
|
|
1091
|
+
callback(err);
|
|
1092
|
+
}
|
|
1093
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
1094
|
+
// The next section of functions support stacked-window primitives throughout the system.
|
|
1095
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
1096
|
+
// stacked window minimize (invoked remotely through stacked window wrapper)
|
|
1097
|
+
minimize(params, callback = Function.prototype) {
|
|
1098
|
+
Logger.system.debug("StackedWindowManager.minimize", params);
|
|
1099
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1100
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1101
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1102
|
+
if (thisStackRecord) {
|
|
1103
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1104
|
+
}
|
|
1105
|
+
else {
|
|
1106
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1107
|
+
return callback("undefined window");
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
if (this.isShowing(params)) {
|
|
1111
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1112
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1113
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._minimize(params); // invoke function on active window's wrapper
|
|
1114
|
+
}
|
|
1115
|
+
else {
|
|
1116
|
+
Logger.system.error(`StackedWindowManager Warning: minimize received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1117
|
+
}
|
|
1118
|
+
callback(null);
|
|
1119
|
+
}
|
|
1120
|
+
// stacked window maximize (invoked remotely through stacked window wrapper)
|
|
1121
|
+
maximize(params, callback = Function.prototype) {
|
|
1122
|
+
Logger.system.debug("StackedWindowManager.maximize", params);
|
|
1123
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1124
|
+
const visibleWindowWrap = this.childWindow[thisStackRecord.visibleWindowIdentifier.windowName];
|
|
1125
|
+
if (visibleWindowWrap)
|
|
1126
|
+
visibleWindowWrap._maximize();
|
|
1127
|
+
callback();
|
|
1128
|
+
}
|
|
1129
|
+
// stacked window restore (invoked remotely through stacked window wrapper)
|
|
1130
|
+
restore(params, callback = Function.prototype) {
|
|
1131
|
+
Logger.system.debug("StackedWindowManager.restore", params);
|
|
1132
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1133
|
+
const visibleWindowWrap = this.childWindow[thisStackRecord.visibleWindowIdentifier.windowName];
|
|
1134
|
+
if (visibleWindowWrap.windowState === undefined)
|
|
1135
|
+
visibleWindowWrap.windowState = params.windowState;
|
|
1136
|
+
if (visibleWindowWrap)
|
|
1137
|
+
visibleWindowWrap._restore();
|
|
1138
|
+
return callback();
|
|
1139
|
+
}
|
|
1140
|
+
// stacked window focus (invoked remotely through stacked window wrapper)
|
|
1141
|
+
focus(params, callback = Function.prototype) {
|
|
1142
|
+
Logger.system.debug("StackedWindowManager.focus", params);
|
|
1143
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1144
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1145
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1146
|
+
if (thisStackRecord) {
|
|
1147
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1148
|
+
}
|
|
1149
|
+
else {
|
|
1150
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1151
|
+
return callback("undefined window");
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
if (this.isShowing(params)) {
|
|
1155
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1156
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1157
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._focus(params); // invoke function on active window's wrapper
|
|
1158
|
+
}
|
|
1159
|
+
else {
|
|
1160
|
+
Logger.system.error(`StackedWindowManager Warning: focus received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1161
|
+
}
|
|
1162
|
+
callback(null);
|
|
1163
|
+
}
|
|
1164
|
+
// stacked window bringToFront (invoked remotely through stacked window wrapper)
|
|
1165
|
+
bringToFront(params, callback = Function.prototype) {
|
|
1166
|
+
var _a;
|
|
1167
|
+
params = params || {};
|
|
1168
|
+
Logger.system.debug("StackedWindowManager.bringToFront", params);
|
|
1169
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1170
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1171
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1172
|
+
if (thisStackRecord) {
|
|
1173
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1177
|
+
return callback("undefined window");
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
if (this.isShowing(params)) {
|
|
1181
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1182
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1183
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._bringToFront(params); // invoke function on active window's wrapper
|
|
1184
|
+
}
|
|
1185
|
+
else {
|
|
1186
|
+
Logger.system.error(`StackedWindowManager Warning: bringToFront received for hidden window ${(_a = params.stackedWindowIdentifier) === null || _a === void 0 ? void 0 : _a.windowName}`);
|
|
1187
|
+
}
|
|
1188
|
+
callback(null);
|
|
1189
|
+
}
|
|
1190
|
+
saveWindowStateToStore(params, callback = Function.prototype) {
|
|
1191
|
+
this.saveWindowOptions({ closing: false }, params.stackedWindowIdentifier, callback);
|
|
1192
|
+
}
|
|
1193
|
+
mergeBounds(stackRecord, bounds) {
|
|
1194
|
+
bounds.right = bounds.left + bounds.width;
|
|
1195
|
+
const newBounds = {
|
|
1196
|
+
left: bounds.left,
|
|
1197
|
+
right: bounds.right,
|
|
1198
|
+
width: bounds.width,
|
|
1199
|
+
top: bounds.top,
|
|
1200
|
+
bottom: bounds.top + bounds.height,
|
|
1201
|
+
height: bounds.height,
|
|
1202
|
+
};
|
|
1203
|
+
const defaultBounds = {
|
|
1204
|
+
defaultLeft: bounds.left,
|
|
1205
|
+
defaultWidth: bounds.width,
|
|
1206
|
+
defaultTop: bounds.top,
|
|
1207
|
+
defaultHeight: bounds.height,
|
|
1208
|
+
};
|
|
1209
|
+
Object.assign(stackRecord, newBounds);
|
|
1210
|
+
Object.assign(stackRecord, defaultBounds);
|
|
1211
|
+
stackRecord.bounds = newBounds;
|
|
1212
|
+
}
|
|
1213
|
+
// stacked window setBounds (invoked remotely through stacked window wrapper)
|
|
1214
|
+
setBounds(params, callback = Function.prototype) {
|
|
1215
|
+
Logger.system.debug("StackedWindowManager.setBounds", params);
|
|
1216
|
+
let err = null;
|
|
1217
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1218
|
+
if (!thisStackRecord) {
|
|
1219
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1220
|
+
err = "undefined window";
|
|
1221
|
+
}
|
|
1222
|
+
else {
|
|
1223
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1224
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1225
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1226
|
+
}
|
|
1227
|
+
if (this.isShowing(params)) {
|
|
1228
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1229
|
+
this.mergeBounds(thisStackRecord, params.bounds);
|
|
1230
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1231
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._setBounds(params); // invoke function on active window's wrapper
|
|
1232
|
+
}
|
|
1233
|
+
else if (params.windowIdentifier) {
|
|
1234
|
+
Logger.system.warn(`StackedWindowManager Warning: setBounds received for hidden window ${params.windowIdentifier}`);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
callback(err);
|
|
1238
|
+
}
|
|
1239
|
+
// stacked window getBoundsFromSystem (invoked remotely through stacked window wrapper)
|
|
1240
|
+
getBoundsFromSystem(params, callback = Function.prototype) {
|
|
1241
|
+
Logger.system.debug("StackedWindowManager.getBoundsFromSystem", params);
|
|
1242
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1243
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1244
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1245
|
+
if (thisStackRecord) {
|
|
1246
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1247
|
+
}
|
|
1248
|
+
else {
|
|
1249
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1250
|
+
return callback("undefined window");
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
if (this.isShowing(params)) {
|
|
1254
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1255
|
+
if (!visibleWindow) {
|
|
1256
|
+
const err = `stackedWindowManager: cannot find child window ${params.windowIdentifier.windowName}`;
|
|
1257
|
+
Logger.system.error(err);
|
|
1258
|
+
callback(err);
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1262
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._getBoundsFromSystem(params, (err, bounds) => {
|
|
1263
|
+
// invoke function on active window's wrapper
|
|
1264
|
+
const _bounds = err ? thisStackRecord.bounds : bounds;
|
|
1265
|
+
callback(err, _bounds);
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
else if (!this.operatingDirectlyOnStackedWindow(params)) {
|
|
1269
|
+
Logger.system.error(`StackedWindowManager Warning: getBoundsFromSystem received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1270
|
+
callback("getBounds on hidden window");
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
// stacked window getBounds (invoked remotely through stacked window wrapper)
|
|
1274
|
+
getBounds(params, callback = Function.prototype) {
|
|
1275
|
+
params = params || {};
|
|
1276
|
+
Logger.system.debug("StackedWindowManager.getBounds", params);
|
|
1277
|
+
let thisStackRecord = null;
|
|
1278
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1279
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1280
|
+
thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1281
|
+
if (thisStackRecord) {
|
|
1282
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1283
|
+
Logger.system.debug("StackedWindowManager.getBounds", params, thisStackRecord);
|
|
1284
|
+
}
|
|
1285
|
+
else {
|
|
1286
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1287
|
+
callback("undefined window");
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
if (thisStackRecord && thisStackRecord.bounds) {
|
|
1292
|
+
callback(null, thisStackRecord.bounds);
|
|
1293
|
+
}
|
|
1294
|
+
else if (!thisStackRecord.visibleWindowIdentifier) {
|
|
1295
|
+
// since no visible window use empty bounds; this is to handle an intermittent error that sometimes occurred when creating a stack
|
|
1296
|
+
const emptyBounds = {
|
|
1297
|
+
left: 0,
|
|
1298
|
+
right: 0,
|
|
1299
|
+
width: 10,
|
|
1300
|
+
top: 0,
|
|
1301
|
+
bottom: 0,
|
|
1302
|
+
height: 10,
|
|
1303
|
+
};
|
|
1304
|
+
callback(null, emptyBounds);
|
|
1305
|
+
}
|
|
1306
|
+
else if (this.isShowing(params)) {
|
|
1307
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1308
|
+
if (!visibleWindow) {
|
|
1309
|
+
const err = `stackedWindowManager: cannot find child window ${params.windowIdentifier.windowName}`;
|
|
1310
|
+
Logger.system.error(err);
|
|
1311
|
+
callback(err);
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1315
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._getBounds(params, (err, bounds) => {
|
|
1316
|
+
// invoke function on active window's wrapper
|
|
1317
|
+
const _bounds = err ? this.storeCache[params.stackedWindowIdentifier.windowName].bounds : bounds;
|
|
1318
|
+
callback(err, _bounds);
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
else if (!this.operatingDirectlyOnStackedWindow(params)) {
|
|
1322
|
+
Logger.system.error(`StackedWindowManager Warning: getBounds received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1323
|
+
callback("getBounds on hidden window");
|
|
1324
|
+
}
|
|
1325
|
+
callback("something went wrong");
|
|
1326
|
+
}
|
|
1327
|
+
// stacked window updateOptions (invoked remotely through stacked window wrapper)
|
|
1328
|
+
updateOptions(params, callback = Function.prototype) {
|
|
1329
|
+
Logger.system.debug("StackedWindowManager.updateOptions", params);
|
|
1330
|
+
let err = null;
|
|
1331
|
+
// TABBING TBD: put in a getter function for the stacked records to provide common error checking. Docking might invoke for non-existent stacked window
|
|
1332
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1333
|
+
if (thisStackRecord) {
|
|
1334
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1335
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1336
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1337
|
+
}
|
|
1338
|
+
if (this.isShowing(params)) {
|
|
1339
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1340
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1341
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._updateOptions(params); // invoke function on active window's wrapper
|
|
1342
|
+
// if (visibleWindow) { // update options is invoked during docking registration while stacked window is being created, so may not have visible window
|
|
1343
|
+
// visibleWindow._updateOptions(params); // invoke function on active window's wrapper
|
|
1344
|
+
// }
|
|
1345
|
+
}
|
|
1346
|
+
else {
|
|
1347
|
+
Logger.system.error(`StackedWindowManager.updateOptions Warning: updateOptions received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
else {
|
|
1351
|
+
// else must be an outdated request from a closed stacked window
|
|
1352
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1353
|
+
err = "undefined window";
|
|
1354
|
+
}
|
|
1355
|
+
callback(err);
|
|
1356
|
+
}
|
|
1357
|
+
// stacked window hide (invoked remotely through stacked window wrapper)
|
|
1358
|
+
hide(params, callback = Function.prototype) {
|
|
1359
|
+
Logger.system.debug("StackedWindowManager.hide", params);
|
|
1360
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1361
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1362
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1363
|
+
if (thisStackRecord) {
|
|
1364
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1365
|
+
thisStackRecord.isVisible = false;
|
|
1366
|
+
}
|
|
1367
|
+
else {
|
|
1368
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1369
|
+
return callback("undefined window");
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
if (this.isShowing(params)) {
|
|
1373
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1374
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1375
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._hide(params); // invoke function on active window's wrapper
|
|
1376
|
+
}
|
|
1377
|
+
else {
|
|
1378
|
+
Logger.system.error(`StackedWindowManager Warning: hide received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1379
|
+
}
|
|
1380
|
+
callback(null);
|
|
1381
|
+
}
|
|
1382
|
+
// stacked window show (invoked remotely through stacked window wrapper)
|
|
1383
|
+
show(params, callback = Function.prototype) {
|
|
1384
|
+
Logger.system.debug("StackedWindowManager.show", params);
|
|
1385
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1386
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1387
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1388
|
+
if (thisStackRecord) {
|
|
1389
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1390
|
+
thisStackRecord.isVisible = true;
|
|
1391
|
+
}
|
|
1392
|
+
else {
|
|
1393
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1394
|
+
return callback("undefined window");
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
if (this.isShowing(params)) {
|
|
1398
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1399
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1400
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._show(params); // invoke function on active window's wrapper
|
|
1401
|
+
}
|
|
1402
|
+
else {
|
|
1403
|
+
Logger.system.error(`StackedWindowManager Warning: show received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1404
|
+
}
|
|
1405
|
+
callback(null);
|
|
1406
|
+
}
|
|
1407
|
+
// this stacked window close applies to an individual child window (see closeStackedWindow for closing the complete stackedWindow)
|
|
1408
|
+
close(params, callback = Function.prototype) {
|
|
1409
|
+
Logger.system.debug("StackedWindowManager.close", params);
|
|
1410
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1411
|
+
if (params.removeFromWorkspace || this.operatingDirectlyOnStackedWindow(params)) {
|
|
1412
|
+
this.closeStackedWindow(params, callback);
|
|
1413
|
+
}
|
|
1414
|
+
else {
|
|
1415
|
+
this.deleteWindow(params, callback);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* whether the stack itself is visible or not
|
|
1420
|
+
* @param params
|
|
1421
|
+
* @param callback
|
|
1422
|
+
*/
|
|
1423
|
+
isStackShowing(params, callback = Function.prototype) {
|
|
1424
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1425
|
+
if (thisStackRecord.isVisible === false) {
|
|
1426
|
+
callback(null, false);
|
|
1427
|
+
return;
|
|
1428
|
+
}
|
|
1429
|
+
callback(null, true);
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* set Stack to be always on top. Makes all children of the stack always on top and triggers the alwaysOnTop event for the stack
|
|
1433
|
+
*/
|
|
1434
|
+
setAlwaysOnTop(params, callback = Function.prototype) {
|
|
1435
|
+
const setAlwaysOnTopPromiseResolver = (resolve) => {
|
|
1436
|
+
Logger.system.debug("StackedWindowManager.setAlwaysOnTop", params);
|
|
1437
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1438
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1439
|
+
if (this.operatingDirectlyOnStackedWindow(params) && !thisStackRecord) {
|
|
1440
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1441
|
+
resolve();
|
|
1442
|
+
return callback("undefined window");
|
|
1443
|
+
}
|
|
1444
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1445
|
+
for (const childWindowIdentifier of thisStackRecord.childWindowIdentifiers) {
|
|
1446
|
+
const childWindow = this.childWindow[childWindowIdentifier.windowName];
|
|
1447
|
+
childWindow._alwaysOnTop(params);
|
|
1448
|
+
}
|
|
1449
|
+
FinsembleWindowInternal.getInstance({ name: thisStackRecord.name }, (err, stackedWindow) => {
|
|
1450
|
+
if (stackedWindow.alwaysOnTop !== params.alwaysOnTop) {
|
|
1451
|
+
stackedWindow.alwaysOnTop = params.alwaysOnTop;
|
|
1452
|
+
stackedWindow.eventManager.trigger("alwaysOnTop", {
|
|
1453
|
+
alwaysOnTop: params.alwaysOnTop,
|
|
1454
|
+
});
|
|
1455
|
+
Logger.system.verbose("StackedWindowManager transmitting event", "alwaysOnTop", this.eventChannelName(thisStackRecord.name, "alwaysOnTop"), event);
|
|
1456
|
+
}
|
|
1457
|
+
callback(null);
|
|
1458
|
+
resolve();
|
|
1459
|
+
});
|
|
1460
|
+
};
|
|
1461
|
+
return new Promise(setAlwaysOnTopPromiseResolver);
|
|
1462
|
+
}
|
|
1463
|
+
// stacked window setOpacity (invoked remotely through stacked window wrapper)
|
|
1464
|
+
setOpacity(params, callback = Function.prototype) {
|
|
1465
|
+
let err = null;
|
|
1466
|
+
Logger.system.debug("StackedWindowManager.setOpacity", params);
|
|
1467
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1468
|
+
if (thisStackRecord) {
|
|
1469
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1470
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1471
|
+
if (!thisStackRecord.visibleWindowIdentifier)
|
|
1472
|
+
return; // there's no window to set opacity on.
|
|
1473
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1474
|
+
}
|
|
1475
|
+
if (this.isShowing(params)) {
|
|
1476
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1477
|
+
params.invokedByParent = true; // prevents wrapper function from recalling parent (causing a loop)
|
|
1478
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow._setOpacity(params); // invoke function on active window's wrapper
|
|
1479
|
+
}
|
|
1480
|
+
else {
|
|
1481
|
+
Logger.system.error(`StackedWindowManager Warning: setOpacity received for hidden window ${params.windowIdentifier.windowName}`);
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
else {
|
|
1485
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1486
|
+
err = "undefined window";
|
|
1487
|
+
}
|
|
1488
|
+
callback(err);
|
|
1489
|
+
}
|
|
1490
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
1491
|
+
// General functions support workspace and docking
|
|
1492
|
+
// TABBING TBD: NEED GENERAL PARAMETERIZED VERSIONS OF THE FUNCTIONS BELOW PULLED OUT OF THE WINDOW CLIENT AND PUT IN COMMON TO SHARE
|
|
1493
|
+
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
1494
|
+
// placeholder for workspace integration
|
|
1495
|
+
async saveWindowOptions(params, stackedWindowIdentifier, maincallback = Function.prototype) {
|
|
1496
|
+
Logger.system.debug("StackedWindowManager.setComponentState", stackedWindowIdentifier);
|
|
1497
|
+
const thisStackRecord = this.storeCache[stackedWindowIdentifier.windowName];
|
|
1498
|
+
if (!thisStackRecord)
|
|
1499
|
+
return maincallback("stack record not found");
|
|
1500
|
+
const { wrap: stackedWindow } = await FinsembleWindowInternal.getInstance({
|
|
1501
|
+
name: stackedWindowIdentifier.windowName,
|
|
1502
|
+
});
|
|
1503
|
+
stackedWindow.saveCompleteWindowState(thisStackRecord, () => {
|
|
1504
|
+
var _a;
|
|
1505
|
+
const saveChildBounds = (childIdentifier, done) => {
|
|
1506
|
+
Logger.system.debug("StackedWindowManager.saveWindowOptions saveCompleteWindowState child", childIdentifier.windowName);
|
|
1507
|
+
const { bounds } = thisStackRecord;
|
|
1508
|
+
bounds.persistBounds = true;
|
|
1509
|
+
const wrap = this.childWindow[childIdentifier.windowName];
|
|
1510
|
+
if (wrap) {
|
|
1511
|
+
wrap._setBounds({ bounds, invokedByParent: true }, done);
|
|
1512
|
+
}
|
|
1513
|
+
else {
|
|
1514
|
+
FinsembleWindowInternal.getInstance({ name: childIdentifier.windowName }, (err, wrappedWindow) => {
|
|
1515
|
+
wrappedWindow._setBounds({ bounds, invokedByParent: true }, done);
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
};
|
|
1519
|
+
Logger.system.debug("StackedWindowManager.saveWindowOptions saveCompleteWindowState start", (_a = stackedWindow.identifier) === null || _a === void 0 ? void 0 : _a.windowName, thisStackRecord);
|
|
1520
|
+
if (!params.closing) {
|
|
1521
|
+
asyncEach(thisStackRecord.childWindowIdentifiers, saveChildBounds, () => {
|
|
1522
|
+
Logger.system.debug("StackedWindowManager.saveWindowOptions saveCompleteWindowState done");
|
|
1523
|
+
RouterClient.publish(`Finsemble.StackedWindow.${stackedWindowIdentifier.windowName}`, thisStackRecord);
|
|
1524
|
+
maincallback();
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
else {
|
|
1528
|
+
Logger.system.debug("StackedWindowManager.saveWindowOptions saveCompleteWindowState skipped");
|
|
1529
|
+
RouterClient.publish(`Finsemble.StackedWindow.${stackedWindowIdentifier.windowName}`, thisStackRecord);
|
|
1530
|
+
maincallback();
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
/**
|
|
1535
|
+
* Register a window with docking. It transmits a message to the LauncherService, which registers it as a dockable window.
|
|
1536
|
+
*
|
|
1537
|
+
* @param {object} params Parameters
|
|
1538
|
+
* @param {string} params.windowIdentifier the window to register (may be stacked window or child window)
|
|
1539
|
+
* @private
|
|
1540
|
+
*/
|
|
1541
|
+
registerWithDockingManager(params, cb = Function.prototype) {
|
|
1542
|
+
const promiseResolver = (resolve) => {
|
|
1543
|
+
Logger.system.debug("StackedWindowManager.registerWithDockingManager", params);
|
|
1544
|
+
const { windowName } = params.windowIdentifier;
|
|
1545
|
+
params.windowIdentifier.name = windowName;
|
|
1546
|
+
// In the case when we have an existing window, we should use it's options. Otherwise the default options will be applied.
|
|
1547
|
+
const wrap = this.childWindow[windowName];
|
|
1548
|
+
const queryParams = wrap
|
|
1549
|
+
? {
|
|
1550
|
+
name: windowName,
|
|
1551
|
+
uuid: params.windowIdentifier.uuid,
|
|
1552
|
+
windowType: params.windowIdentifier.windowType,
|
|
1553
|
+
options: {
|
|
1554
|
+
// dockingOptions
|
|
1555
|
+
options: wrap.dockingOptions,
|
|
1556
|
+
snapping: wrap.snapping,
|
|
1557
|
+
tiling: wrap.tiling,
|
|
1558
|
+
tabbing: wrap.tabbing,
|
|
1559
|
+
allowAutoArrange: wrap.allowAutoArrange,
|
|
1560
|
+
canMinimize: wrap.canMinimize,
|
|
1561
|
+
canMaximize: wrap.canMaximize,
|
|
1562
|
+
},
|
|
1563
|
+
}
|
|
1564
|
+
: Object.assign(params.windowIdentifier, params.windowType);
|
|
1565
|
+
RouterClient.query("DockingService.registerWindow", queryParams, () => {
|
|
1566
|
+
Logger.system.debug("StackedWindowManager Docking Registration complete.", params);
|
|
1567
|
+
resolve();
|
|
1568
|
+
if (cb) {
|
|
1569
|
+
cb();
|
|
1570
|
+
}
|
|
1571
|
+
});
|
|
1572
|
+
};
|
|
1573
|
+
return new Promise(promiseResolver);
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Unregister a window with docking.
|
|
1577
|
+
*
|
|
1578
|
+
* @param {object} params Parameters
|
|
1579
|
+
* @param {boolean} params.removeFromWorkspace true to remove from workspace
|
|
1580
|
+
* @param {string} params.windowIdentifier window to unregister
|
|
1581
|
+
* @private
|
|
1582
|
+
*/
|
|
1583
|
+
deregisterWithDockingManager(params) {
|
|
1584
|
+
Logger.system.debug("StackedWindowManager.deregisterWithDockingManager", params);
|
|
1585
|
+
RouterClient.transmit("DockingService.deregisterWindow", {
|
|
1586
|
+
name: params.windowIdentifier.windowName,
|
|
1587
|
+
userInitiated: params.removeFromWorkspace,
|
|
1588
|
+
});
|
|
1589
|
+
}
|
|
1590
|
+
startMove(params, callback = Function.prototype) {
|
|
1591
|
+
// stacked window setBounds (invoked remotely through stacked window wrapper)
|
|
1592
|
+
Logger.system.debug("StackedWindowManager.startMove", params);
|
|
1593
|
+
let err = null;
|
|
1594
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1595
|
+
if (!thisStackRecord) {
|
|
1596
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1597
|
+
err = "undefined window";
|
|
1598
|
+
}
|
|
1599
|
+
else {
|
|
1600
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1601
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1602
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1603
|
+
}
|
|
1604
|
+
if (this.isShowing(params)) {
|
|
1605
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1606
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow.startMove(); // invoke function on active window's wrapper
|
|
1607
|
+
}
|
|
1608
|
+
else {
|
|
1609
|
+
Logger.system.error(`StackedWindowManager Warning: startMove received for hidden window ${params.windowIdentifier}`);
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
callback(err);
|
|
1613
|
+
}
|
|
1614
|
+
stopMove(params, callback = Function.prototype) {
|
|
1615
|
+
// stacked window setBounds (invoked remotely through stacked window wrapper)
|
|
1616
|
+
Logger.system.debug("StackedWindowManager.stopMove", params);
|
|
1617
|
+
let err = null;
|
|
1618
|
+
const thisStackRecord = this.storeCache[params.stackedWindowIdentifier.windowName];
|
|
1619
|
+
if (!thisStackRecord) {
|
|
1620
|
+
Logger.system.warn("ignoring command because StackedWindow undefined (probably okay due to its recent close)", params);
|
|
1621
|
+
err = "undefined window";
|
|
1622
|
+
}
|
|
1623
|
+
else {
|
|
1624
|
+
// if operating on StackedWindow then operation should apply to the visible window
|
|
1625
|
+
if (this.operatingDirectlyOnStackedWindow(params)) {
|
|
1626
|
+
params.windowIdentifier = thisStackRecord.visibleWindowIdentifier;
|
|
1627
|
+
}
|
|
1628
|
+
if (this.isShowing(params)) {
|
|
1629
|
+
const visibleWindow = this.childWindow[params.windowIdentifier.windowName];
|
|
1630
|
+
visibleWindow === null || visibleWindow === void 0 ? void 0 : visibleWindow.stopMove(); // invoke function on active window's wrapper
|
|
1631
|
+
}
|
|
1632
|
+
else {
|
|
1633
|
+
Logger.system.error(`StackedWindowManager Warning: stopMove received for hidden window ${params.windowIdentifier}`);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
callback(err);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
const serviceInstance = new StackedWindowManager({});
|
|
1640
|
+
export default serviceInstance;
|
|
1641
|
+
//# sourceMappingURL=stackedWindowManager.js.map
|