@finsemble/finsemble-ui 8.3.0-beta.8 → 8.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FEA.d.ts +102 -28
- package/FEA.d.ts.map +1 -1
- package/FEA.js.map +1 -1
- package/clients/Interop/FinsembleDesktopAgent.d.ts +1 -0
- package/clients/Interop/FinsembleDesktopAgent.d.ts.map +1 -1
- package/clients/Interop/FinsembleDesktopAgent.js +17 -16
- package/clients/Interop/FinsembleDesktopAgent.js.map +1 -1
- package/clients/Interop/types.d.ts +1 -0
- package/clients/Interop/types.d.ts.map +1 -1
- package/clients/Startup/FSBLDesktop.d.ts +2 -8
- package/clients/Startup/FSBLDesktop.d.ts.map +1 -1
- package/clients/Startup/FSBLDesktop.js +2 -4
- package/clients/Startup/FSBLDesktop.js.map +1 -1
- package/clients/Startup/unhandledErrors.d.ts.map +1 -1
- package/clients/Startup/unhandledErrors.js +6 -4
- package/clients/Startup/unhandledErrors.js.map +1 -1
- package/clients/Startup/windowStartup.d.ts.map +1 -1
- package/clients/Startup/windowStartup.js +125 -112
- package/clients/Startup/windowStartup.js.map +1 -1
- package/clients/StoreModel.d.ts +8 -8
- package/clients/StoreModel.js +9 -9
- package/clients/StoreModel.js.map +1 -1
- package/clients/appsClient.d.ts +463 -0
- package/clients/appsClient.d.ts.map +1 -0
- package/clients/appsClient.js +696 -0
- package/clients/appsClient.js.map +1 -0
- package/clients/authenticationClient.d.ts +36 -27
- package/clients/authenticationClient.d.ts.map +1 -1
- package/clients/authenticationClient.js +18 -15
- package/clients/authenticationClient.js.map +1 -1
- package/clients/configClient.d.ts +189 -71
- package/clients/configClient.d.ts.map +1 -1
- package/clients/configClient.js +185 -114
- package/clients/configClient.js.map +1 -1
- package/clients/controller/DialogManagerClientController.d.ts +78 -0
- package/clients/controller/DialogManagerClientController.d.ts.map +1 -0
- package/clients/controller/DialogManagerClientController.js +213 -0
- package/clients/controller/DialogManagerClientController.js.map +1 -0
- package/clients/dialogManagerClient.d.ts +11 -75
- package/clients/dialogManagerClient.d.ts.map +1 -1
- package/clients/dialogManagerClient.js +11 -208
- package/clients/dialogManagerClient.js.map +1 -1
- package/clients/distributedStoreClient.d.ts +4 -0
- package/clients/distributedStoreClient.d.ts.map +1 -1
- package/clients/distributedStoreClient.js +4 -0
- package/clients/distributedStoreClient.js.map +1 -1
- package/clients/hotkeyClient.d.ts +23 -9
- package/clients/hotkeyClient.d.ts.map +1 -1
- package/clients/hotkeyClient.js +35 -14
- package/clients/hotkeyClient.js.map +1 -1
- package/clients/index.d.ts +2 -0
- package/clients/index.d.ts.map +1 -1
- package/clients/index.js +2 -0
- package/clients/index.js.map +1 -1
- package/clients/launcherClient.d.ts +55 -209
- package/clients/launcherClient.d.ts.map +1 -1
- package/clients/launcherClient.js +37 -422
- package/clients/launcherClient.js.map +1 -1
- package/clients/logger.d.ts +6 -0
- package/clients/logger.d.ts.map +1 -1
- package/clients/logger.js +49 -41
- package/clients/logger.js.map +1 -1
- package/clients/notificationClient.d.ts +32 -8
- package/clients/notificationClient.d.ts.map +1 -1
- package/clients/notificationClient.js +32 -8
- package/clients/notificationClient.js.map +1 -1
- package/clients/routerClient.d.ts +39 -21
- package/clients/routerClient.d.ts.map +1 -1
- package/clients/routerClient.js +38 -20
- package/clients/routerClient.js.map +1 -1
- package/clients/searchClient.d.ts +7 -2
- package/clients/searchClient.d.ts.map +1 -1
- package/clients/searchClient.js +7 -2
- package/clients/searchClient.js.map +1 -1
- package/clients/storageClient.d.ts +19 -6
- package/clients/storageClient.d.ts.map +1 -1
- package/clients/storageClient.js +18 -6
- package/clients/storageClient.js.map +1 -1
- package/clients/windowClient.d.ts +207 -80
- package/clients/windowClient.d.ts.map +1 -1
- package/clients/windowClient.js +291 -139
- package/clients/windowClient.js.map +1 -1
- package/clients/workspaceClient.d.ts +45 -18
- package/clients/workspaceClient.d.ts.map +1 -1
- package/clients/workspaceClient.js +41 -13
- package/clients/workspaceClient.js.map +1 -1
- package/common/Desktop.d.ts +12 -50
- package/common/Desktop.d.ts.map +1 -1
- package/common/Desktop.js +14 -64
- package/common/Desktop.js.map +1 -1
- package/common/FinsembleWindow.d.ts +5 -108
- package/common/FinsembleWindow.d.ts.map +1 -1
- package/common/FinsembleWindow.js +28 -349
- package/common/FinsembleWindow.js.map +1 -1
- package/common/Monitors.d.ts +30 -18
- package/common/Monitors.d.ts.map +1 -1
- package/common/Monitors.js +45 -80
- package/common/Monitors.js.map +1 -1
- package/common/Singleton.d.ts +7 -1
- package/common/Singleton.d.ts.map +1 -1
- package/common/Singleton.js +24 -11
- package/common/Singleton.js.map +1 -1
- package/common/constants.d.ts +3 -9
- package/common/constants.d.ts.map +1 -1
- package/common/constants.js +3 -14
- package/common/constants.js.map +1 -1
- package/common/events/FinsembleEvent.d.ts +1 -1
- package/common/events/FinsembleEvent.d.ts.map +1 -1
- package/common/redux/getRemoteStore.d.ts +53 -0
- package/common/redux/getRemoteStore.d.ts.map +1 -0
- package/common/redux/getRemoteStore.js +50 -0
- package/common/redux/getRemoteStore.js.map +1 -0
- package/common/redux/remoteReduxEnhancer.d.ts +7 -7
- package/common/redux/remoteReduxEnhancer.d.ts.map +1 -1
- package/common/redux/remoteReduxEnhancer.js +35 -20
- package/common/redux/remoteReduxEnhancer.js.map +1 -1
- package/common/redux/types.d.ts +14 -1
- package/common/redux/types.d.ts.map +1 -1
- package/common/systemManagerClient.d.ts +11 -5
- package/common/systemManagerClient.d.ts.map +1 -1
- package/common/systemManagerClient.js +25 -8
- package/common/systemManagerClient.js.map +1 -1
- package/common/util.d.ts +1 -7
- package/common/util.d.ts.map +1 -1
- package/common/util.js +1 -14
- package/common/util.js.map +1 -1
- package/deprecated/deprecatedFunctions.d.ts +1 -1
- package/deprecated/deprecatedFunctions.d.ts.map +1 -1
- package/deprecated/deprecatedFunctions.js +3 -4
- package/deprecated/deprecatedFunctions.js.map +1 -1
- package/deprecated/deprecatedlauncherClient.d.ts +1 -1
- package/deprecated/deprecatedlauncherClient.d.ts.map +1 -1
- package/deprecated/deprecatedlauncherClient.js.map +1 -1
- package/deprecated/dragAndDropClient.d.ts +4 -3
- package/deprecated/dragAndDropClient.d.ts.map +1 -1
- package/deprecated/dragAndDropClient.js +15 -4
- package/deprecated/dragAndDropClient.js.map +1 -1
- package/deprecated/linkerClient.d.ts +1 -1
- package/deprecated/linkerClient.d.ts.map +1 -1
- package/main.d.ts +289 -171
- package/main.d.ts.map +1 -1
- package/main.js +3 -1
- package/main.js.map +1 -1
- package/package.json +4 -4
- package/platform/services/Interop/modules/types.d.ts +2 -0
- package/platform/services/Interop/modules/types.d.ts.map +1 -1
- package/platform/services/Interop/types.d.ts +24 -2
- package/platform/services/Interop/types.d.ts.map +1 -1
- package/platform/services/Interop/types.js.map +1 -1
- package/platform/services/router/types.d.ts +5 -6
- package/platform/services/router/types.d.ts.map +1 -1
- package/platform/services/systemManager/_constants.d.ts +1 -0
- package/platform/services/systemManager/_constants.d.ts.map +1 -1
- package/platform/services/systemManager/_constants.js +2 -0
- package/platform/services/systemManager/_constants.js.map +1 -1
- package/platform/services/systemManager/types.d.ts +1 -1
- package/platform/services/systemManager/types.d.ts.map +1 -1
- package/platform/services/systemManager/types.js.map +1 -1
- package/platform/services/window/modules/actions.d.ts +68 -0
- package/platform/services/window/modules/actions.d.ts.map +1 -0
- package/platform/services/window/modules/actions.js +60 -0
- package/platform/services/window/modules/actions.js.map +1 -0
- package/platform/services/window/types.d.ts +275 -51
- package/platform/services/window/types.d.ts.map +1 -1
- package/platform/services/workspace/types.d.ts +4 -3
- package/platform/services/workspace/types.d.ts.map +1 -1
- package/react/actions/smartDesktopDesignerActions.d.ts +7 -1
- package/react/actions/smartDesktopDesignerActions.d.ts.map +1 -1
- package/react/actions/smartDesktopDesignerActions.js +3 -0
- package/react/actions/smartDesktopDesignerActions.js.map +1 -1
- package/react/assets/css/core/icons.css +0 -5
- package/react/assets/css/dialogs.css +2 -1
- package/react/assets/css/fonts/icons-reference.html +1 -1
- package/react/assets/css/processMonitor.css +9 -4
- package/react/assets/css/userPreferences.css +1 -1
- package/react/assets/css/windowTitleBar.css +101 -285
- package/react/assets/icons/chevron-down.svg +1 -0
- package/react/assets/icons/chevron-up.svg +1 -0
- package/react/components/appCatalog/AppCatalog.d.ts +3 -0
- package/react/components/appCatalog/AppCatalog.d.ts.map +1 -1
- package/react/components/appCatalog/AppCatalog.js +3 -0
- package/react/components/appCatalog/AppCatalog.js.map +1 -1
- package/react/components/appCatalog/AppCatalogComponent.d.ts +4 -0
- package/react/components/appCatalog/AppCatalogComponent.d.ts.map +1 -1
- package/react/components/appCatalog/AppCatalogComponent.js +6 -2
- package/react/components/appCatalog/AppCatalogComponent.js.map +1 -1
- package/react/components/common/ButtonRow.d.ts.map +1 -1
- package/react/components/common/ButtonRow.js +4 -9
- package/react/components/common/ButtonRow.js.map +1 -1
- package/react/components/common/Checkbox.d.ts +1 -0
- package/react/components/common/Checkbox.d.ts.map +1 -1
- package/react/components/common/Checkbox.js +14 -2
- package/react/components/common/Checkbox.js.map +1 -1
- package/react/components/common/ContextMenu.d.ts.map +1 -1
- package/react/components/common/ContextMenu.js +5 -11
- package/react/components/common/ContextMenu.js.map +1 -1
- package/react/components/common/DropdownButton.d.ts.map +1 -1
- package/react/components/common/DropdownButton.js +11 -24
- package/react/components/common/DropdownButton.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 +6 -4
- package/react/components/common/FinsembleIcon.js.map +1 -1
- package/react/components/common/FinsembleLink.d.ts +7 -0
- package/react/components/common/FinsembleLink.d.ts.map +1 -0
- package/react/components/common/FinsembleLink.js +13 -0
- package/react/components/common/FinsembleLink.js.map +1 -0
- package/react/components/common/Header.d.ts +1 -0
- package/react/components/common/Header.d.ts.map +1 -1
- package/react/components/common/Header.js +4 -2
- package/react/components/common/Header.js.map +1 -1
- package/react/components/common/css/accordion.css +9 -21
- package/react/components/common/css/application-edit-page.css +0 -15
- package/react/components/common/css/application-list.css +54 -23
- package/react/components/common/css/button.css +20 -0
- package/react/components/common/css/selector.css +3 -1
- package/react/components/downloadManager/DownloadManager.d.ts +1 -1
- package/react/components/downloadManager/DownloadManager.d.ts.map +1 -1
- package/react/components/downloadManager/DownloadManager.js +2 -4
- package/react/components/downloadManager/DownloadManager.js.map +1 -1
- package/react/components/fdc3Resolver/ResolverContainer.d.ts +6 -0
- package/react/components/fdc3Resolver/ResolverContainer.d.ts.map +1 -1
- package/react/components/fdc3Resolver/ResolverContainer.js +37 -89
- package/react/components/fdc3Resolver/ResolverContainer.js.map +1 -1
- package/react/components/fdc3Resolver/ResolverDialog.d.ts +10 -1
- package/react/components/fdc3Resolver/ResolverDialog.d.ts.map +1 -1
- package/react/components/fdc3Resolver/ResolverDialog.js +78 -66
- package/react/components/fdc3Resolver/ResolverDialog.js.map +1 -1
- package/react/components/icon/Icon.js +1 -1
- package/react/components/icon/Icon.js.map +1 -1
- package/react/components/legacyControls/FinsembleDialogTextInput.d.ts +1 -1
- package/react/components/legacyControls/FinsembleDialogTextInput.d.ts.map +1 -1
- package/react/components/linker/remoteRedux.d.ts +2 -9
- package/react/components/linker/remoteRedux.d.ts.map +1 -1
- package/react/components/linker/remoteRedux.js +2 -22
- package/react/components/linker/remoteRedux.js.map +1 -1
- package/react/components/notifications/components/shared/IconButton.d.ts +1 -1
- package/react/components/notifications/components/shared/IconButton.d.ts.map +1 -1
- package/react/components/notifications/components/shared/IconButton.js +2 -2
- package/react/components/notifications/components/shared/IconButton.js.map +1 -1
- package/react/components/notifications/components/shared/NotificationCardShell.d.ts +1 -1
- package/react/components/notifications/components/shared/NotificationCardShell.d.ts.map +1 -1
- package/react/components/notifications/components/shared/notificationCard/NotificationCardHeaderControls.d.ts +1 -1
- package/react/components/notifications/components/shared/notificationCard/NotificationCardHeaderControls.d.ts.map +1 -1
- package/react/components/notifications/components/shared/notificationCard/NotificationCardHeaderShell.d.ts +1 -1
- package/react/components/notifications/components/shared/notificationCard/NotificationCardHeaderShell.d.ts.map +1 -1
- package/react/components/notifications/css/notification-center.css +2 -0
- package/react/components/processMonitor/ProcessMonitor.d.ts.map +1 -1
- package/react/components/processMonitor/ProcessMonitor.js +14 -36
- package/react/components/processMonitor/ProcessMonitor.js.map +1 -1
- package/react/components/processMonitor/ProcessMonitorTypes.d.ts +0 -4
- package/react/components/processMonitor/ProcessMonitorTypes.d.ts.map +1 -1
- package/react/components/processMonitor/ProcessMonitorTypes.js +1 -5
- package/react/components/processMonitor/ProcessMonitorTypes.js.map +1 -1
- package/react/components/processMonitor/components/ChildWindow.d.ts +2 -3
- package/react/components/processMonitor/components/ChildWindow.d.ts.map +1 -1
- package/react/components/processMonitor/components/ChildWindow.js +5 -9
- package/react/components/processMonitor/components/ChildWindow.js.map +1 -1
- package/react/components/processMonitor/components/ListHeader.d.ts +1 -5
- package/react/components/processMonitor/components/ListHeader.d.ts.map +1 -1
- package/react/components/processMonitor/components/ListHeader.js +3 -2
- package/react/components/processMonitor/components/ListHeader.js.map +1 -1
- package/react/components/processMonitor/components/Process.d.ts +10 -0
- package/react/components/processMonitor/components/Process.d.ts.map +1 -0
- package/react/components/processMonitor/components/Process.js +11 -0
- package/react/components/processMonitor/components/Process.js.map +1 -0
- package/react/components/processMonitor/components/ProcessStatistics.d.ts +5 -4
- package/react/components/processMonitor/components/ProcessStatistics.d.ts.map +1 -1
- package/react/components/processMonitor/components/ProcessStatistics.js +10 -7
- package/react/components/processMonitor/components/ProcessStatistics.js.map +1 -1
- package/react/components/processMonitor/constants.d.ts +1 -2
- package/react/components/processMonitor/constants.d.ts.map +1 -1
- package/react/components/processMonitor/constants.js +2 -8
- package/react/components/processMonitor/constants.js.map +1 -1
- package/react/components/processMonitor/helpers.d.ts +0 -1
- package/react/components/processMonitor/helpers.d.ts.map +1 -1
- package/react/components/processMonitor/helpers.js +2 -9
- package/react/components/processMonitor/helpers.js.map +1 -1
- package/react/components/processMonitor/stores/ProcessMonitorStore.d.ts +0 -4
- package/react/components/processMonitor/stores/ProcessMonitorStore.d.ts.map +1 -1
- package/react/components/processMonitor/stores/ProcessMonitorStore.js +0 -29
- package/react/components/processMonitor/stores/ProcessMonitorStore.js.map +1 -1
- package/react/components/sdd/Content.d.ts +9 -0
- package/react/components/sdd/Content.d.ts.map +1 -0
- package/react/components/sdd/Content.js +7 -0
- package/react/components/sdd/Content.js.map +1 -0
- package/react/components/sdd/Dashboard.d.ts +20 -0
- package/react/components/sdd/Dashboard.d.ts.map +1 -0
- package/react/components/sdd/Dashboard.js +103 -0
- package/react/components/sdd/Dashboard.js.map +1 -0
- package/react/components/sdd/Export.d.ts +24 -0
- package/react/components/sdd/Export.d.ts.map +1 -0
- package/react/components/sdd/Export.js +133 -0
- package/react/components/sdd/Export.js.map +1 -0
- package/react/components/sdd/ExportCloud.d.ts +7 -0
- package/react/components/sdd/ExportCloud.d.ts.map +1 -0
- package/react/components/sdd/ExportCloud.js +38 -0
- package/react/components/sdd/ExportCloud.js.map +1 -0
- package/react/components/sdd/ExportDeployInfo.d.ts +3 -0
- package/react/components/sdd/ExportDeployInfo.d.ts.map +1 -0
- package/react/components/sdd/ExportDeployInfo.js +18 -0
- package/react/components/sdd/ExportDeployInfo.js.map +1 -0
- package/react/components/sdd/ExportZip.d.ts +7 -0
- package/react/components/sdd/ExportZip.d.ts.map +1 -0
- package/react/components/sdd/ExportZip.js +43 -0
- package/react/components/sdd/ExportZip.js.map +1 -0
- package/react/components/sdd/ProjectErrors.d.ts +12 -0
- package/react/components/sdd/ProjectErrors.d.ts.map +1 -0
- package/react/components/sdd/ProjectErrors.js +26 -0
- package/react/components/sdd/ProjectErrors.js.map +1 -0
- package/react/components/sdd/ProjectMasonry.d.ts +13 -0
- package/react/components/sdd/ProjectMasonry.d.ts.map +1 -0
- package/react/components/sdd/ProjectMasonry.js +22 -0
- package/react/components/sdd/ProjectMasonry.js.map +1 -0
- package/react/components/sdd/Publish.d.ts +9 -0
- package/react/components/sdd/Publish.d.ts.map +1 -0
- package/react/components/sdd/Publish.js +113 -0
- package/react/components/sdd/Publish.js.map +1 -0
- package/react/components/sdd/PublishProgress.d.ts +10 -0
- package/react/components/sdd/PublishProgress.d.ts.map +1 -0
- package/react/components/sdd/PublishProgress.js +24 -0
- package/react/components/sdd/PublishProgress.js.map +1 -0
- package/react/components/sdd/View.d.ts +9 -0
- package/react/components/sdd/View.d.ts.map +1 -0
- package/react/components/sdd/View.js +7 -0
- package/react/components/sdd/View.js.map +1 -0
- package/react/components/sdd/css/addApp.css +62 -8
- package/react/components/sdd/css/appD.css +81 -0
- package/react/components/sdd/css/appDViewer.css +93 -0
- package/react/components/sdd/css/applications.css +53 -15
- package/react/components/sdd/css/exportAppD.css +31 -0
- package/react/components/sdd/css/horizontalScroll.css +9 -0
- package/react/components/sdd/css/project-header.css +2 -1
- package/react/components/sdd/css/views.css +3 -0
- package/react/components/sdd/smartDesktopClient.d.ts +627 -0
- package/react/components/sdd/smartDesktopClient.d.ts.map +1 -0
- package/react/components/sdd/smartDesktopClient.js +1222 -0
- package/react/components/sdd/smartDesktopClient.js.map +1 -0
- package/react/components/sdd/types.d.ts +9 -0
- package/react/components/sdd/types.d.ts.map +1 -0
- package/react/components/sdd/types.js +2 -0
- package/react/components/sdd/types.js.map +1 -0
- package/react/components/search/SearchInput.d.ts +1 -2
- package/react/components/search/SearchInput.d.ts.map +1 -1
- package/react/components/search/SearchInput.js +11 -13
- package/react/components/search/SearchInput.js.map +1 -1
- package/react/components/search/SearchResults.d.ts.map +1 -1
- package/react/components/search/SearchResults.js +6 -6
- package/react/components/search/SearchResults.js.map +1 -1
- package/react/components/shared/openQuitConfirmationDialog.d.ts.map +1 -1
- package/react/components/shared/openQuitConfirmationDialog.js +31 -4
- package/react/components/shared/openQuitConfirmationDialog.js.map +1 -1
- package/react/components/singleInputDialog/SingleInputDialog.d.ts.map +1 -1
- package/react/components/singleInputDialog/SingleInputDialog.js +83 -100
- package/react/components/singleInputDialog/SingleInputDialog.js.map +1 -1
- package/react/components/toolbar/DownloadButton.d.ts +1 -1
- package/react/components/toolbar/DownloadButton.d.ts.map +1 -1
- package/react/components/toolbar/DownloadButton.js +3 -6
- package/react/components/toolbar/DownloadButton.js.map +1 -1
- package/react/components/toolbar/DragHandle.d.ts.map +1 -1
- package/react/components/toolbar/DragHandle.js +8 -5
- package/react/components/toolbar/DragHandle.js.map +1 -1
- package/react/components/toolbar/ToolbarIcon.d.ts.map +1 -1
- package/react/components/toolbar/ToolbarIcon.js +10 -1
- package/react/components/toolbar/ToolbarIcon.js.map +1 -1
- package/react/components/toolbar/ToolbarShell.d.ts +1 -0
- package/react/components/toolbar/ToolbarShell.d.ts.map +1 -1
- package/react/components/toolbar/ToolbarShell.js +3 -2
- package/react/components/toolbar/ToolbarShell.js.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/LeftNavBottomLinks.d.ts.map +1 -1
- package/react/components/toolbar/advancedAppLauncher/components/LeftNavBottomLinks.js +3 -0
- package/react/components/toolbar/advancedAppLauncher/components/LeftNavBottomLinks.js.map +1 -1
- package/react/components/userPreferences/components/content/Workspaces.d.ts +5 -0
- package/react/components/userPreferences/components/content/Workspaces.d.ts.map +1 -1
- package/react/components/userPreferences/components/content/Workspaces.js +14 -1
- package/react/components/userPreferences/components/content/Workspaces.js.map +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourceTypes.d.ts.map +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourceTypes.js +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourceTypes.js.map +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourcesPreferences.d.ts.map +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourcesPreferences.js +1 -1
- package/react/components/userPreferences/components/content/notificationViews/NotificationsSourcesPreferences.js.map +1 -1
- package/react/components/utils.d.ts +50 -0
- package/react/components/utils.d.ts.map +1 -0
- package/react/components/utils.js +60 -0
- package/react/components/utils.js.map +1 -0
- package/react/components/windowTitleBar/AlwaysOnTopButton.d.ts +9 -0
- package/react/components/windowTitleBar/AlwaysOnTopButton.d.ts.map +1 -0
- package/react/components/windowTitleBar/AlwaysOnTopButton.js +29 -0
- package/react/components/windowTitleBar/AlwaysOnTopButton.js.map +1 -0
- package/react/components/windowTitleBar/CloseButton.d.ts.map +1 -0
- package/react/components/windowTitleBar/CloseButton.js +22 -0
- package/react/components/windowTitleBar/CloseButton.js.map +1 -0
- package/react/components/windowTitleBar/GroupingButton.d.ts +3 -0
- package/react/components/windowTitleBar/GroupingButton.d.ts.map +1 -0
- package/react/components/windowTitleBar/GroupingButton.js +25 -0
- package/react/components/windowTitleBar/GroupingButton.js.map +1 -0
- package/react/components/windowTitleBar/LinkerButton.d.ts.map +1 -0
- package/react/components/windowTitleBar/{components/left/LinkerButton.js → LinkerButton.js} +4 -4
- package/react/components/windowTitleBar/LinkerButton.js.map +1 -0
- package/react/components/windowTitleBar/LinkerButtonDeprecated.d.ts +11 -0
- package/react/components/windowTitleBar/LinkerButtonDeprecated.d.ts.map +1 -0
- package/react/components/windowTitleBar/LinkerButtonDeprecated.js +63 -0
- package/react/components/windowTitleBar/LinkerButtonDeprecated.js.map +1 -0
- package/react/components/windowTitleBar/LinkerGroups.d.ts.map +1 -0
- package/react/components/windowTitleBar/{components/left/LinkerGroups.js → LinkerGroups.js} +2 -3
- package/react/components/windowTitleBar/LinkerGroups.js.map +1 -0
- package/react/components/windowTitleBar/LinkerGroupsDeprecated.d.ts +7 -0
- package/react/components/windowTitleBar/LinkerGroupsDeprecated.d.ts.map +1 -0
- package/react/components/windowTitleBar/LinkerGroupsDeprecated.js +35 -0
- package/react/components/windowTitleBar/LinkerGroupsDeprecated.js.map +1 -0
- package/react/components/windowTitleBar/MaximizeButton.d.ts +3 -0
- package/react/components/windowTitleBar/MaximizeButton.d.ts.map +1 -0
- package/react/components/windowTitleBar/MaximizeButton.js +18 -0
- package/react/components/windowTitleBar/MaximizeButton.js.map +1 -0
- package/react/components/windowTitleBar/MinimizeButton.d.ts +3 -0
- package/react/components/windowTitleBar/MinimizeButton.d.ts.map +1 -0
- package/react/components/windowTitleBar/MinimizeButton.js +21 -0
- package/react/components/windowTitleBar/MinimizeButton.js.map +1 -0
- package/react/components/windowTitleBar/ShareButton.d.ts +3 -0
- package/react/components/windowTitleBar/ShareButton.d.ts.map +1 -0
- package/react/components/windowTitleBar/ShareButton.js +24 -0
- package/react/components/windowTitleBar/ShareButton.js.map +1 -0
- package/react/components/windowTitleBar/TabRegion.d.ts +7 -0
- package/react/components/windowTitleBar/TabRegion.d.ts.map +1 -0
- package/react/components/windowTitleBar/TabRegion.js +479 -0
- package/react/components/windowTitleBar/TabRegion.js.map +1 -0
- package/react/components/windowTitleBar/TabTitle.d.ts +8 -0
- package/react/components/windowTitleBar/TabTitle.d.ts.map +1 -0
- package/react/components/windowTitleBar/TabTitle.js +17 -0
- package/react/components/windowTitleBar/TabTitle.js.map +1 -0
- package/react/components/windowTitleBar/TitleEdit.d.ts +10 -0
- package/react/components/windowTitleBar/TitleEdit.d.ts.map +1 -0
- package/react/components/windowTitleBar/TitleEdit.js +30 -0
- package/react/components/windowTitleBar/TitleEdit.js.map +1 -0
- package/react/components/windowTitleBar/WindowTitleBarContext.d.ts +12 -0
- package/react/components/windowTitleBar/WindowTitleBarContext.d.ts.map +1 -0
- package/react/components/windowTitleBar/WindowTitleBarContext.js +3 -0
- package/react/components/windowTitleBar/WindowTitleBarContext.js.map +1 -0
- package/react/components/windowTitleBar/WindowTitleBarShell.d.ts +14 -272
- package/react/components/windowTitleBar/WindowTitleBarShell.d.ts.map +1 -1
- package/react/components/windowTitleBar/WindowTitleBarShell.js +41 -929
- package/react/components/windowTitleBar/WindowTitleBarShell.js.map +1 -1
- package/react/components/windowTitleBar/index.d.ts +9 -8
- package/react/components/windowTitleBar/index.d.ts.map +1 -1
- package/react/components/windowTitleBar/index.js +9 -8
- package/react/components/windowTitleBar/index.js.map +1 -1
- package/react/components/windowTitleBar/useKeyboardNavigation.d.ts +7 -0
- package/react/components/windowTitleBar/useKeyboardNavigation.d.ts.map +1 -0
- package/react/components/windowTitleBar/useKeyboardNavigation.js +57 -0
- package/react/components/windowTitleBar/useKeyboardNavigation.js.map +1 -0
- package/react/components/windowTitleBar/useMaximize.d.ts +5 -0
- package/react/components/windowTitleBar/useMaximize.d.ts.map +1 -0
- package/react/components/windowTitleBar/useMaximize.js +23 -0
- package/react/components/windowTitleBar/useMaximize.js.map +1 -0
- package/react/components/yesNoDialog/timer.js +2 -1
- package/react/components/yesNoDialog/timer.js.map +1 -1
- package/react/hooks/useDashbar.d.ts.map +1 -1
- package/react/hooks/useDashbar.js.map +1 -1
- package/react/hooks/useDragRegion.d.ts +27 -0
- package/react/hooks/useDragRegion.d.ts.map +1 -0
- package/react/hooks/useDragRegion.js +74 -0
- package/react/hooks/useDragRegion.js.map +1 -0
- package/react/hooks/useInjectedTitleBar.d.ts +3 -0
- package/react/hooks/useInjectedTitleBar.d.ts.map +1 -0
- package/react/hooks/useInjectedTitleBar.js +437 -0
- package/react/hooks/useInjectedTitleBar.js.map +1 -0
- package/react/hooks/useNotifications.d.ts +1 -1
- package/react/hooks/useToolbar.d.ts +1 -0
- package/react/hooks/useToolbar.d.ts.map +1 -1
- package/react/hooks/useToolbar.js +13 -3
- package/react/hooks/useToolbar.js.map +1 -1
- package/react/reducers/rootReducer.d.ts +12 -0
- package/react/reducers/rootReducer.d.ts.map +1 -1
- package/react/reducers/smartDesktopDesignerReducer.d.ts.map +1 -1
- package/react/reducers/smartDesktopDesignerReducer.js +12 -0
- package/react/reducers/smartDesktopDesignerReducer.js.map +1 -1
- package/react/store.d.ts +24 -0
- package/react/store.d.ts.map +1 -1
- package/react/types/smartDesktopDesignerTypes.d.ts +42 -1
- package/react/types/smartDesktopDesignerTypes.d.ts.map +1 -1
- package/react/types/smartDesktopDesignerTypes.js.map +1 -1
- package/typedefs/FDC3/api/AppMetadata.d.ts +1 -0
- package/typedefs/FDC3/api/AppMetadata.d.ts.map +1 -1
- package/typedoc-types.d.ts +9 -0
- package/typedoc-types.d.ts.map +1 -0
- package/typedoc-types.js +6 -0
- package/typedoc-types.js.map +1 -0
- package/types.d.ts +5 -11
- package/types.d.ts.map +1 -1
- package/types.js +2 -0
- package/types.js.map +1 -1
- package/common/events/PrivateEventManager.d.ts +0 -95
- package/common/events/PrivateEventManager.d.ts.map +0 -1
- package/common/events/PrivateEventManager.js +0 -295
- package/common/events/PrivateEventManager.js.map +0 -1
- package/common/events/PrivateFinsembleEvent.d.ts +0 -30
- package/common/events/PrivateFinsembleEvent.d.ts.map +0 -1
- package/common/events/PrivateFinsembleEvent.js +0 -65
- package/common/events/PrivateFinsembleEvent.js.map +0 -1
- package/common/redux/createReducer.d.ts +0 -128
- package/common/redux/createReducer.d.ts.map +0 -1
- package/common/redux/createReducer.js +0 -298
- package/common/redux/createReducer.js.map +0 -1
- package/common/redux/index.d.ts +0 -3
- package/common/redux/index.d.ts.map +0 -1
- package/common/redux/index.js +0 -3
- package/common/redux/index.js.map +0 -1
- package/platform/services/window/Common/Pools/ObjectPool.d.ts +0 -11
- package/platform/services/window/Common/Pools/ObjectPool.d.ts.map +0 -1
- package/platform/services/window/Common/Pools/ObjectPool.js +0 -43
- package/platform/services/window/Common/Pools/ObjectPool.js.map +0 -1
- package/platform/services/window/Common/Pools/PoolSingletons.d.ts +0 -10
- package/platform/services/window/Common/Pools/PoolSingletons.d.ts.map +0 -1
- package/platform/services/window/Common/Pools/PoolSingletons.js +0 -10
- package/platform/services/window/Common/Pools/PoolSingletons.js.map +0 -1
- package/platform/services/window/Common/Pools/WindowPool.d.ts +0 -7
- package/platform/services/window/Common/Pools/WindowPool.d.ts.map +0 -1
- package/platform/services/window/Common/Pools/WindowPool.js +0 -16
- package/platform/services/window/Common/Pools/WindowPool.js.map +0 -1
- package/platform/services/window/Docking/boxMath.d.ts +0 -144
- package/platform/services/window/Docking/boxMath.d.ts.map +0 -1
- package/platform/services/window/Docking/boxMath.js +0 -511
- package/platform/services/window/Docking/boxMath.js.map +0 -1
- package/platform/services/window/Docking/constants.d.ts +0 -29
- package/platform/services/window/Docking/constants.d.ts.map +0 -1
- package/platform/services/window/Docking/constants.js +0 -29
- package/platform/services/window/Docking/constants.js.map +0 -1
- package/platform/services/window/Docking/dockableBox.d.ts +0 -117
- package/platform/services/window/Docking/dockableBox.d.ts.map +0 -1
- package/platform/services/window/Docking/dockableBox.js +0 -525
- package/platform/services/window/Docking/dockableBox.js.map +0 -1
- package/platform/services/window/Docking/dockableGroup.d.ts +0 -252
- package/platform/services/window/Docking/dockableGroup.d.ts.map +0 -1
- package/platform/services/window/Docking/dockableGroup.js +0 -1054
- package/platform/services/window/Docking/dockableGroup.js.map +0 -1
- package/platform/services/window/Docking/dockableMonitor.d.ts +0 -99
- package/platform/services/window/Docking/dockableMonitor.d.ts.map +0 -1
- package/platform/services/window/Docking/dockableMonitor.js +0 -427
- package/platform/services/window/Docking/dockableMonitor.js.map +0 -1
- package/platform/services/window/Docking/dockableWindow.d.ts +0 -272
- package/platform/services/window/Docking/dockableWindow.d.ts.map +0 -1
- package/platform/services/window/Docking/dockableWindow.js +0 -1239
- package/platform/services/window/Docking/dockableWindow.js.map +0 -1
- package/platform/services/window/Docking/dockingCalculator.d.ts +0 -741
- package/platform/services/window/Docking/dockingCalculator.d.ts.map +0 -1
- package/platform/services/window/Docking/dockingCalculator.js +0 -3438
- package/platform/services/window/Docking/dockingCalculator.js.map +0 -1
- package/platform/services/window/Docking/dockingMain.d.ts +0 -349
- package/platform/services/window/Docking/dockingMain.d.ts.map +0 -1
- package/platform/services/window/Docking/dockingMain.js +0 -2541
- package/platform/services/window/Docking/dockingMain.js.map +0 -1
- package/platform/services/window/Docking/maskBoundsCalculator.d.ts +0 -28
- package/platform/services/window/Docking/maskBoundsCalculator.d.ts.map +0 -1
- package/platform/services/window/Docking/maskBoundsCalculator.js +0 -67
- package/platform/services/window/Docking/maskBoundsCalculator.js.map +0 -1
- package/platform/services/window/Docking/monitorUpdateHandler.d.ts +0 -32
- package/platform/services/window/Docking/monitorUpdateHandler.d.ts.map +0 -1
- package/platform/services/window/Docking/monitorUpdateHandler.js +0 -117
- package/platform/services/window/Docking/monitorUpdateHandler.js.map +0 -1
- package/platform/services/window/Docking/types.d.ts +0 -334
- package/platform/services/window/Docking/types.d.ts.map +0 -1
- package/platform/services/window/Docking/types.js +0 -12
- package/platform/services/window/Docking/types.js.map +0 -1
- package/platform/services/window/MultiWindowFeatures/autoArrange.d.ts +0 -90
- package/platform/services/window/MultiWindowFeatures/autoArrange.d.ts.map +0 -1
- package/platform/services/window/MultiWindowFeatures/autoArrange.js +0 -510
- package/platform/services/window/MultiWindowFeatures/autoArrange.js.map +0 -1
- package/platform/services/window/StackedWindowManager/stackedWindowManager.d.ts +0 -411
- package/platform/services/window/StackedWindowManager/stackedWindowManager.d.ts.map +0 -1
- package/platform/services/window/StackedWindowManager/stackedWindowManager.js +0 -1641
- package/platform/services/window/StackedWindowManager/stackedWindowManager.js.map +0 -1
- package/platform/services/window/WindowAbstractions/BaseWindow.d.ts +0 -469
- package/platform/services/window/WindowAbstractions/BaseWindow.d.ts.map +0 -1
- package/platform/services/window/WindowAbstractions/BaseWindow.js +0 -1347
- package/platform/services/window/WindowAbstractions/BaseWindow.js.map +0 -1
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.d.ts +0 -9
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.d.ts.map +0 -1
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.js +0 -23
- package/platform/services/window/WindowAbstractions/FinsembleWindowInternal.js.map +0 -1
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.d.ts +0 -227
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.d.ts.map +0 -1
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.js +0 -1168
- package/platform/services/window/WindowAbstractions/WebWindowWrapper.js.map +0 -1
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.d.ts +0 -121
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.d.ts.map +0 -1
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.js +0 -591
- package/platform/services/window/WindowAbstractions/externalWindowWrapper.js.map +0 -1
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.d.ts +0 -194
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.d.ts.map +0 -1
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.js +0 -680
- package/platform/services/window/WindowAbstractions/stackedWindowWrapper.js.map +0 -1
- package/platform/services/window/windowGroup.d.ts +0 -86
- package/platform/services/window/windowGroup.d.ts.map +0 -1
- package/platform/services/window/windowGroup.js +0 -323
- package/platform/services/window/windowGroup.js.map +0 -1
- package/platform/services/workspace/windowStorageManager.d.ts +0 -180
- package/platform/services/workspace/windowStorageManager.d.ts.map +0 -1
- package/platform/services/workspace/windowStorageManager.js +0 -195
- package/platform/services/workspace/windowStorageManager.js.map +0 -1
- package/react/assets/icons/question-circle.svg +0 -6
- package/react/components/legacyControls/FinsembleHoverDetector.d.ts +0 -23
- package/react/components/legacyControls/FinsembleHoverDetector.d.ts.map +0 -1
- package/react/components/legacyControls/FinsembleHoverDetector.js +0 -57
- package/react/components/legacyControls/FinsembleHoverDetector.js.map +0 -1
- package/react/components/sdd/Appearance.helpers.d.ts +0 -2
- package/react/components/sdd/Appearance.helpers.d.ts.map +0 -1
- package/react/components/sdd/Appearance.helpers.js +0 -2
- package/react/components/sdd/Appearance.helpers.js.map +0 -1
- package/react/components/shared/linkerUtil.d.ts +0 -4
- package/react/components/shared/linkerUtil.d.ts.map +0 -1
- package/react/components/shared/linkerUtil.js +0 -10
- package/react/components/shared/linkerUtil.js.map +0 -1
- package/react/components/windowTitleBar/components/center/Tab.d.ts +0 -31
- package/react/components/windowTitleBar/components/center/Tab.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/center/Tab.js +0 -58
- package/react/components/windowTitleBar/components/center/Tab.js.map +0 -1
- package/react/components/windowTitleBar/components/center/TabList.d.ts +0 -138
- package/react/components/windowTitleBar/components/center/TabList.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/center/TabList.js +0 -614
- package/react/components/windowTitleBar/components/center/TabList.js.map +0 -1
- package/react/components/windowTitleBar/components/center/TabRegion.d.ts +0 -3
- package/react/components/windowTitleBar/components/center/TabRegion.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/center/TabRegion.js +0 -13
- package/react/components/windowTitleBar/components/center/TabRegion.js.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerButton.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerButton.js.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerButtonDeprecated.d.ts +0 -85
- package/react/components/windowTitleBar/components/left/LinkerButtonDeprecated.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerButtonDeprecated.js +0 -172
- package/react/components/windowTitleBar/components/left/LinkerButtonDeprecated.js.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerGroups.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerGroups.js.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerGroupsDeprecated.d.ts +0 -50
- package/react/components/windowTitleBar/components/left/LinkerGroupsDeprecated.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/left/LinkerGroupsDeprecated.js +0 -120
- package/react/components/windowTitleBar/components/left/LinkerGroupsDeprecated.js.map +0 -1
- package/react/components/windowTitleBar/components/left/ShareButton.d.ts +0 -42
- package/react/components/windowTitleBar/components/left/ShareButton.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/left/ShareButton.js +0 -82
- package/react/components/windowTitleBar/components/left/ShareButton.js.map +0 -1
- package/react/components/windowTitleBar/components/right/AlwaysOnTopButton.d.ts +0 -3
- package/react/components/windowTitleBar/components/right/AlwaysOnTopButton.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/right/AlwaysOnTopButton.js +0 -15
- package/react/components/windowTitleBar/components/right/AlwaysOnTopButton.js.map +0 -1
- package/react/components/windowTitleBar/components/right/CloseButton.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/right/CloseButton.js +0 -16
- package/react/components/windowTitleBar/components/right/CloseButton.js.map +0 -1
- package/react/components/windowTitleBar/components/right/GroupingButton.d.ts +0 -50
- package/react/components/windowTitleBar/components/right/GroupingButton.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/right/GroupingButton.js +0 -82
- package/react/components/windowTitleBar/components/right/GroupingButton.js.map +0 -1
- package/react/components/windowTitleBar/components/right/MaximizeButton.d.ts +0 -59
- package/react/components/windowTitleBar/components/right/MaximizeButton.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/right/MaximizeButton.js +0 -96
- package/react/components/windowTitleBar/components/right/MaximizeButton.js.map +0 -1
- package/react/components/windowTitleBar/components/right/MinimizeButton.d.ts +0 -26
- package/react/components/windowTitleBar/components/right/MinimizeButton.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/right/MinimizeButton.js +0 -32
- package/react/components/windowTitleBar/components/right/MinimizeButton.js.map +0 -1
- package/react/components/windowTitleBar/components/windowTitle.d.ts +0 -67
- package/react/components/windowTitleBar/components/windowTitle.d.ts.map +0 -1
- package/react/components/windowTitleBar/components/windowTitle.js +0 -382
- package/react/components/windowTitleBar/components/windowTitle.js.map +0 -1
- package/react/components/windowTitleBar/stores/windowTitleBarStore.d.ts +0 -69
- package/react/components/windowTitleBar/stores/windowTitleBarStore.d.ts.map +0 -1
- package/react/components/windowTitleBar/stores/windowTitleBarStore.js +0 -610
- package/react/components/windowTitleBar/stores/windowTitleBarStore.js.map +0 -1
- package/react/components/windowTitleBar/stores/windowTitleBarStoreDefaults.d.ts +0 -44
- package/react/components/windowTitleBar/stores/windowTitleBarStoreDefaults.d.ts.map +0 -1
- package/react/components/windowTitleBar/stores/windowTitleBarStoreDefaults.js +0 -43
- package/react/components/windowTitleBar/stores/windowTitleBarStoreDefaults.js.map +0 -1
- package/react/components/windowTitleBar/windowTitleBarContext.d.ts +0 -23
- package/react/components/windowTitleBar/windowTitleBarContext.d.ts.map +0 -1
- package/react/components/windowTitleBar/windowTitleBarContext.js +0 -22
- package/react/components/windowTitleBar/windowTitleBarContext.js.map +0 -1
- package/react/types/windowTitleBar.d.ts +0 -49
- package/react/types/windowTitleBar.d.ts.map +0 -1
- package/react/types/windowTitleBar.js +0 -2
- package/react/types/windowTitleBar.js.map +0 -1
- /package/react/components/windowTitleBar/{components/right/CloseButton.d.ts → CloseButton.d.ts} +0 -0
- /package/react/components/windowTitleBar/{components/left/LinkerButton.d.ts → LinkerButton.d.ts} +0 -0
- /package/react/components/windowTitleBar/{components/left/LinkerGroups.d.ts → LinkerGroups.d.ts} +0 -0
|
@@ -1,3438 +0,0 @@
|
|
|
1
|
-
import { queue } from "async";
|
|
2
|
-
import DockableGroup from "./dockableGroup";
|
|
3
|
-
import DockableBox from "./dockableBox";
|
|
4
|
-
import BoxMath from "./boxMath";
|
|
5
|
-
import { mousePosToBounds, mouseDown } from "./maskBoundsCalculator";
|
|
6
|
-
import { MonitorPoolSingleton, GroupPoolSingleton, DockingPoolSingleton } from "../Common/Pools/PoolSingletons";
|
|
7
|
-
import { fastClone, checkIfBoundsAreEqual } from "../../../../common/util";
|
|
8
|
-
import { CORNERS, OPPOSITE_EDGE_MAP } from "./constants";
|
|
9
|
-
import { WINDOWSTATE } from "../../../../common/constants";
|
|
10
|
-
import { adjustBoundsToBeOnMonitor, getBoundsWhenMovedOffDockedWindow, getMonitorByBounds, getMonitorFromScaledXY, } from "../../../../common/Monitors";
|
|
11
|
-
import { Logger } from "../../../../clients/logger";
|
|
12
|
-
import { RouterClient } from "../../../../clients/routerClient";
|
|
13
|
-
import uuidv4 from "uuid-random";
|
|
14
|
-
let MINIMUM_HEIGHT;
|
|
15
|
-
let MINIMUM_WIDTH;
|
|
16
|
-
let ALLOW_GROUPS_TO_SNAP;
|
|
17
|
-
let SNAPPING_OPACITY = 0.8;
|
|
18
|
-
/**
|
|
19
|
-
* The pools are just the collection of windows that the DockingCalculator is concerned with
|
|
20
|
-
*/
|
|
21
|
-
const groupPool = GroupPoolSingleton;
|
|
22
|
-
// Stationary and moving window are cached onMouseDown and cleared onMouseUp.
|
|
23
|
-
let globalStationaryWindow = null;
|
|
24
|
-
// Windows to ignore for grouping functions (e.g., toolbar - it can snap, but shouldn't group)
|
|
25
|
-
const groupBlacklist = [];
|
|
26
|
-
// Changing the taskbar icon has a single entry point that requires
|
|
27
|
-
// a reason in order to hide or show the taskbar icon.
|
|
28
|
-
// these are the valid reasons to do so.
|
|
29
|
-
const TASKBAR_ICON_CHANGE_REASONS = {
|
|
30
|
-
IS_MOVE_ANCHOR: "Window is in a movable group and is the move anchor.",
|
|
31
|
-
MOVABLE_GROUP_BEING_DESTROYED: "Window is in a movable group that's being destroyed.",
|
|
32
|
-
NOT_MOVE_ANCHOR: "Window is in a movable group and is NOT the move anchor.",
|
|
33
|
-
LEAVING_MOVABLE_GROUP: "Window is leaving a movable group.",
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Expands BoxCoordinates to the requested width/height, keeping the requested edge fixed.
|
|
37
|
-
*/
|
|
38
|
-
const expandBoundsAgainstFixedEdge = (bounds, edge) => {
|
|
39
|
-
var _a, _b;
|
|
40
|
-
const width = (_a = bounds.width) !== null && _a !== void 0 ? _a : 0;
|
|
41
|
-
const height = (_b = bounds.height) !== null && _b !== void 0 ? _b : 0;
|
|
42
|
-
if (edge === "left")
|
|
43
|
-
bounds.right = bounds.left + width;
|
|
44
|
-
if (edge === "right")
|
|
45
|
-
bounds.left = bounds.right - width;
|
|
46
|
-
if (edge === "top")
|
|
47
|
-
bounds.bottom = bounds.top + height;
|
|
48
|
-
if (edge === "bottom")
|
|
49
|
-
bounds.top = bounds.bottom - height;
|
|
50
|
-
};
|
|
51
|
-
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* @returns
|
|
55
|
-
*/
|
|
56
|
-
class DockingCalculator {
|
|
57
|
-
constructor(monitorsInstance) {
|
|
58
|
-
// This allows us to defer adding windows/removing windows from a group until onMouseDown. It's modified onMouseMove.
|
|
59
|
-
this.groupAction = {
|
|
60
|
-
name: null,
|
|
61
|
-
windows: [],
|
|
62
|
-
};
|
|
63
|
-
//win?: FSBLWindow;
|
|
64
|
-
//monitorDockablePositions: MonitorDockablePositions = {};
|
|
65
|
-
//dockingOptions: DockingConfigOptions = {};
|
|
66
|
-
//dockedPosition: number | undefined;
|
|
67
|
-
//ignoreSnappingRequests: boolean = false;
|
|
68
|
-
//undockedPosition!: DockedDimensions;
|
|
69
|
-
//primaryMonitor?: MonitorInfoDetail;
|
|
70
|
-
//isHidden: boolean = false;
|
|
71
|
-
//dockedParams: DockingConfigOptions = {};
|
|
72
|
-
//dockedHeight: number = 0;
|
|
73
|
-
//snappedEdge: string = "left";
|
|
74
|
-
//monitor?: DockableMonitor;
|
|
75
|
-
//onboundschanged: number = 0;
|
|
76
|
-
//previouslySnappedEdge?: boolean;
|
|
77
|
-
//dockedBounds?: DockingBounds;
|
|
78
|
-
//justDocked?: boolean;
|
|
79
|
-
//vertices: Record<string, Vertex> = {};
|
|
80
|
-
this.groups = [];
|
|
81
|
-
// object that's created onMouseDown. Used to cache potentially expensive operations and common information needed across functions.
|
|
82
|
-
this.resizeObject = {};
|
|
83
|
-
this.groupMode = {
|
|
84
|
-
enabled: true,
|
|
85
|
-
};
|
|
86
|
-
this.groupMask = null;
|
|
87
|
-
// Placeholder for the moveRequest.
|
|
88
|
-
this.moveRequest = null;
|
|
89
|
-
//stationaryWindow: DockableWindow | null = null;
|
|
90
|
-
this.movingWindow = null;
|
|
91
|
-
this.bufferSize = 15;
|
|
92
|
-
this.resizeEventThrottlePeriod = 0;
|
|
93
|
-
this.moveCount = 0;
|
|
94
|
-
this.intersection = null;
|
|
95
|
-
// The group mask operations are asynchronous and take a variable amount of time. Generally speaking, show takes longer to complete than hide. So if you call show, and 4ms later call hide, you can finish hiding the group mask before the show has completed. This boolean tells the calculator whether the mask should be hidden or shown. Before calling .show or .hide, we check to see if the last function called matches. So if we expect the mask to be hidden, but we're about to call .show, we exit early.
|
|
96
|
-
this.groupMaskExpectedState = "hidden";
|
|
97
|
-
this.shiftKey = false;
|
|
98
|
-
this.movingGroup = null;
|
|
99
|
-
this.groupMaskIsVisible = false;
|
|
100
|
-
this.movingAGroupOfWindows = false;
|
|
101
|
-
this.groupTileBuffer = 0;
|
|
102
|
-
this.headerHeight = 40;
|
|
103
|
-
this.enableWindowsAeroSnap = false;
|
|
104
|
-
this.claimSpace = false;
|
|
105
|
-
this.preventOverlapClaimSpace = false;
|
|
106
|
-
this.persistedOpacity = {};
|
|
107
|
-
this.monitorsInstance = monitorsInstance;
|
|
108
|
-
this.groupMaskQueue = queue((task, callback) => {
|
|
109
|
-
task(callback);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
// Overridden by DockingMain
|
|
113
|
-
updateGroupData() { }
|
|
114
|
-
setBoundsErrorCB(err) {
|
|
115
|
-
Logger.system.error(err);
|
|
116
|
-
}
|
|
117
|
-
removeUserRequestFromGroup(userRequest) {
|
|
118
|
-
var _a;
|
|
119
|
-
// Remove from group and move
|
|
120
|
-
const groupNames = fastClone((_a = userRequest.groupNames) !== null && _a !== void 0 ? _a : []);
|
|
121
|
-
groupNames.forEach((groupName) => {
|
|
122
|
-
this.removeWindowFromGroup(userRequest.name, groupName);
|
|
123
|
-
this.wipeSnapRelationships(userRequest.name);
|
|
124
|
-
});
|
|
125
|
-
this.updateGroupData();
|
|
126
|
-
userRequest.groupName = null;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 5/20/19 Joe: Previously group was not set sometimes. In the event that the maximize request comes
|
|
130
|
-
* into a window that is a group, this will throw an error.
|
|
131
|
-
*/
|
|
132
|
-
ensureMovingGroupIsSet(moveRequest) {
|
|
133
|
-
// We reset the moving group in here in cases some request details
|
|
134
|
-
// have changed since last time we've set it
|
|
135
|
-
this.movingGroup = this.getMovingGroup(moveRequest);
|
|
136
|
-
/**
|
|
137
|
-
* 6/5/19 Joe: If the moving window is in a group (movingGroup is defined)
|
|
138
|
-
* and any windows in the group that aren't the moving window are maximized
|
|
139
|
-
* then restore them.
|
|
140
|
-
*/
|
|
141
|
-
if (this.movingGroup) {
|
|
142
|
-
Object.keys(this.movingGroup.windows).forEach((windowName) => {
|
|
143
|
-
var _a;
|
|
144
|
-
const movingWin = (_a = this.movingGroup) === null || _a === void 0 ? void 0 : _a.windows[windowName];
|
|
145
|
-
if (movingWin &&
|
|
146
|
-
this.isDockableWindowMaximized(movingWin) &&
|
|
147
|
-
this.movingWindow &&
|
|
148
|
-
movingWin.name !== this.movingWindow.name) {
|
|
149
|
-
movingWin.restore();
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
ensureNotOffMonitor(movingWindow) {
|
|
155
|
-
const currentBounds = {
|
|
156
|
-
top: movingWindow.top,
|
|
157
|
-
bottom: movingWindow.bottom,
|
|
158
|
-
left: movingWindow.left,
|
|
159
|
-
right: movingWindow.right,
|
|
160
|
-
width: movingWindow.width,
|
|
161
|
-
height: movingWindow.height,
|
|
162
|
-
name: movingWindow.name,
|
|
163
|
-
};
|
|
164
|
-
const newBounds = adjustBoundsToBeOnMonitor(this.monitorsInstance, currentBounds);
|
|
165
|
-
if (newBounds.top !== currentBounds.top || newBounds.left !== currentBounds.left) {
|
|
166
|
-
Logger.system.debug("Dockable component was dropped outside of a monitor. Finsemble pushed it back onto monitor. Requested position:", currentBounds, ". Actual position:", newBounds);
|
|
167
|
-
this.moveWindow(newBounds);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Check if the window or group being dropped is overlapping a docked window (currently only the toolbar).
|
|
172
|
-
* If so, move it directly adjacent to the docked window.
|
|
173
|
-
* @param movingWindow
|
|
174
|
-
* @param dockedWindowPosition - "edge"
|
|
175
|
-
*/
|
|
176
|
-
async ensureNotOverlappingDockedWindow(movingWindow, dockedWindowPosition) {
|
|
177
|
-
var _a;
|
|
178
|
-
const currentBounds = {
|
|
179
|
-
top: movingWindow.top,
|
|
180
|
-
bottom: movingWindow.bottom,
|
|
181
|
-
left: movingWindow.left,
|
|
182
|
-
right: movingWindow.right,
|
|
183
|
-
width: movingWindow.width,
|
|
184
|
-
height: movingWindow.height,
|
|
185
|
-
name: movingWindow.name,
|
|
186
|
-
};
|
|
187
|
-
// Use the top two corners of the window to determine which monitor to use for the check. If the top of the window is straddling
|
|
188
|
-
// two monitors, we want to check the monitor that is shared with the docked toolbar.
|
|
189
|
-
const topLeftMonitor = await getMonitorFromScaledXY(currentBounds.left, currentBounds.top);
|
|
190
|
-
const topRightMonitor = await getMonitorFromScaledXY(currentBounds.right, currentBounds.top);
|
|
191
|
-
const sharedMonitors = [topLeftMonitor, topRightMonitor].filter((monitor) => (monitor === null || monitor === void 0 ? void 0 : monitor.name) === dockedWindowPosition.monitorName);
|
|
192
|
-
// Neither top corner is on the same monitor as the docked toolbar, no need to check
|
|
193
|
-
if (sharedMonitors.length === 0) {
|
|
194
|
-
return currentBounds;
|
|
195
|
-
}
|
|
196
|
-
const monitorToCheck = sharedMonitors[0];
|
|
197
|
-
// calculate the new location of the window if it needs to move
|
|
198
|
-
const { shouldMove, newBounds } = getBoundsWhenMovedOffDockedWindow((_a = monitorToCheck === null || monitorToCheck === void 0 ? void 0 : monitorToCheck.rawMonitor) !== null && _a !== void 0 ? _a : monitorToCheck, currentBounds, dockedWindowPosition.edge);
|
|
199
|
-
if (shouldMove) {
|
|
200
|
-
Logger.system.debug("Dockable component was dropped overlapping docked window. Finsemble moved it adjacent to the docked window. Requested position:", currentBounds, ". Actual position:", newBounds);
|
|
201
|
-
const group = this.getMovableGroup(movingWindow.name);
|
|
202
|
-
if (group) {
|
|
203
|
-
const sourceMoveRequest = {
|
|
204
|
-
name: movingWindow.name,
|
|
205
|
-
changeType: 0,
|
|
206
|
-
};
|
|
207
|
-
Object.assign(sourceMoveRequest, newBounds);
|
|
208
|
-
this.requestMove(sourceMoveRequest, () => {
|
|
209
|
-
group.updateBounds();
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
this.moveWindow(newBounds);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
endMovingGroup(group) {
|
|
218
|
-
this.resizeObject = this.correctResizeObject(this.movingWindow, this.resizeObject);
|
|
219
|
-
if (this.groupMask && this.resizeObject.handle)
|
|
220
|
-
group.scale(this.groupMask.getBounds(), this.resizeObject.handle, this);
|
|
221
|
-
this.hideGroupMask();
|
|
222
|
-
const groupIter = this.groupWindowIterator(group);
|
|
223
|
-
for (const win of groupIter) {
|
|
224
|
-
win.show();
|
|
225
|
-
}
|
|
226
|
-
this.movingAGroupOfWindows = false;
|
|
227
|
-
}
|
|
228
|
-
maybeMakeOrBreakGroups(systemMoved) {
|
|
229
|
-
let dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
230
|
-
for (const win of dockingPoolIterator) {
|
|
231
|
-
// Only break and remake the groups if a user initiated the move action. If the OS moved the group, there is no reason to break it
|
|
232
|
-
if (!systemMoved) {
|
|
233
|
-
this.buildSnapRelationships(win);
|
|
234
|
-
if (win.snappedWindows.length === 0 && win.groupNames.length) {
|
|
235
|
-
this.removeWindowFromAllGroups(win);
|
|
236
|
-
this.updateGroupData();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
// If this window is in a movable group, get the window in the
|
|
240
|
-
// top right and show only its taskbar icon.
|
|
241
|
-
// This is typically only done when windows join or leave a group
|
|
242
|
-
// However, in a non-rectangular group, you could resize one of
|
|
243
|
-
// the windows such that the top-right window changes.
|
|
244
|
-
const movableGroup = this.getMovableGroup(win.name);
|
|
245
|
-
if (movableGroup) {
|
|
246
|
-
this.setTaskbarIconForGroup(movableGroup);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
stopMovingGroup(group) {
|
|
251
|
-
// When we have finished acting on the group, update each individual window's 'finished' property. Then call the function to complete the move.
|
|
252
|
-
for (const windowName in group.windows) {
|
|
253
|
-
const win = this.getWindow(windowName);
|
|
254
|
-
win.finished = true;
|
|
255
|
-
}
|
|
256
|
-
group.stopMove();
|
|
257
|
-
// When we have finished acting on the group, update each individual window's 'finishedMove' property. Then call the function to complete the move.
|
|
258
|
-
for (const windowName in group.windows) {
|
|
259
|
-
const win = this.getWindow(windowName);
|
|
260
|
-
win.win._stopMove();
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
maybeDockWindow(moveRequest, movingWindow, monitor) {
|
|
264
|
-
var _a;
|
|
265
|
-
moveRequest.dockedHeight = movingWindow.dockedParams.height; // This will only work when docking top/bottom (which is all that's allowed for now)
|
|
266
|
-
const { width: oldWidth, height: oldHeight } = moveRequest;
|
|
267
|
-
moveRequest.dockableEdges = (_a = movingWindow.dockingOptions) === null || _a === void 0 ? void 0 : _a.dockable;
|
|
268
|
-
const newMoveRequest = monitor.getDockedPosition(moveRequest);
|
|
269
|
-
if (newMoveRequest) {
|
|
270
|
-
this.moveWindow(newMoveRequest, () => {
|
|
271
|
-
monitor.dockWindowToMonitor(newMoveRequest, movingWindow, oldWidth, oldHeight);
|
|
272
|
-
// Initially, the "bounds-changed" event is used to broadcast an Electron level events such as "windowMoved" and "mouseUp".
|
|
273
|
-
// But the docking occurs at the Finsemble API level, so needed to additionally trigger the "bounds-changed" event here with new bounds.
|
|
274
|
-
movingWindow.win.eventManager.trigger("bounds-changed", movingWindow.getBounds());
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
ensureNotInTwoGroups(win, group) {
|
|
279
|
-
// You can only be in two groups at a time. a movable one, and a resizable one.
|
|
280
|
-
if (group.isMovable) {
|
|
281
|
-
const movableGroup = this.getMovableGroup(win.name);
|
|
282
|
-
if (movableGroup) {
|
|
283
|
-
this.removeWindowFromGroup(win.name, movableGroup.name, true, false);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
const immobileGroup = this.getImmobileGroup(win.name);
|
|
288
|
-
if (immobileGroup) {
|
|
289
|
-
this.removeWindowFromGroup(win.name, immobileGroup.name, true, false);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
// This should probably be moved to DockableWindow but we do not seem
|
|
294
|
-
// to be relying on windowState on the maximized event handler there...
|
|
295
|
-
isDockableWindowMaximized(dockableWindow) {
|
|
296
|
-
return dockableWindow.win.windowState === WINDOWSTATE.MAXIMIZED;
|
|
297
|
-
}
|
|
298
|
-
groupContainsMaximizedWindows(group) {
|
|
299
|
-
return Object.keys(group).some((windowName) => this.isDockableWindowMaximized(group[windowName]));
|
|
300
|
-
}
|
|
301
|
-
/** **************************************
|
|
302
|
-
* Core Loop
|
|
303
|
-
* Docking works like this:
|
|
304
|
-
* A dockableWindow receives a `bounds-change-request` event from the window object that it wraps (e.g., an Electron window). Then the docking calculator gets to work.
|
|
305
|
-
* 1. `this.requestMove`.
|
|
306
|
-
* 2. `this.onMouseDown`.
|
|
307
|
-
* 3. `this.onMouseMove`.
|
|
308
|
-
*
|
|
309
|
-
* As the user moves her mouse around, steps 1 and 3 are executed.When she releases her mouse, the dockableWindow throws a `bounds-changed` event, which in turn calls `this.onMouseUp`.
|
|
310
|
-
* The general idea is that the user says "Hey, I'd like to move my window 10px to the right of this window. The calculator spins through, notices that the window that the user is moving is within a snapping buffer around the other window. So it responds, "You're too close to that window, sorry, but we're snapping you.". If the movingWindow isn't within the stationaryWindow's buffer, we give the window the all clear to proceed.
|
|
311
|
-
*************************************** */
|
|
312
|
-
/**
|
|
313
|
-
* This is the core controller of the program. It routes the window's moveRequest to the appropriate place, and it receives the modified bounds afterwards. It communicates the modified bounds to the window via the CB.
|
|
314
|
-
* @param {moveRequest} Request from the `dockableWindow`.
|
|
315
|
-
* @param {function} cb What to do after the window's new bounds have been calculated.
|
|
316
|
-
*/
|
|
317
|
-
async requestMove(userRequest, cb) {
|
|
318
|
-
return new Promise((resolve) => {
|
|
319
|
-
if (!userRequest) {
|
|
320
|
-
Logger.system.warn("userRequest null or undefined in requestMove.");
|
|
321
|
-
cb === null || cb === void 0 ? void 0 : cb(null);
|
|
322
|
-
resolve(null);
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
const win = this.getWindow(userRequest.name);
|
|
326
|
-
if (!win) {
|
|
327
|
-
Logger.system.warn("Got Move Request From Window Not Registered With Docking", userRequest.name);
|
|
328
|
-
cb === null || cb === void 0 ? void 0 : cb(null);
|
|
329
|
-
resolve(null);
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
// TPina - 12/05/2022 - We are disabling the dragging of maximized windows (grouped and not grouped).
|
|
333
|
-
// Ideally we would mimic the OS which restores the window before the drag, but our code
|
|
334
|
-
// it is not robust enough that allow us to do that at this point.
|
|
335
|
-
// Electron may also have some bugs related to this since other electron apps behave oddly when we drag
|
|
336
|
-
// maximized windows.
|
|
337
|
-
if (win.win.windowState === WINDOWSTATE.MAXIMIZED) {
|
|
338
|
-
cb === null || cb === void 0 ? void 0 : cb(null);
|
|
339
|
-
resolve(null);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
this.movingGroup = this.getMovingGroup(userRequest);
|
|
343
|
-
if (this.movingGroup &&
|
|
344
|
-
this.movingGroup.windows &&
|
|
345
|
-
this.groupContainsMaximizedWindows(this.movingGroup.windows)) {
|
|
346
|
-
cb === null || cb === void 0 ? void 0 : cb(null);
|
|
347
|
-
resolve(null);
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
// Occasionally the system bubbles up an incorrect change type.
|
|
351
|
-
// A resize from the top right would start with a changeType of 0.
|
|
352
|
-
// The next move will have the proper change type. If we detect that scenario, we need to reset the resizeObject.
|
|
353
|
-
if (this.moveRequest && this.moveRequest.changeType === 0 && userRequest.changeType !== 0) {
|
|
354
|
-
this.resizeObject = this.constructResizeObject(userRequest);
|
|
355
|
-
}
|
|
356
|
-
// Force minimum height and width even if not in group.
|
|
357
|
-
if (userRequest.changeType !== 0)
|
|
358
|
-
userRequest = this.checkShortCircuits(userRequest);
|
|
359
|
-
const shouldRemoveFromGroup = this.shiftKey && userRequest.changeType === 0;
|
|
360
|
-
if (shouldRemoveFromGroup)
|
|
361
|
-
this.removeUserRequestFromGroup(userRequest);
|
|
362
|
-
this.groupAction = {
|
|
363
|
-
name: null,
|
|
364
|
-
windows: [],
|
|
365
|
-
};
|
|
366
|
-
/** *
|
|
367
|
-
* The check below is to see whether we should call onMouseDown, which resets a lot of cached information for docking. There are a couple of cases where we want to call onMouseDown.
|
|
368
|
-
1. We don't have a cached movingWindow reference. This can mean that onMouseDown hasn't been called, _or_ the moving window was removed from docking before onMouseUp was called. This can be triggered by tiling operations.
|
|
369
|
-
2. We don't have a cached moveRequest.
|
|
370
|
-
3. We have a moverequest, but the incoming request has a different change type. The only time we've seen that is in the case of aero-snap. if you aero-snap a window to the side or top of a monitor, then move it, it sends in a changeType of 2 - change in position in size. In any normal world, this is a resize. But it comes in as though a user moved the window. That confuses docking.
|
|
371
|
-
*/
|
|
372
|
-
const changeTypesAreDifferent = this.moveRequest && this.moveRequest.changeType !== userRequest.changeType;
|
|
373
|
-
if (!this.movingWindow || !this.moveRequest || changeTypesAreDifferent) {
|
|
374
|
-
this.onMouseDown(userRequest);
|
|
375
|
-
}
|
|
376
|
-
const moveRequest = this.setMoveRequest(userRequest);
|
|
377
|
-
if (moveRequest.changeType === undefined) {
|
|
378
|
-
moveRequest.changeType = 0;
|
|
379
|
-
}
|
|
380
|
-
if (!this.movingWindow)
|
|
381
|
-
this.movingWindow = this.getWindow(moveRequest.name);
|
|
382
|
-
moveRequest.groupNames = this.movingWindow.groupNames;
|
|
383
|
-
moveRequest.movingRegion = this.resizeObject.correctedHandle;
|
|
384
|
-
moveRequest.resizeHandle = moveRequest.forceResizeHandle
|
|
385
|
-
? moveRequest.resizeHandle
|
|
386
|
-
: this.resizeObject.correctedHandle;
|
|
387
|
-
this.ensureMovingGroupIsSet(moveRequest);
|
|
388
|
-
const afterMove = (bounds) => {
|
|
389
|
-
this.onMouseMove(bounds, () => {
|
|
390
|
-
cb === null || cb === void 0 ? void 0 : cb(null);
|
|
391
|
-
resolve(null);
|
|
392
|
-
});
|
|
393
|
-
};
|
|
394
|
-
if (this.groupMode.enabled && moveRequest.groupNames.length) {
|
|
395
|
-
// /Do something if in a group.
|
|
396
|
-
this.handleGroup(moveRequest, afterMove);
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
this.checkBuffers(moveRequest, afterMove);
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Windows can be part of two groups - one that can move, and one that allows shared border resizing/group resizing. When N windows are snapped together but not explicitly grouped together, they form an "immobileGroup". A movable group is one that the user has explicitly formed. This function returns the appropriate group, given a moveRequest.
|
|
404
|
-
* @param {object} moveRequest moverequest.
|
|
405
|
-
*/
|
|
406
|
-
getMovingGroup(moveRequest) {
|
|
407
|
-
// If snapped windows can't resize, we always want to return the movable group first.
|
|
408
|
-
if (this.groupMode.allowSnappedWindowsToResize && moveRequest.changeType !== 0) {
|
|
409
|
-
return this.getImmobileGroup(moveRequest.name) || this.getMovableGroup(moveRequest.name);
|
|
410
|
-
}
|
|
411
|
-
return this.getMovableGroup(moveRequest.name) || this.getImmobileGroup(moveRequest.name);
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* Loops through all DockableGroups and reconstitutes gaps. This is to clean up an issue where
|
|
415
|
-
* grouped windows containing a single pixel gap would break on mouse down as the system would
|
|
416
|
-
* no longer consider them snapped, and therefore would break and remove the group
|
|
417
|
-
*/
|
|
418
|
-
fixAllGroupGaps() {
|
|
419
|
-
Object.values(this.getGroups()).forEach((group) => {
|
|
420
|
-
this.cleanupGroupGaps(group);
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Given a group, will clean up the gaps and reconstitute the groups
|
|
425
|
-
* @param {object} group An object containing groups, with groupName as key
|
|
426
|
-
*/
|
|
427
|
-
cleanupGroupGaps(group) {
|
|
428
|
-
let windowBounds = this.getBoundsOfGroupWindows(group);
|
|
429
|
-
windowBounds = this.cleanupGaps(group, windowBounds);
|
|
430
|
-
this.setBoundsOfGroupWindows(group, windowBounds);
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* This function caches information in the resizeObject so that it doesn't need to be calculated onMouseMove.
|
|
434
|
-
*/
|
|
435
|
-
onMouseDown(moveRequest) {
|
|
436
|
-
RouterClient.transmit("Assimilation.taskbar", { visible: false });
|
|
437
|
-
if (this.moveCount === 0) {
|
|
438
|
-
/*
|
|
439
|
-
* JC 7/26/19 - Cleanup group gaps on first move to solve an issue where grouped
|
|
440
|
-
* windows with a single pixel gap would break when the group was moved
|
|
441
|
-
*/
|
|
442
|
-
this.fixAllGroupGaps();
|
|
443
|
-
this.recalculateSnaps();
|
|
444
|
-
}
|
|
445
|
-
this.moveCount++;
|
|
446
|
-
this.movingWindow = this.getWindow(moveRequest.name);
|
|
447
|
-
this.movingWindow.resizeHandle = null;
|
|
448
|
-
if (!this.movingWindow) {
|
|
449
|
-
throw new Error("Window not found");
|
|
450
|
-
}
|
|
451
|
-
// save window opacity before moving
|
|
452
|
-
this.saveWindowsOpacity();
|
|
453
|
-
// When we mouse down on a dockable component, we need to store the monitor its on immediately.
|
|
454
|
-
// Sometimes, in a multi-monitor configuration, when the window undocks it will momentarily
|
|
455
|
-
// jump to another monitor (since the grabber when docked is always near a monitor edge).
|
|
456
|
-
// To prevent the moveAllWindowsOutOfClaimedSpace calculation from using the
|
|
457
|
-
// wrong monitor, we store it on the window to remove it later.
|
|
458
|
-
if (this.movingWindow.isDockableComponent && this.movingWindow.win.isDocked) {
|
|
459
|
-
this.movingWindow.dockedMonitor = this.getMonitorForWindow(this.movingWindow); // Not sure why this.movingWindow.monitor is wrong on restart (is always display1)
|
|
460
|
-
}
|
|
461
|
-
this.movingGroup = this.getMovingGroup(moveRequest);
|
|
462
|
-
if (this.movingGroup) {
|
|
463
|
-
// If this is a group move and there are maximized windows we do not perform the move
|
|
464
|
-
// since the window movement code is quite frail and it causes a vast array of issues
|
|
465
|
-
// Group moves are only allowed if all windows in the group are not maximized.
|
|
466
|
-
if (this.groupContainsMaximizedWindows(this.movingGroup.windows)) {
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
for (const windowName in this.movingGroup.windows) {
|
|
470
|
-
this.getWindow(windowName).bringToFront();
|
|
471
|
-
}
|
|
472
|
-
// Call bringToFront after the loop because the moving window should always be on top of the others windows in the group
|
|
473
|
-
this.movingWindow.bringToFront();
|
|
474
|
-
this.movingGroup.startMove();
|
|
475
|
-
}
|
|
476
|
-
else {
|
|
477
|
-
this.movingWindow.win.startMove();
|
|
478
|
-
}
|
|
479
|
-
// If there's no moving group, then we're moving an individual window. if it's part of a resizableGroup, it needs to be removed from that group.
|
|
480
|
-
if (this.groupMode.behavior === "explicit" &&
|
|
481
|
-
moveRequest.changeType === 0 &&
|
|
482
|
-
this.movingGroup &&
|
|
483
|
-
!this.movingGroup.isMovable) {
|
|
484
|
-
this.removeWindowFromGroup(moveRequest.name, this.movingGroup.name);
|
|
485
|
-
this.wipeSnapRelationships(moveRequest.name);
|
|
486
|
-
this.updateGroupData();
|
|
487
|
-
}
|
|
488
|
-
this.resizeObject = this.constructResizeObject(moveRequest);
|
|
489
|
-
if (this.resizeObject.scalingGroup && this.movingGroup) {
|
|
490
|
-
const groupIter = this.groupWindowIterator(this.movingGroup);
|
|
491
|
-
for (const win of groupIter) {
|
|
492
|
-
win.hide();
|
|
493
|
-
}
|
|
494
|
-
mouseDown(this.movingGroup.getBounds(), moveRequest.mousePosition, this.resizeObject);
|
|
495
|
-
this.showGroupMask({ bounds: this.movingGroup.getBounds(), opacity: 0.5 }, () => { });
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
hideGroupMask(cb = Function.prototype) {
|
|
499
|
-
this.groupMaskExpectedState = "hidden";
|
|
500
|
-
this.groupMaskQueue.push((done) => {
|
|
501
|
-
var _a;
|
|
502
|
-
if (this.groupMaskExpectedState === "shown" || this.groupMaskIsVisible === false) {
|
|
503
|
-
cb();
|
|
504
|
-
return done();
|
|
505
|
-
}
|
|
506
|
-
(_a = this.groupMask) === null || _a === void 0 ? void 0 : _a.win._hide({}, () => {
|
|
507
|
-
this.groupMaskIsVisible = false;
|
|
508
|
-
cb();
|
|
509
|
-
done();
|
|
510
|
-
});
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Transparency breaks often with group mask. So use this to show it.
|
|
515
|
-
*
|
|
516
|
-
* @param {any} bounds
|
|
517
|
-
* @param {number} [opacity=0.5]
|
|
518
|
-
* @param {any} [cb=Function.prototype]
|
|
519
|
-
* @memberof DockingCalculator
|
|
520
|
-
*/
|
|
521
|
-
showGroupMask(params, cb = Function.prototype) {
|
|
522
|
-
this.groupMaskExpectedState = "shown";
|
|
523
|
-
if (!this.groupMask)
|
|
524
|
-
return;
|
|
525
|
-
const { bounds } = params;
|
|
526
|
-
const groupMaskBounds = this.groupMask.getBounds();
|
|
527
|
-
if (this.groupMaskIsVisible &&
|
|
528
|
-
groupMaskBounds.top == bounds.top &&
|
|
529
|
-
groupMaskBounds.left == bounds.left &&
|
|
530
|
-
groupMaskBounds.height == bounds.height &&
|
|
531
|
-
groupMaskBounds.width == bounds.width) {
|
|
532
|
-
return cb();
|
|
533
|
-
}
|
|
534
|
-
this.groupMask.setBounds(params.bounds, () => {
|
|
535
|
-
var _a;
|
|
536
|
-
(_a = this.groupMask) === null || _a === void 0 ? void 0 : _a.win._updateOptions({ opacity: params.opacity }, () => {
|
|
537
|
-
this.groupMaskQueue.push((done) => {
|
|
538
|
-
var _a;
|
|
539
|
-
if (this.groupMaskExpectedState === "hidden" || this.groupMaskIsVisible === true) {
|
|
540
|
-
cb();
|
|
541
|
-
return done();
|
|
542
|
-
}
|
|
543
|
-
(_a = this.groupMask) === null || _a === void 0 ? void 0 : _a.win._show({}, () => {
|
|
544
|
-
var _a;
|
|
545
|
-
(_a = this.groupMask) === null || _a === void 0 ? void 0 : _a.win._bringToFront({}, () => {
|
|
546
|
-
this.groupMaskIsVisible = true;
|
|
547
|
-
cb();
|
|
548
|
-
done();
|
|
549
|
-
});
|
|
550
|
-
});
|
|
551
|
-
});
|
|
552
|
-
});
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* This function happens _after_ the calculations have been made. The request comes in, `this.requestMove` routes the request to the appropriate place, and modified bounds are passed into this function. It's a choke point for all docking-sanctioned window movement.
|
|
557
|
-
*/
|
|
558
|
-
onMouseMove(bounds, cb) {
|
|
559
|
-
var _a;
|
|
560
|
-
this.fixWindowOpacity({
|
|
561
|
-
checkForSnappability: true,
|
|
562
|
-
});
|
|
563
|
-
// We might get here via fillHoles or some other programatic action, in which case we don't want
|
|
564
|
-
// to move the group mask. We can check whether mousePosition exists to determine this.
|
|
565
|
-
if (this.resizeObject.scalingGroup && ((_a = this.moveRequest) === null || _a === void 0 ? void 0 : _a.mousePosition)) {
|
|
566
|
-
this.moveGroupMask();
|
|
567
|
-
}
|
|
568
|
-
if (bounds.finished) {
|
|
569
|
-
if (typeof bounds.top !== "undefined") {
|
|
570
|
-
this.moveWindow(bounds);
|
|
571
|
-
}
|
|
572
|
-
cb(null);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
/**
|
|
576
|
-
* When the user lifts her mouse, this is fired. It cleans up opacity, shows windows if we were moving a group, and cleans up global variables.
|
|
577
|
-
*
|
|
578
|
-
* @param {} params - Optional. Possible parameters:
|
|
579
|
-
* systemMoved: If true, indicates the OS initiated the group move
|
|
580
|
-
* triggeredByAutoArrange: If true, indicate the move was initiated by auto-arrange
|
|
581
|
-
*/
|
|
582
|
-
async onMouseUp(params = {}) {
|
|
583
|
-
var _a, _b;
|
|
584
|
-
if (!this.movingWindow)
|
|
585
|
-
return;
|
|
586
|
-
if (this.movingWindow && this.movingWindow.win.windowState === WINDOWSTATE.MAXIMIZED)
|
|
587
|
-
return;
|
|
588
|
-
RouterClient.transmit("Assimilation.taskbar", { visible: true });
|
|
589
|
-
if (this.movingAGroupOfWindows && this.movingGroup)
|
|
590
|
-
this.endMovingGroup(this.movingGroup);
|
|
591
|
-
this.maybeMakeOrBreakGroups(params.systemMoved);
|
|
592
|
-
const isUndockedDockableComponent = this.movingWindow.isDockableComponent && !this.movingWindow.win.isDocked;
|
|
593
|
-
// Dockable components cannot be dropped off monitor. This code will push the back onto
|
|
594
|
-
// the monitor if the user dropped them off monitor.
|
|
595
|
-
if (isUndockedDockableComponent)
|
|
596
|
-
this.ensureNotOffMonitor(this.movingWindow);
|
|
597
|
-
const monitorForWindow = this.getMonitorForWindow(this.movingWindow);
|
|
598
|
-
const movedWin = {
|
|
599
|
-
name: this.movingWindow.name,
|
|
600
|
-
monitor: monitorForWindow,
|
|
601
|
-
};
|
|
602
|
-
globalStationaryWindow = null;
|
|
603
|
-
let dockedWindowPosition = {};
|
|
604
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
605
|
-
// Iterate through all known windows, saving information about a docked window (e.g. the toolbar)
|
|
606
|
-
// and also updating the bounds of all groups in case any have changed.
|
|
607
|
-
for (const win of dockingPoolIterator) {
|
|
608
|
-
if (win.win.isDocked) {
|
|
609
|
-
dockedWindowPosition.edge = win.snappedEdge;
|
|
610
|
-
({ name: dockedWindowPosition.monitorName } = await this.getMonitorForWindow(win));
|
|
611
|
-
}
|
|
612
|
-
win.resizeHandle = null;
|
|
613
|
-
win.groupNames.forEach((groupName) => {
|
|
614
|
-
const group = this.getGroup(groupName);
|
|
615
|
-
group.updateBounds();
|
|
616
|
-
});
|
|
617
|
-
}
|
|
618
|
-
// If we did a group operation, call stopMove, which triggers a bounds save.
|
|
619
|
-
if (this.movingGroup) {
|
|
620
|
-
this.stopMovingGroup(this.movingGroup);
|
|
621
|
-
}
|
|
622
|
-
else {
|
|
623
|
-
this.movingWindow.win.stopMove();
|
|
624
|
-
}
|
|
625
|
-
// moveRequest is null on group mask resizes..sometimes.
|
|
626
|
-
if (!this.moveRequest)
|
|
627
|
-
return;
|
|
628
|
-
// Reposition the window if it overlaps a docked window (the toolbar). Since only the toolbar can be docked, we only need to do this
|
|
629
|
-
// check if (1) the toolbar is docked and (2) the movingWindow is not the toolbar
|
|
630
|
-
if (this.claimSpace &&
|
|
631
|
-
this.preventOverlapClaimSpace &&
|
|
632
|
-
!((_a = this.movingWindow) === null || _a === void 0 ? void 0 : _a.isDockableComponent) &&
|
|
633
|
-
dockedWindowPosition !== {})
|
|
634
|
-
this.ensureNotOverlappingDockedWindow(this.movingWindow, dockedWindowPosition);
|
|
635
|
-
// If we mouse up on a dockable component we need to check if it should be docked. If it should, we have to call to move the window since we also want to expand one side or another, since a docked window expands to take the width (or height) of the monitor.
|
|
636
|
-
if (isUndockedDockableComponent && this.movingWindow.snappedMonitor)
|
|
637
|
-
this.maybeDockWindow(this.moveRequest, this.movingWindow, monitorForWindow);
|
|
638
|
-
this.hideGroupMask();
|
|
639
|
-
// When we eject a tab from a tabbed group it should be brought to front
|
|
640
|
-
this.movingWindow.bringToFront();
|
|
641
|
-
this.movingGroup = null;
|
|
642
|
-
this.movingWindow = null;
|
|
643
|
-
this.resizeObject = {};
|
|
644
|
-
if (this.groupMode.enabled && this.groupAction.name) {
|
|
645
|
-
this.formGroup(this.moveRequest.name, { isMovable: false });
|
|
646
|
-
}
|
|
647
|
-
this.moveRequest = null;
|
|
648
|
-
this.fixWindowOpacity({
|
|
649
|
-
checkForSnappability: false,
|
|
650
|
-
persist: true,
|
|
651
|
-
});
|
|
652
|
-
// restore the initial window opacity
|
|
653
|
-
this.restoreWindowsOpacity();
|
|
654
|
-
// function below defined by the service. Tell it which monitor the window was on when it moved.
|
|
655
|
-
(_b = this.onMoveComplete) === null || _b === void 0 ? void 0 : _b.call(this, movedWin, params.triggeredByAutoArrange);
|
|
656
|
-
}
|
|
657
|
-
static get NO_CHANGE() {
|
|
658
|
-
return -1;
|
|
659
|
-
}
|
|
660
|
-
/** **************************************
|
|
661
|
-
* Calculators - Window Collections *
|
|
662
|
-
*************************************** */
|
|
663
|
-
formGroup(name, params) {
|
|
664
|
-
let { isMovable, whitelist, isAlwaysOnTop } = params;
|
|
665
|
-
const self = this;
|
|
666
|
-
if (!whitelist) {
|
|
667
|
-
whitelist = this.getWindowNames();
|
|
668
|
-
}
|
|
669
|
-
const win = this.getWindow(name);
|
|
670
|
-
let windows = win.snappedWindows.map((snapObj) => snapObj.name).filter((snapName) => whitelist.includes(snapName));
|
|
671
|
-
const processed = [win.name];
|
|
672
|
-
function getSnappedWindows(windo) {
|
|
673
|
-
processed.push(windo.name);
|
|
674
|
-
let snappedWindows = windo.snappedWindows
|
|
675
|
-
.map((snapObj) => snapObj.name)
|
|
676
|
-
.filter((snapName) => whitelist.includes(snapName));
|
|
677
|
-
windo.snappedWindows.forEach((snapObj) => {
|
|
678
|
-
if (!processed.includes(snapObj.name) && whitelist.includes(snapObj.name)) {
|
|
679
|
-
const snapWin = self.getWindow(snapObj.name);
|
|
680
|
-
const grandSnaps = getSnappedWindows(snapWin);
|
|
681
|
-
snappedWindows = snappedWindows.concat(grandSnaps);
|
|
682
|
-
}
|
|
683
|
-
});
|
|
684
|
-
return snappedWindows;
|
|
685
|
-
}
|
|
686
|
-
win.snappedWindows.forEach((snapObj) => {
|
|
687
|
-
if (whitelist.includes(snapObj.name)) {
|
|
688
|
-
const snapWin = self.getWindow(snapObj.name);
|
|
689
|
-
const snappedWindows = getSnappedWindows(snapWin);
|
|
690
|
-
windows = windows.concat(snappedWindows);
|
|
691
|
-
}
|
|
692
|
-
});
|
|
693
|
-
// dedupe.
|
|
694
|
-
windows = windows.filter((el, i, arr) => arr.indexOf(el) === i);
|
|
695
|
-
if (windows.length) {
|
|
696
|
-
this.groupWindows({ windows, isMovable, isAlwaysOnTop });
|
|
697
|
-
}
|
|
698
|
-
return windows;
|
|
699
|
-
}
|
|
700
|
-
/**
|
|
701
|
-
* Spins through all of the windows that can group and creates groups based on window position.
|
|
702
|
-
*/
|
|
703
|
-
constituteGroups() {
|
|
704
|
-
for (const groupName in this.getGroups()) {
|
|
705
|
-
this.removeGroup(groupName);
|
|
706
|
-
}
|
|
707
|
-
this.eliminateGaps();
|
|
708
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
709
|
-
for (let win of dockingPoolIterator) {
|
|
710
|
-
if (groupBlacklist.includes(win.name) || !win.canGroup) {
|
|
711
|
-
continue;
|
|
712
|
-
}
|
|
713
|
-
const groupList = this.getGroupNames();
|
|
714
|
-
if (!Object.keys(groupList).length) {
|
|
715
|
-
this.addWindowToGroup({
|
|
716
|
-
groupName: uuidv4(),
|
|
717
|
-
win,
|
|
718
|
-
});
|
|
719
|
-
continue;
|
|
720
|
-
}
|
|
721
|
-
this.buildSnapRelationships(win);
|
|
722
|
-
const { snappedWindows } = win;
|
|
723
|
-
for (let i = 0, len = snappedWindows.length; i < len; i++) {
|
|
724
|
-
const snapObj = snappedWindows[i];
|
|
725
|
-
var snappedWindow = this.getWindow(snapObj.name);
|
|
726
|
-
if (win.groupNames.length) {
|
|
727
|
-
win.groupNames.forEach((groupName) => {
|
|
728
|
-
this.addWindowToGroup({
|
|
729
|
-
groupName,
|
|
730
|
-
win: snappedWindow,
|
|
731
|
-
});
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
else if (snappedWindow && snappedWindow.groupNames.length) {
|
|
735
|
-
snappedWindow.groupNames.forEach((groupName) => {
|
|
736
|
-
this.addWindowToGroup({
|
|
737
|
-
groupName,
|
|
738
|
-
win,
|
|
739
|
-
});
|
|
740
|
-
});
|
|
741
|
-
}
|
|
742
|
-
else {
|
|
743
|
-
const groupParams = {
|
|
744
|
-
name: uuidv4(),
|
|
745
|
-
MINIMUM_HEIGHT: this.MINIMUM_HEIGHT,
|
|
746
|
-
MINIMUM_WIDTH: this.MINIMUM_WIDTH,
|
|
747
|
-
};
|
|
748
|
-
const newGroup = new DockableGroup(groupParams);
|
|
749
|
-
this.addGroup(newGroup);
|
|
750
|
-
this.addWindowToGroup({
|
|
751
|
-
groupName: newGroup.name,
|
|
752
|
-
win,
|
|
753
|
-
});
|
|
754
|
-
this.addWindowToGroup({
|
|
755
|
-
groupName: newGroup.name,
|
|
756
|
-
win: snappedWindow,
|
|
757
|
-
});
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
/**
|
|
763
|
-
* Given a moveRequest, it returns an array of windowNames. The check essentially boils down to "is this window within my snapping buffer?"
|
|
764
|
-
* @param {moveRequest} moveRequest
|
|
765
|
-
*/
|
|
766
|
-
getSnappableWindows(moveRequest) {
|
|
767
|
-
const snappableWindows = [];
|
|
768
|
-
const windowIter = DockingPoolSingleton.iterator();
|
|
769
|
-
for (const win of windowIter) {
|
|
770
|
-
// if moveRequest puts the window inside of the stationary window's buffer, snap.
|
|
771
|
-
if (moveRequest.name === win.name) {
|
|
772
|
-
continue;
|
|
773
|
-
}
|
|
774
|
-
if (!win.ignoreSnappingRequests && win.canSnapToWindow(moveRequest) && !moveRequest.ignoreSnappingRequests) {
|
|
775
|
-
snappableWindows.push(win.name);
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
return snappableWindows;
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
* Checks to see if the window is within the snapping region of any monitor.
|
|
782
|
-
*/
|
|
783
|
-
getSnappableMonitors(moveRequest) {
|
|
784
|
-
const monitorNames = Object.keys(MonitorPoolSingleton.getAll());
|
|
785
|
-
const snappableMonitors = [];
|
|
786
|
-
for (let i = 0, len = monitorNames.length; i < len; i++) {
|
|
787
|
-
const monitorName = monitorNames[i];
|
|
788
|
-
const monitor = MonitorPoolSingleton.get(monitorName);
|
|
789
|
-
if (monitor.canSnapToWindow(moveRequest)) {
|
|
790
|
-
snappableMonitors.push(monitorName);
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
return snappableMonitors;
|
|
794
|
-
}
|
|
795
|
-
/**
|
|
796
|
-
* Returns an object that describes the edges and corners that are shared between two windows.
|
|
797
|
-
*/
|
|
798
|
-
getSnapObj(win1, win2) {
|
|
799
|
-
return {
|
|
800
|
-
canGroup: !groupBlacklist.includes(win2.name),
|
|
801
|
-
name: win2.name,
|
|
802
|
-
edges: win1.getSharedEdges(win2),
|
|
803
|
-
corners: win1.getSharedCorners(win2),
|
|
804
|
-
};
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* Snaps two windows..
|
|
808
|
-
*/
|
|
809
|
-
snapTwoWindows(win1, win2) {
|
|
810
|
-
if (groupBlacklist.includes(win1.name) || groupBlacklist.includes(win2.name)) {
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
win1.addSnappedWindow(this.getSnapObj(win1, win2));
|
|
814
|
-
win2.addSnappedWindow(this.getSnapObj(win2, win1));
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* Wipes all relationships between windows and recalculates them.
|
|
818
|
-
*/
|
|
819
|
-
recalculateSnaps() {
|
|
820
|
-
const windowIter = DockingPoolSingleton.iterator();
|
|
821
|
-
for (const win of windowIter) {
|
|
822
|
-
this.buildSnapRelationships(win);
|
|
823
|
-
if (win.groupNames.length) {
|
|
824
|
-
win.groupNames.forEach((groupName) => {
|
|
825
|
-
const group = this.getGroup(groupName);
|
|
826
|
-
group.updateBounds();
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
/**
|
|
832
|
-
* Updates the snappedWindows array for window. The snappedWindow object contains: name, shared edges, shared corners, and whether the window canGroup.
|
|
833
|
-
* @param {dockableWindow} win
|
|
834
|
-
*/
|
|
835
|
-
buildSnapRelationships(win) {
|
|
836
|
-
if (win.snappedWindows.length) {
|
|
837
|
-
this.wipeSnapRelationships(win.name);
|
|
838
|
-
}
|
|
839
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
840
|
-
for (const snappedWindow of dockingPoolIterator) {
|
|
841
|
-
if (snappedWindow.name === win.name) {
|
|
842
|
-
continue;
|
|
843
|
-
}
|
|
844
|
-
const isOneGroup = win.groupNames.filter((groupName) => snappedWindow.groupNames.includes(groupName)).length > 0;
|
|
845
|
-
const isOneWindowMaximized = win.win.windowState === WINDOWSTATE.MAXIMIZED || snappedWindow.win.windowState === WINDOWSTATE.MAXIMIZED;
|
|
846
|
-
// snap windows if they have:
|
|
847
|
-
// 1) shared edge OR
|
|
848
|
-
// 2) shared corner OR
|
|
849
|
-
// 3) one of them is maximized and they both in the same group. That case prevents ungrouping on toolbar docking/undocking
|
|
850
|
-
if (win.sharesAnEdgeWith(snappedWindow) ||
|
|
851
|
-
win.sharesACornerWith(snappedWindow) ||
|
|
852
|
-
(isOneGroup && isOneWindowMaximized)) {
|
|
853
|
-
this.snapTwoWindows(win, snappedWindow);
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
/**
|
|
858
|
-
* Returns any window with a vertex on a segment.
|
|
859
|
-
* @param {segment} segment A line segment. An array with 2 points in it (start and end).
|
|
860
|
-
* @return {type}
|
|
861
|
-
*/
|
|
862
|
-
getWindowBoxesOnSegment(segment) {
|
|
863
|
-
const windowsOnSegment = [];
|
|
864
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
865
|
-
const points = [segment.min, segment.max];
|
|
866
|
-
for (const win of dockingPoolIterator) {
|
|
867
|
-
for (let p = 0, len = points.length; p < len; p++) {
|
|
868
|
-
const point = points[p];
|
|
869
|
-
if (win.pointIsOnBoundingBox(point)) {
|
|
870
|
-
const snapObj = {
|
|
871
|
-
name: win.name,
|
|
872
|
-
edge: win.getEdgeByPoint(point),
|
|
873
|
-
win,
|
|
874
|
-
};
|
|
875
|
-
snapObj.segment = win.getEdges("obj")[snapObj.edge];
|
|
876
|
-
windowsOnSegment.push(snapObj);
|
|
877
|
-
break;
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
return windowsOnSegment;
|
|
882
|
-
}
|
|
883
|
-
windowsOnEdgeFromPool(win, edge, includeCorners) {
|
|
884
|
-
let windowsOnEdge = [];
|
|
885
|
-
const oppEdge = OPPOSITE_EDGE_MAP[edge];
|
|
886
|
-
const windowSegment = win.getEdges("obj", includeCorners)[edge];
|
|
887
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
888
|
-
for (const possibleSnapper of dockingPoolIterator) {
|
|
889
|
-
// Current window isn't a candidate
|
|
890
|
-
if (possibleSnapper.name === win.name)
|
|
891
|
-
continue;
|
|
892
|
-
const segment = possibleSnapper.getEdges("obj", includeCorners)[oppEdge];
|
|
893
|
-
let points = [
|
|
894
|
-
{
|
|
895
|
-
name: possibleSnapper.name,
|
|
896
|
-
val: segment.min,
|
|
897
|
-
},
|
|
898
|
-
{
|
|
899
|
-
name: possibleSnapper.name,
|
|
900
|
-
val: segment.max,
|
|
901
|
-
},
|
|
902
|
-
{
|
|
903
|
-
name: win.name,
|
|
904
|
-
val: windowSegment.min,
|
|
905
|
-
},
|
|
906
|
-
{
|
|
907
|
-
name: win.name,
|
|
908
|
-
val: windowSegment.max,
|
|
909
|
-
},
|
|
910
|
-
];
|
|
911
|
-
if (["top", "bottom"].includes(edge)) {
|
|
912
|
-
if (segment.min.y !== windowSegment.min.y)
|
|
913
|
-
continue;
|
|
914
|
-
points = points.sort((a, b) => b.val.x - a.val.x);
|
|
915
|
-
}
|
|
916
|
-
if (["left", "right"].includes(edge)) {
|
|
917
|
-
if (segment.min.x !== windowSegment.min.x)
|
|
918
|
-
continue;
|
|
919
|
-
points = points.sort((a, b) => b.val.y - a.val.y);
|
|
920
|
-
}
|
|
921
|
-
if (points[0].name === points[1].name)
|
|
922
|
-
continue;
|
|
923
|
-
windowsOnEdge.push({
|
|
924
|
-
name: possibleSnapper.name,
|
|
925
|
-
edge: oppEdge,
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
return windowsOnEdge;
|
|
929
|
-
}
|
|
930
|
-
/**
|
|
931
|
-
* Similar to getWindowBoxesOnSegment but you can pass in a string instead of a line segment.
|
|
932
|
-
* @param {dockableWindow} win
|
|
933
|
-
* @param {string} edge E.g., 'left', 'right', etc.
|
|
934
|
-
* @return {array}
|
|
935
|
-
*/
|
|
936
|
-
getWindowsOnEdge(win, edge, includeCorners = false) {
|
|
937
|
-
if (!edge)
|
|
938
|
-
return [];
|
|
939
|
-
const splitEdge = edge.split(/(?=[A-Z])/).map((s) => s.toLowerCase());
|
|
940
|
-
if (splitEdge.length > 1) {
|
|
941
|
-
const cornerPoint = win.getPointByVertex(edge);
|
|
942
|
-
const windowsAtCorner = this.getWindowsAtPoint(cornerPoint);
|
|
943
|
-
const windowToPossibleSnapper = (windowName) => {
|
|
944
|
-
var _a;
|
|
945
|
-
const possibleSnapper = this.getWindow(windowName);
|
|
946
|
-
return {
|
|
947
|
-
name: possibleSnapper.name,
|
|
948
|
-
edge: (_a = possibleSnapper.getVertexByPoint(cornerPoint)) !== null && _a !== void 0 ? _a : "undefined",
|
|
949
|
-
};
|
|
950
|
-
};
|
|
951
|
-
return windowsAtCorner.map((windowName) => windowToPossibleSnapper(windowName));
|
|
952
|
-
}
|
|
953
|
-
return this.windowsOnEdgeFromPool(win, edge, includeCorners);
|
|
954
|
-
}
|
|
955
|
-
/**
|
|
956
|
-
* Returns a list of windows that straddle a given edge.
|
|
957
|
-
* +-----------+------------+
|
|
958
|
-
* | | |
|
|
959
|
-
* | | |
|
|
960
|
-
* | A | B |
|
|
961
|
-
* | | |
|
|
962
|
-
* +-----------+--+---------+
|
|
963
|
-
* | | |
|
|
964
|
-
* | C | D |
|
|
965
|
-
* | | |
|
|
966
|
-
* +--------------+---------+
|
|
967
|
-
*
|
|
968
|
-
* In the drawing above, B straddles the left edge of D and the right Edge of C.
|
|
969
|
-
* @param {dockableWindow} win
|
|
970
|
-
* @param {string} edge E.g., 'left', 'right', etc.
|
|
971
|
-
*/
|
|
972
|
-
getStraddlers(win) {
|
|
973
|
-
const straddlers = [];
|
|
974
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
975
|
-
for (const straddler of dockingPoolIterator) {
|
|
976
|
-
if (straddler.name === win.name) {
|
|
977
|
-
continue;
|
|
978
|
-
}
|
|
979
|
-
const corners = straddler.vertices;
|
|
980
|
-
for (const corner in corners) {
|
|
981
|
-
if (win.pointIsOnBoundingBox(corners[corner], false)) {
|
|
982
|
-
straddlers.push({
|
|
983
|
-
name: straddler.name,
|
|
984
|
-
edge: win.getEdgeByPoint(corners[corner]),
|
|
985
|
-
});
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
return straddlers;
|
|
990
|
-
}
|
|
991
|
-
/**
|
|
992
|
-
* Given an X, Y point, it returns a list of windows with that point on their boundingBox.
|
|
993
|
-
* @param {object} point
|
|
994
|
-
* @return {array}
|
|
995
|
-
*/
|
|
996
|
-
getWindowsAtPoint(point) {
|
|
997
|
-
const windows = [];
|
|
998
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
999
|
-
for (const win of dockingPoolIterator) {
|
|
1000
|
-
if (groupBlacklist.includes(win.name)) {
|
|
1001
|
-
continue;
|
|
1002
|
-
}
|
|
1003
|
-
if (win.pointIsOnBoundingBox(point)) {
|
|
1004
|
-
windows.push(win.name);
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
return windows;
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* Just a helper to say whether a window has an edge on the edge of the group.
|
|
1011
|
-
* @param {dockableWindow} win
|
|
1012
|
-
* @param {dockableGroup} group
|
|
1013
|
-
*/
|
|
1014
|
-
windowIsOnExteriorEdgeOfGroup(win, group) {
|
|
1015
|
-
const winBounds = win.windowBoundingBox;
|
|
1016
|
-
const groupBounds = group.bounds;
|
|
1017
|
-
// left
|
|
1018
|
-
if (winBounds.min.x === groupBounds.min.x) {
|
|
1019
|
-
return true;
|
|
1020
|
-
}
|
|
1021
|
-
// bottom
|
|
1022
|
-
if (winBounds.max.y === groupBounds.max.y) {
|
|
1023
|
-
return true;
|
|
1024
|
-
}
|
|
1025
|
-
// right
|
|
1026
|
-
if (winBounds.max.x === groupBounds.max.x) {
|
|
1027
|
-
return true;
|
|
1028
|
-
}
|
|
1029
|
-
// top
|
|
1030
|
-
return winBounds.min.y === groupBounds.min.y;
|
|
1031
|
-
}
|
|
1032
|
-
/**
|
|
1033
|
-
* Lets the program know that shift is being held down. This is used when moving a window that's explicitly grouped (if assimilation is turned on). In that case, the window moves out of the group.
|
|
1034
|
-
*/
|
|
1035
|
-
setShift(bool) {
|
|
1036
|
-
this.shiftKey = bool;
|
|
1037
|
-
}
|
|
1038
|
-
/**
|
|
1039
|
-
* Returns an ordered Object. Sorts by Top, then Left.
|
|
1040
|
-
* @return {Object} Object where the keys are names of the window.
|
|
1041
|
-
*/
|
|
1042
|
-
orderWindows(windowList, anchor) {
|
|
1043
|
-
// sort windows by top so that when we constitute groups it won't randomly compare windows in the bottom to ones in the top of the monitor.
|
|
1044
|
-
const sortableArray = [];
|
|
1045
|
-
if (windowList === undefined) {
|
|
1046
|
-
windowList = DockingPoolSingleton.getAll();
|
|
1047
|
-
}
|
|
1048
|
-
for (const windowName in windowList) {
|
|
1049
|
-
const win = this.getWindow(windowName);
|
|
1050
|
-
sortableArray.push(win);
|
|
1051
|
-
}
|
|
1052
|
-
sortableArray.sort((a, b) => {
|
|
1053
|
-
const aTop = a.top;
|
|
1054
|
-
const aLeft = a.left;
|
|
1055
|
-
const bTop = b.top;
|
|
1056
|
-
const bLeft = b.left;
|
|
1057
|
-
// if the window's top is above the anchor's top, compare its bottom to the anchor's top. In a 3x3 grid, this will ensure that windows in row 2 end up after windows in row 3. Looking at the grid below, if we just compared the window's top to the anchor's top, window D would appear in the array before D, even though D is closer to G. By comparing the bottoms of windows above the anchor, we force the algorithm to look at the left instead of the top. That all may be a crock of shit, too. I Basically, if I resize from the top-right of this group I want it to go: G, H, I, D, E, F, A, B, C. The algorithm below does that.
|
|
1058
|
-
/**
|
|
1059
|
-
* +-----------+--------------+-------------+
|
|
1060
|
-
* | | | |
|
|
1061
|
-
* | | | |
|
|
1062
|
-
* | A | B | C |
|
|
1063
|
-
* | | | |
|
|
1064
|
-
* | | | |
|
|
1065
|
-
* +-----------+ +-------------+
|
|
1066
|
-
* | +--------------+ |
|
|
1067
|
-
* | | | |
|
|
1068
|
-
* | D | E | F |
|
|
1069
|
-
* | | | |
|
|
1070
|
-
* +----------------------------------------+
|
|
1071
|
-
* | | | |
|
|
1072
|
-
* | | | |
|
|
1073
|
-
* | G | H | I |
|
|
1074
|
-
* | | | |
|
|
1075
|
-
* | | | |
|
|
1076
|
-
* +-----------+--------------+-------------+
|
|
1077
|
-
*/
|
|
1078
|
-
if (anchor) {
|
|
1079
|
-
const aDelta = {
|
|
1080
|
-
left: Math.abs(anchor.left - a.left),
|
|
1081
|
-
top: a.bottom === anchor.top ? Math.abs(anchor.top - a.bottom) : Math.abs(anchor.top - a.top),
|
|
1082
|
-
};
|
|
1083
|
-
const bDelta = {
|
|
1084
|
-
left: Math.abs(anchor.left - b.left),
|
|
1085
|
-
top: b.bottom === anchor.top ? Math.abs(anchor.top - b.bottom) : Math.abs(anchor.top - b.top),
|
|
1086
|
-
};
|
|
1087
|
-
if (aDelta.left === bDelta.left) {
|
|
1088
|
-
return aDelta.top - bDelta.top;
|
|
1089
|
-
}
|
|
1090
|
-
return aDelta.left - bDelta.left;
|
|
1091
|
-
}
|
|
1092
|
-
// orders windows ascending by their Top values.
|
|
1093
|
-
if (aTop === bTop) {
|
|
1094
|
-
return aLeft - bLeft;
|
|
1095
|
-
}
|
|
1096
|
-
return aTop - bTop;
|
|
1097
|
-
});
|
|
1098
|
-
return sortableArray;
|
|
1099
|
-
}
|
|
1100
|
-
/** **************************************
|
|
1101
|
-
* Getters/Setters *
|
|
1102
|
-
*************************************** */
|
|
1103
|
-
/**
|
|
1104
|
-
* Registers the window with the calculator
|
|
1105
|
-
* @param {string} name
|
|
1106
|
-
* @param {dockableWindow} val
|
|
1107
|
-
*/
|
|
1108
|
-
addWindowInternal(name, val) {
|
|
1109
|
-
var _a, _b, _c, _d;
|
|
1110
|
-
val.setBufferSize(this.bufferSize);
|
|
1111
|
-
val.setResizeThrottlePeriod(this.resizeEventThrottlePeriod);
|
|
1112
|
-
DockingPoolSingleton.add(name, val);
|
|
1113
|
-
// if the window is not resisable then the limits need to be set correctly
|
|
1114
|
-
val.limits = {
|
|
1115
|
-
minHeight: val.win.windowOptions.resizable === false ? val.win.windowOptions.height : (_a = val.dockingOptions) === null || _a === void 0 ? void 0 : _a.minHeight,
|
|
1116
|
-
minWidth: val.win.windowOptions.resizable === false ? val.win.windowOptions.width : (_b = val.dockingOptions) === null || _b === void 0 ? void 0 : _b.minWidth,
|
|
1117
|
-
maxHeight: val.win.windowOptions.resizable === false ? val.win.windowOptions.height : (_c = val.dockingOptions) === null || _c === void 0 ? void 0 : _c.maxHeight,
|
|
1118
|
-
maxWidth: val.win.windowOptions.resizable === false ? val.win.windowOptions.width : (_d = val.dockingOptions) === null || _d === void 0 ? void 0 : _d.maxWidth,
|
|
1119
|
-
};
|
|
1120
|
-
if (val.win.windowDescriptor) {
|
|
1121
|
-
if (val.win.windowDescriptor.minWidth && val.win.windowDescriptor.minWidth < val.limits.minWidth) {
|
|
1122
|
-
Logger.system.warn(`addWindow [${name}] minWidth ${val.win.windowDescriptor.minWidth} less than system minimum ${val.limits.minWidth}`);
|
|
1123
|
-
}
|
|
1124
|
-
if (val.win.windowDescriptor.minHeight && val.win.windowDescriptor.minHeight < val.limits.minHeight) {
|
|
1125
|
-
Logger.system.warn(`addWindow [${name}] minHeight ${val.win.windowDescriptor.minHeight} less than system minimum ${val.limits.minHeight}`);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
val.monitor = this.getMonitorForWindow(val);
|
|
1129
|
-
/* Does not appear to be used
|
|
1130
|
-
if (val.groupName) {
|
|
1131
|
-
const group = this.getGroup(val.groupName);
|
|
1132
|
-
group.addWindow(val);
|
|
1133
|
-
}
|
|
1134
|
-
*/
|
|
1135
|
-
this.buildSnapRelationships(val);
|
|
1136
|
-
}
|
|
1137
|
-
/**
|
|
1138
|
-
* Virtually unsnaps a window from all other windows. This doesn't affect physical positioning. Only the relationships that Docking is a aware of.
|
|
1139
|
-
*/
|
|
1140
|
-
wipeSnapRelationships(name) {
|
|
1141
|
-
const win = this.getWindow(name);
|
|
1142
|
-
if (win && win.snappedWindows) {
|
|
1143
|
-
const snappedWindows = fastClone(win.snappedWindows);
|
|
1144
|
-
for (let i = 0, len = snappedWindows.length; i < len; i++) {
|
|
1145
|
-
const snapObj = snappedWindows[i];
|
|
1146
|
-
const snappedWindow = this.getWindow(snapObj.name);
|
|
1147
|
-
win.removeSnappedWindow(snappedWindow.name);
|
|
1148
|
-
if (snappedWindow) {
|
|
1149
|
-
snappedWindow.removeSnappedWindow(win.name);
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
/**
|
|
1155
|
-
* Removes a window from all groups.
|
|
1156
|
-
*/
|
|
1157
|
-
removeWindowFromAllGroups(win, deleteGroupsWithOneWindow = true) {
|
|
1158
|
-
if (!win) {
|
|
1159
|
-
Logger.system.warn("INVESTIGATE: No win passed to removeWindowFromAllGroups.");
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
const groupNames = fastClone(win.groupNames);
|
|
1163
|
-
for (let i = 0, len = groupNames.length; i < len; i++) {
|
|
1164
|
-
const groupName = groupNames[i];
|
|
1165
|
-
this.removeWindowFromGroup(win.name, groupName, deleteGroupsWithOneWindow);
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
/**
|
|
1169
|
-
* Unregisters the window.
|
|
1170
|
-
* @param {string} name
|
|
1171
|
-
*/
|
|
1172
|
-
removeWindowInternal(name, removeListeners = true) {
|
|
1173
|
-
const win = this.getWindow(name);
|
|
1174
|
-
if (!win) {
|
|
1175
|
-
Logger.system.warn("window was not found:", name);
|
|
1176
|
-
return;
|
|
1177
|
-
}
|
|
1178
|
-
// Removes event listeners from the window.
|
|
1179
|
-
if (removeListeners) {
|
|
1180
|
-
win.removeEventListeners();
|
|
1181
|
-
}
|
|
1182
|
-
if (!win) {
|
|
1183
|
-
Logger.system.warn(`INVESTIGATE: No win found for ${name} in removeWindow.`);
|
|
1184
|
-
}
|
|
1185
|
-
if (win && win.groupNames.length) {
|
|
1186
|
-
// If we aren't removing listeners, we're removing the window for tiling purposes (so it doesn't mess up other windows resizing). In that case, we don't want to remove groups with a single window, which is what the 2nd param here does.
|
|
1187
|
-
this.removeWindowFromAllGroups(win, !removeListeners);
|
|
1188
|
-
}
|
|
1189
|
-
// If we're removing the window that was last cached on mouseDown, wipe the reference. This way, onMouseUp, the window's bounds-changed event will not trigger, and it will not break everything.
|
|
1190
|
-
if (this.movingWindow && this.movingWindow.name === win.name) {
|
|
1191
|
-
this.movingWindow = null;
|
|
1192
|
-
}
|
|
1193
|
-
this.wipeSnapRelationships(win.name);
|
|
1194
|
-
DockingPoolSingleton.remove(name);
|
|
1195
|
-
}
|
|
1196
|
-
/**
|
|
1197
|
-
* Returns an array of window names.
|
|
1198
|
-
*/
|
|
1199
|
-
getWindowNames() {
|
|
1200
|
-
return Object.keys(DockingPoolSingleton.getAll());
|
|
1201
|
-
}
|
|
1202
|
-
/**
|
|
1203
|
-
* @return {dockingPool}
|
|
1204
|
-
*/
|
|
1205
|
-
getWindows() {
|
|
1206
|
-
return DockingPoolSingleton.getAll();
|
|
1207
|
-
}
|
|
1208
|
-
getUnignoredWindows() {
|
|
1209
|
-
const windowIter = DockingPoolSingleton.iterator();
|
|
1210
|
-
const ret = [];
|
|
1211
|
-
for (const win of windowIter) {
|
|
1212
|
-
ret.push(win);
|
|
1213
|
-
}
|
|
1214
|
-
return ret;
|
|
1215
|
-
}
|
|
1216
|
-
/**
|
|
1217
|
-
* Gets a window object by name.
|
|
1218
|
-
* @param {type} name
|
|
1219
|
-
* @param {type} throwError Usually we want to throw the error, but sometimes we use this function to filter (e.g., autoarrange).
|
|
1220
|
-
* @return {type}
|
|
1221
|
-
*/
|
|
1222
|
-
getWindow(name, throwError) {
|
|
1223
|
-
const win = DockingPoolSingleton.get(name, throwError);
|
|
1224
|
-
if (!win && (typeof throwError === "undefined" || throwError)) {
|
|
1225
|
-
Logger.system.warn(`No win found for ${name}.`, Object.keys(DockingPoolSingleton.getAll()));
|
|
1226
|
-
}
|
|
1227
|
-
return win;
|
|
1228
|
-
}
|
|
1229
|
-
/**
|
|
1230
|
-
* returns the monitor that the window is on. If the left edge of the window is on two or more monitors, we calculate the monitor that houses the majority of the window.
|
|
1231
|
-
* @param {string} windowName
|
|
1232
|
-
*/
|
|
1233
|
-
getMonitorForWindow(win) {
|
|
1234
|
-
// Sometimes bad objects get passed into this function. They shouldn't, but they do. if we can't retrieve bounds, it's not a window. Try to get a window. If there's no window, return the first monitor.
|
|
1235
|
-
if (!win.getBounds && win.name)
|
|
1236
|
-
win = this.getWindow(win.name);
|
|
1237
|
-
if (!win.getBounds)
|
|
1238
|
-
return this.getMonitorArray()[0];
|
|
1239
|
-
const boundingBox = win.getBounds();
|
|
1240
|
-
return getMonitorByBounds(boundingBox);
|
|
1241
|
-
}
|
|
1242
|
-
/**
|
|
1243
|
-
* Returns a monitor object.
|
|
1244
|
-
* @param {string} name name of monitor.
|
|
1245
|
-
*/
|
|
1246
|
-
getMonitor(name) {
|
|
1247
|
-
return MonitorPoolSingleton.get(name);
|
|
1248
|
-
}
|
|
1249
|
-
/**
|
|
1250
|
-
* Unregisters a monitor with the calculator.
|
|
1251
|
-
* @param {type} name
|
|
1252
|
-
* @return {type}
|
|
1253
|
-
*/
|
|
1254
|
-
removeMonitor(name) {
|
|
1255
|
-
MonitorPoolSingleton.remove(name);
|
|
1256
|
-
}
|
|
1257
|
-
/**
|
|
1258
|
-
* @return {MonitorPoolSingleton}
|
|
1259
|
-
*/
|
|
1260
|
-
getMonitors() {
|
|
1261
|
-
return MonitorPoolSingleton.getAll();
|
|
1262
|
-
}
|
|
1263
|
-
/**
|
|
1264
|
-
* Returns a list of 'rawMonitors' from the container. These are only available when they are actually passed into the DockableMonitor when its instantiated.
|
|
1265
|
-
*/
|
|
1266
|
-
getRawMonitors() {
|
|
1267
|
-
const rawMonitors = [];
|
|
1268
|
-
const iterator = MonitorPoolSingleton.iterator();
|
|
1269
|
-
for (const monitor of iterator) {
|
|
1270
|
-
rawMonitors.push(monitor.rawMonitor);
|
|
1271
|
-
}
|
|
1272
|
-
return rawMonitors;
|
|
1273
|
-
}
|
|
1274
|
-
/**
|
|
1275
|
-
* Returns the monitors in an array
|
|
1276
|
-
*/
|
|
1277
|
-
getMonitorArray() {
|
|
1278
|
-
const monitors = [];
|
|
1279
|
-
const iterator = MonitorPoolSingleton.iterator();
|
|
1280
|
-
for (const monitor of iterator) {
|
|
1281
|
-
monitors.push(monitor);
|
|
1282
|
-
}
|
|
1283
|
-
return monitors;
|
|
1284
|
-
}
|
|
1285
|
-
/**
|
|
1286
|
-
*
|
|
1287
|
-
*/
|
|
1288
|
-
removeAllMonitors() {
|
|
1289
|
-
const iterator = MonitorPoolSingleton.iterator();
|
|
1290
|
-
for (const monitor of iterator) {
|
|
1291
|
-
this.removeMonitor(monitor.name);
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
/**
|
|
1295
|
-
* Sets the resize throttle period. This allows the system to drop events that occur too quickly.
|
|
1296
|
-
*/
|
|
1297
|
-
setResizeThrottlePeriod(throttlePeriod) {
|
|
1298
|
-
Logger.system.log("DockingService.SetThrottle", JSON.stringify(throttlePeriod));
|
|
1299
|
-
this.resizeEventThrottlePeriod = throttlePeriod;
|
|
1300
|
-
const windowIter = DockingPoolSingleton.iterator();
|
|
1301
|
-
for (const win of windowIter) {
|
|
1302
|
-
win.setResizeThrottlePeriod(throttlePeriod);
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
/**
|
|
1306
|
-
* Sets the opacity that windows take when entering another window's snapping region.
|
|
1307
|
-
*/
|
|
1308
|
-
setSnappingOpacity(opacity) {
|
|
1309
|
-
SNAPPING_OPACITY = opacity;
|
|
1310
|
-
}
|
|
1311
|
-
/**
|
|
1312
|
-
* At one point we weren't sure if we were going to allow groups to snap because of bugs. This is vestigial and should be removed at some point.
|
|
1313
|
-
*/
|
|
1314
|
-
setAllowGroupsToSnap(bool) {
|
|
1315
|
-
ALLOW_GROUPS_TO_SNAP = bool;
|
|
1316
|
-
}
|
|
1317
|
-
/**
|
|
1318
|
-
* Sets the size of the region around windows that will trigger a snap.
|
|
1319
|
-
*/
|
|
1320
|
-
setBufferSize(buffer) {
|
|
1321
|
-
Logger.system.info("Setting buffer size", `${buffer}`);
|
|
1322
|
-
this.bufferSize = buffer;
|
|
1323
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
1324
|
-
for (const win of dockingPoolIterator) {
|
|
1325
|
-
win.setBufferSize(buffer);
|
|
1326
|
-
}
|
|
1327
|
-
const monitorIterator = MonitorPoolSingleton.iterator();
|
|
1328
|
-
let monitor;
|
|
1329
|
-
for (monitor in monitorIterator) {
|
|
1330
|
-
monitor.setBufferSize(buffer);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
/**
|
|
1334
|
-
* Will prevent a window from being added to groups.
|
|
1335
|
-
*/
|
|
1336
|
-
addToGroupBlacklist(windowName) {
|
|
1337
|
-
groupBlacklist.push(windowName);
|
|
1338
|
-
}
|
|
1339
|
-
/**
|
|
1340
|
-
* Will allow a window previously blacklisted to be included in group operations.
|
|
1341
|
-
*/
|
|
1342
|
-
removeFromGroupBlacklist(windowName) {
|
|
1343
|
-
if (groupBlacklist.includes(windowName)) {
|
|
1344
|
-
groupBlacklist.splice(groupBlacklist.indexOf(windowName), 1);
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
/**
|
|
1348
|
-
* Adds a group to the calculator.
|
|
1349
|
-
* @param {type} group
|
|
1350
|
-
*/
|
|
1351
|
-
addGroup(group) {
|
|
1352
|
-
groupPool.add(group.name, group);
|
|
1353
|
-
}
|
|
1354
|
-
/**
|
|
1355
|
-
* Removes a group from the calculator.
|
|
1356
|
-
* @param {type} groupName
|
|
1357
|
-
* @param {Boolean} willReform Whether the group is going to be reformed. This will
|
|
1358
|
-
* tell removeWindowFromGroup if it should modify window taskbar icon visibility.
|
|
1359
|
-
*/
|
|
1360
|
-
removeGroup(groupName, willReform = false) {
|
|
1361
|
-
const group = this.getGroup(groupName);
|
|
1362
|
-
if (group) {
|
|
1363
|
-
const groupIter = this.groupWindowIterator(group);
|
|
1364
|
-
group.willReform = willReform;
|
|
1365
|
-
if (group.getWindowNames().length) {
|
|
1366
|
-
for (const win of groupIter) {
|
|
1367
|
-
this.removeWindowFromGroup(win.name, groupName);
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
groupPool.remove(groupName, false);
|
|
1371
|
-
console.warn(`Tried removing a group that was already removed. ${groupName}.`);
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
/**
|
|
1375
|
-
* Returns a list of groups that are capable of moving together.
|
|
1376
|
-
*/
|
|
1377
|
-
getMovableGroups() {
|
|
1378
|
-
const groupNames = this.getGroupNames();
|
|
1379
|
-
const groups = {};
|
|
1380
|
-
for (let i = 0, len = groupNames.length; i < len; i++) {
|
|
1381
|
-
const groupName = groupNames[i];
|
|
1382
|
-
const group = this.getGroup(groupName);
|
|
1383
|
-
if (group.isMovable) {
|
|
1384
|
-
groups[groupName] = group;
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
return groups;
|
|
1388
|
-
}
|
|
1389
|
-
/**
|
|
1390
|
-
* Returns the group Pool
|
|
1391
|
-
* @return {type}
|
|
1392
|
-
*/
|
|
1393
|
-
getGroups() {
|
|
1394
|
-
return groupPool.getAll();
|
|
1395
|
-
}
|
|
1396
|
-
/**
|
|
1397
|
-
* Gets a group by name.
|
|
1398
|
-
* @param {type} name
|
|
1399
|
-
* @return {type}
|
|
1400
|
-
*/
|
|
1401
|
-
getGroup(name) {
|
|
1402
|
-
return groupPool.get(name, false);
|
|
1403
|
-
}
|
|
1404
|
-
/**
|
|
1405
|
-
* Gets an array of group names.
|
|
1406
|
-
* @return {type}
|
|
1407
|
-
*/
|
|
1408
|
-
getGroupNames() {
|
|
1409
|
-
const names = [];
|
|
1410
|
-
const iter = groupPool.iterator();
|
|
1411
|
-
for (const group of iter) {
|
|
1412
|
-
names.push(group.name);
|
|
1413
|
-
}
|
|
1414
|
-
return names;
|
|
1415
|
-
}
|
|
1416
|
-
/**
|
|
1417
|
-
* Imagine 3 windows snapped horizontally. All are grouped ([A][B][C]). You ungroup B. This function will remove A and C. It iterates through all of the windows in the group and makes sure it's still attached to the group.
|
|
1418
|
-
*/
|
|
1419
|
-
checkGroupMembership(win) {
|
|
1420
|
-
if (!win) {
|
|
1421
|
-
Logger.system.warn("INVESTIGATE: No win passed in to checkGroupMembership.");
|
|
1422
|
-
return;
|
|
1423
|
-
}
|
|
1424
|
-
const groupNames = fastClone(win.groupNames);
|
|
1425
|
-
const snappedWindowGroupNames = win.snappedWindows.map((snapObj) => {
|
|
1426
|
-
const snapWin = this.getWindow(snapObj.name);
|
|
1427
|
-
if (snapWin) {
|
|
1428
|
-
return snapWin.groupNames;
|
|
1429
|
-
}
|
|
1430
|
-
Logger.system.warn(`INVESTIGATE: SnapWin does not exist. ${JSON.stringify(snapObj)}.`);
|
|
1431
|
-
return [];
|
|
1432
|
-
});
|
|
1433
|
-
groupNames.forEach((groupName) => {
|
|
1434
|
-
const hasSnappedWindowAttachedToGroup = snappedWindowGroupNames.some((arr) => arr.includes(groupName));
|
|
1435
|
-
if (!hasSnappedWindowAttachedToGroup) {
|
|
1436
|
-
this.removeWindowFromGroup(win.name, groupName);
|
|
1437
|
-
}
|
|
1438
|
-
});
|
|
1439
|
-
}
|
|
1440
|
-
/**
|
|
1441
|
-
* Removes a window from a group. When tiling, we do not delete groups with only one window. We could be doing an operation on a group with two windows, and we want to retain group membership so that hole-filling works appropriately.
|
|
1442
|
-
*/
|
|
1443
|
-
removeWindowFromGroup(windowName, groupName, deleteGroupsWithOneWindow = true, updateAOT = true) {
|
|
1444
|
-
const win = this.getWindow(windowName);
|
|
1445
|
-
if (!win || !groupName || !win.groupNames.includes(groupName)) {
|
|
1446
|
-
return;
|
|
1447
|
-
}
|
|
1448
|
-
win.groupNames.splice(win.groupNames.indexOf(groupName), 1);
|
|
1449
|
-
const group = this.getGroup(groupName);
|
|
1450
|
-
if (!group) {
|
|
1451
|
-
return;
|
|
1452
|
-
}
|
|
1453
|
-
group.removeWindow(win.name, updateAOT);
|
|
1454
|
-
if (group.isMovable) {
|
|
1455
|
-
// if the window was in a movable group, it's likely its taskbar icon was hidden. Show it.
|
|
1456
|
-
this.setTaskbarIconVisiblityForWindow({
|
|
1457
|
-
win,
|
|
1458
|
-
reason: group.willReform
|
|
1459
|
-
? TASKBAR_ICON_CHANGE_REASONS.MOVABLE_GROUP_BEING_DESTROYED
|
|
1460
|
-
: TASKBAR_ICON_CHANGE_REASONS.LEAVING_MOVABLE_GROUP,
|
|
1461
|
-
});
|
|
1462
|
-
// When a window leaves a group, we call 'fixGroupMembership', which destroys and reforms all
|
|
1463
|
-
// of the groups. When we do this, we don't need to modify the taskbar icon's visibility.
|
|
1464
|
-
// It'll be handled when the groups are reformed.
|
|
1465
|
-
if (!group.willReform) {
|
|
1466
|
-
this.setTaskbarIconForGroup(group);
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
if (deleteGroupsWithOneWindow && group.getWindowNames().length === 1) {
|
|
1470
|
-
const lastWindowName = group.getWindowNames()[0];
|
|
1471
|
-
const lastWindow = this.getWindow(lastWindowName);
|
|
1472
|
-
if (group.isMovable) {
|
|
1473
|
-
// If the window is the last in the group, make sure it has a visible taskbar icon.
|
|
1474
|
-
this.setTaskbarIconVisiblityForWindow({
|
|
1475
|
-
win: lastWindow,
|
|
1476
|
-
reason: TASKBAR_ICON_CHANGE_REASONS.MOVABLE_GROUP_BEING_DESTROYED,
|
|
1477
|
-
});
|
|
1478
|
-
}
|
|
1479
|
-
this.removeWindowFromGroup(lastWindowName, group.name, true, updateAOT);
|
|
1480
|
-
this.removeGroup(group.name);
|
|
1481
|
-
}
|
|
1482
|
-
if (!group.getWindowNames().length) {
|
|
1483
|
-
this.removeGroup(group.name);
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
/**
|
|
1487
|
-
* Single entry point for changing the taskbar icon's visibility.
|
|
1488
|
-
* At present, taskbar icon status is only changed when a window leaves or joins a movable group.
|
|
1489
|
-
*/
|
|
1490
|
-
setTaskbarIconVisiblityForWindow(params) {
|
|
1491
|
-
const { win, reason } = params;
|
|
1492
|
-
switch (reason) {
|
|
1493
|
-
case TASKBAR_ICON_CHANGE_REASONS.IS_MOVE_ANCHOR:
|
|
1494
|
-
case TASKBAR_ICON_CHANGE_REASONS.MOVABLE_GROUP_BEING_DESTROYED:
|
|
1495
|
-
case TASKBAR_ICON_CHANGE_REASONS.LEAVING_MOVABLE_GROUP: {
|
|
1496
|
-
win.showTaskbarIcon(true);
|
|
1497
|
-
break;
|
|
1498
|
-
}
|
|
1499
|
-
case TASKBAR_ICON_CHANGE_REASONS.NOT_MOVE_ANCHOR: {
|
|
1500
|
-
win.hideTaskbarIcon();
|
|
1501
|
-
break;
|
|
1502
|
-
}
|
|
1503
|
-
default: {
|
|
1504
|
-
Logger.system.error("SetTaskbarIconVisibility, no case statement found for", reason);
|
|
1505
|
-
break;
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
/**
|
|
1510
|
-
* Groups n-Windows.
|
|
1511
|
-
*
|
|
1512
|
-
* @param {any} params
|
|
1513
|
-
* @param {any} cb
|
|
1514
|
-
*/
|
|
1515
|
-
groupWindows(params, cb) {
|
|
1516
|
-
const groupName = params.groupName || uuidv4();
|
|
1517
|
-
const isMovable = typeof params.isMovable !== "undefined" ? params.isMovable : false;
|
|
1518
|
-
// There must be at least two windows to create a group
|
|
1519
|
-
if (params.windows.length <= 1)
|
|
1520
|
-
return;
|
|
1521
|
-
for (let i = 0, len = params.windows.length; i < len; i++) {
|
|
1522
|
-
const windowName = params.windows[i];
|
|
1523
|
-
const win = this.getWindow(windowName);
|
|
1524
|
-
// Only group windows if they are allowed to. e.g. prevent docking of toolbar.
|
|
1525
|
-
if (win.canGroup) {
|
|
1526
|
-
// Don't set icon visibility inside of addWindowToGroup.
|
|
1527
|
-
// We'll handle that once the group is formed.
|
|
1528
|
-
this.addWindowToGroup({
|
|
1529
|
-
win,
|
|
1530
|
-
groupName,
|
|
1531
|
-
isMovable,
|
|
1532
|
-
handleIcons: false,
|
|
1533
|
-
});
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
if (isMovable) {
|
|
1537
|
-
const group = this.getGroup(groupName);
|
|
1538
|
-
this.setTaskbarIconForGroup(group);
|
|
1539
|
-
}
|
|
1540
|
-
if (cb) {
|
|
1541
|
-
cb(null);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
/**
|
|
1545
|
-
* Given a group, this method will make sure only one window (the top right window) has a visible taskbar icon.
|
|
1546
|
-
* This method is called whenever a window is added to or removed from a group.
|
|
1547
|
-
* @param {DockableGroup} group
|
|
1548
|
-
*/
|
|
1549
|
-
setTaskbarIconForGroup(group) {
|
|
1550
|
-
const iter = this.groupWindowIterator(group);
|
|
1551
|
-
// It's possible to get into this case...we don't want to.
|
|
1552
|
-
if (group.getWindowArray().length === 0)
|
|
1553
|
-
return;
|
|
1554
|
-
const groupAnchor = group.getMoveAnchor("BottomLeft");
|
|
1555
|
-
// see below for why we're doing everything in this order.
|
|
1556
|
-
for (const win of iter) {
|
|
1557
|
-
if (groupAnchor.name !== win.name) {
|
|
1558
|
-
this.setTaskbarIconVisiblityForWindow({
|
|
1559
|
-
win,
|
|
1560
|
-
reason: TASKBAR_ICON_CHANGE_REASONS.NOT_MOVE_ANCHOR,
|
|
1561
|
-
});
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
/**
|
|
1565
|
-
* There is a timing gap in stack creation.
|
|
1566
|
-
* Step 1: Stack joins docking.
|
|
1567
|
-
* Step 2: Stack joins any group that the visible window is part of.
|
|
1568
|
-
* **At this point, both the stack and the visible window are in the same group.**
|
|
1569
|
-
* Step 3: Visible window deregisters.
|
|
1570
|
-
* Before the visible window deregisters, we start trying to figure out which taskbar
|
|
1571
|
-
* icon should be visible. What was happening here was that
|
|
1572
|
-
* we'd try to find the group anchor for this group, and it would come back as
|
|
1573
|
-
* the visible window in the stack.
|
|
1574
|
-
* So we'd show it's taskbar icon.
|
|
1575
|
-
* Then we kept looping.
|
|
1576
|
-
* When we got to the stack, we'd say 'Oh, this isn't the anchor', so its taskbar icon would
|
|
1577
|
-
* be hidden. As a result, the group could end up without a visible taskbar icon.
|
|
1578
|
-
*
|
|
1579
|
-
* Docking knows nothing about stacks and not stacks. In order to keep that separated,
|
|
1580
|
-
* we will hide all non-group anchor icons first, and then show the group anchor's icon.
|
|
1581
|
-
*/
|
|
1582
|
-
this.setTaskbarIconVisiblityForWindow({
|
|
1583
|
-
win: this.getWindow(groupAnchor.name),
|
|
1584
|
-
reason: TASKBAR_ICON_CHANGE_REASONS.IS_MOVE_ANCHOR,
|
|
1585
|
-
});
|
|
1586
|
-
}
|
|
1587
|
-
/**
|
|
1588
|
-
* @param {type} groupName
|
|
1589
|
-
* @param {dockableWindow} win
|
|
1590
|
-
*/
|
|
1591
|
-
addWindowToGroup(params, cb) {
|
|
1592
|
-
let { groupName, win, ungroupedAlwaysOnTopState } = params;
|
|
1593
|
-
if (!win) {
|
|
1594
|
-
Logger.system.warn("INVESTIGATE: No win passed in to addWindowToGroup.");
|
|
1595
|
-
return;
|
|
1596
|
-
}
|
|
1597
|
-
// in the explicit paradigm, groups default to not being immobile, but resizable.
|
|
1598
|
-
const isMovable = typeof params.isMovable !== "undefined" ? params.isMovable : false;
|
|
1599
|
-
const isAlwaysOnTop = typeof params.isAlwaysOnTop !== "undefined" ? params.isAlwaysOnTop : false;
|
|
1600
|
-
if (groupBlacklist.includes(win.name))
|
|
1601
|
-
return;
|
|
1602
|
-
// If window is already part of the group then don't do anything
|
|
1603
|
-
if (win.groupNames.includes(groupName))
|
|
1604
|
-
return;
|
|
1605
|
-
const groupParams = {
|
|
1606
|
-
name: groupName,
|
|
1607
|
-
isMovable,
|
|
1608
|
-
isAlwaysOnTop,
|
|
1609
|
-
ungroupedAlwaysOnTopState,
|
|
1610
|
-
MINIMUM_HEIGHT: 0,
|
|
1611
|
-
MINIMUM_WIDTH: 0,
|
|
1612
|
-
};
|
|
1613
|
-
let group = this.getGroup(groupName);
|
|
1614
|
-
if (!group) {
|
|
1615
|
-
if (!groupName) {
|
|
1616
|
-
groupName = uuidv4();
|
|
1617
|
-
}
|
|
1618
|
-
groupParams.name = groupName;
|
|
1619
|
-
groupParams.MINIMUM_HEIGHT = this.MINIMUM_HEIGHT;
|
|
1620
|
-
groupParams.MINIMUM_WIDTH = this.MINIMUM_WIDTH;
|
|
1621
|
-
group = new DockableGroup(groupParams);
|
|
1622
|
-
this.addGroup(group);
|
|
1623
|
-
}
|
|
1624
|
-
this.ensureNotInTwoGroups(win, group);
|
|
1625
|
-
win.groupNames.push(groupName);
|
|
1626
|
-
group.addWindow(win);
|
|
1627
|
-
if (group.isMovable) {
|
|
1628
|
-
// if this param is undefined or true, change the icon visibility.
|
|
1629
|
-
if (params.handleIcons !== false) {
|
|
1630
|
-
this.setTaskbarIconForGroup(group);
|
|
1631
|
-
}
|
|
1632
|
-
group.bringToFront({});
|
|
1633
|
-
}
|
|
1634
|
-
cb === null || cb === void 0 ? void 0 : cb(group);
|
|
1635
|
-
return group;
|
|
1636
|
-
}
|
|
1637
|
-
/**
|
|
1638
|
-
* Checks if windows in a group are on monitor. If not move the group on monitor so at least one window in the group
|
|
1639
|
-
* is fully on monitor.
|
|
1640
|
-
* Currently this is used on spawn to handle monitor changes when Finsemble wasn't running or a different workspace was loaded.
|
|
1641
|
-
* @param {*} name
|
|
1642
|
-
*/
|
|
1643
|
-
async checkAndFixGroupPosition(name) {
|
|
1644
|
-
const dockableWindow = this.getWindow(name);
|
|
1645
|
-
const group = this.getMovableGroup(name);
|
|
1646
|
-
if (dockableWindow && group) {
|
|
1647
|
-
const currentBounds = {
|
|
1648
|
-
top: dockableWindow.top,
|
|
1649
|
-
bottom: dockableWindow.bottom,
|
|
1650
|
-
left: dockableWindow.left,
|
|
1651
|
-
right: dockableWindow.right,
|
|
1652
|
-
width: dockableWindow.width,
|
|
1653
|
-
height: dockableWindow.height,
|
|
1654
|
-
name: dockableWindow.name,
|
|
1655
|
-
};
|
|
1656
|
-
const newBounds = adjustBoundsToBeOnMonitor(this.monitorsInstance, currentBounds);
|
|
1657
|
-
if (!checkIfBoundsAreEqual(currentBounds, newBounds)) {
|
|
1658
|
-
group.deferSystemMove({ name, bounds: newBounds }, this);
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
/**
|
|
1663
|
-
* Vestigial function; used to pop a window out of a group. Can likely be removed in the future.
|
|
1664
|
-
*/
|
|
1665
|
-
ejectWindow(name) {
|
|
1666
|
-
const win = this.getWindow(name);
|
|
1667
|
-
const newBounds = win;
|
|
1668
|
-
newBounds.left = newBounds.left + 40;
|
|
1669
|
-
newBounds.top = newBounds.top - 40;
|
|
1670
|
-
newBounds.name = win.name;
|
|
1671
|
-
this.moveWindow(newBounds);
|
|
1672
|
-
}
|
|
1673
|
-
/**
|
|
1674
|
-
* @return {boolean}
|
|
1675
|
-
*/
|
|
1676
|
-
getGroupMode() {
|
|
1677
|
-
return this.groupMode;
|
|
1678
|
-
}
|
|
1679
|
-
/**
|
|
1680
|
-
* @param {object} groupMade
|
|
1681
|
-
* @param {boolean} groupMade.enabled Whether group mode is enabled.
|
|
1682
|
-
* @param {number} groupMode.headerHeight How large the header is in windows. This shouldn't be in this config. So bad.
|
|
1683
|
-
* @param {number} groupMode.groupTileBuffer How large the buffer is on the edge of a group to trigger a group-tile operation.
|
|
1684
|
-
* @param {boolean} groupMode.allowSnappedWindowsToResize Whether snapped windows will resize as a group.
|
|
1685
|
-
* @param {boolean} groupMode.fillHolesOnUndock Whether leaving a group triggers a hole-filling operation
|
|
1686
|
-
* @param {boolean} groupMode.undockDisbandsEntireGroup Whether clicking the undock button on one window will disband the entire group.
|
|
1687
|
-
* @param {boolean} groupMode.requireRectangularityForGroupResize Whether a group must be a rectangle to scale the individual windows as a unit.
|
|
1688
|
-
*/
|
|
1689
|
-
setGroupMode(groupMode) {
|
|
1690
|
-
const bool = groupMode.enabled;
|
|
1691
|
-
if (!bool) {
|
|
1692
|
-
this.getGroupNames().forEach((groupName) => {
|
|
1693
|
-
this.removeGroup(groupName);
|
|
1694
|
-
});
|
|
1695
|
-
}
|
|
1696
|
-
else if (bool) {
|
|
1697
|
-
this.constituteGroups();
|
|
1698
|
-
if (groupMode.groupTileBuffer)
|
|
1699
|
-
this.groupTileBuffer = groupMode.groupTileBuffer;
|
|
1700
|
-
if (groupMode.headerHeight)
|
|
1701
|
-
this.headerHeight = groupMode.headerHeight;
|
|
1702
|
-
}
|
|
1703
|
-
if (typeof groupMode.allowSnappedWindowsToResize === "undefined")
|
|
1704
|
-
groupMode.allowSnappedWindowsToResize = true;
|
|
1705
|
-
if (typeof groupMode.fillHolesOnUndock === "undefined")
|
|
1706
|
-
groupMode.fillHolesOnUndock = true;
|
|
1707
|
-
if (typeof groupMode.undockDisbandsEntireGroup === "undefined")
|
|
1708
|
-
groupMode.undockDisbandsEntireGroup = false;
|
|
1709
|
-
if (typeof groupMode.requireRectangularityForGroupResize === "undefined")
|
|
1710
|
-
groupMode.requireRectangularityForGroupResize = true;
|
|
1711
|
-
this.groupMode = groupMode;
|
|
1712
|
-
}
|
|
1713
|
-
/**
|
|
1714
|
-
* Adds useful properties to a raw request.
|
|
1715
|
-
* @param {moveRequest} req
|
|
1716
|
-
* @return {moveRequest}
|
|
1717
|
-
*/
|
|
1718
|
-
setMoveRequest(req, win) {
|
|
1719
|
-
if (!win) {
|
|
1720
|
-
win = this.getWindow(req.name);
|
|
1721
|
-
}
|
|
1722
|
-
/**
|
|
1723
|
-
* If you call setBounds on a window that is maximized, subsequent move requests will come in as though the window's
|
|
1724
|
-
* left edge never moved, until mouseUp happens. This boolean helps us get around this bug.
|
|
1725
|
-
*/
|
|
1726
|
-
if (win.shouldOffsetByMouse) {
|
|
1727
|
-
req.left = req.mousePosition.left - req.width / 2;
|
|
1728
|
-
req.right = req.left + req.width;
|
|
1729
|
-
}
|
|
1730
|
-
req.windowBoundingBox = BoxMath.getWindowBoundingBox(req);
|
|
1731
|
-
req.innerBuffer = this.getInnerBoundingBox(req);
|
|
1732
|
-
req.snappingRegions = BoxMath.getSnappingRegions(req, this.bufferSize);
|
|
1733
|
-
this.moveRequest = req;
|
|
1734
|
-
return req;
|
|
1735
|
-
}
|
|
1736
|
-
/**
|
|
1737
|
-
* @param {dockableWindow} win
|
|
1738
|
-
*/
|
|
1739
|
-
setStationaryWindow(win) {
|
|
1740
|
-
globalStationaryWindow = win;
|
|
1741
|
-
}
|
|
1742
|
-
/**
|
|
1743
|
-
* @param {dockableWindow} win
|
|
1744
|
-
*/
|
|
1745
|
-
setMovingWindow(win) {
|
|
1746
|
-
this.movingWindow = win;
|
|
1747
|
-
}
|
|
1748
|
-
/**
|
|
1749
|
-
* Convenience function I used for like 2 minutes.
|
|
1750
|
-
* @param {dockableWindow} stationary
|
|
1751
|
-
* @param {dockableWindow} moving
|
|
1752
|
-
*/
|
|
1753
|
-
setWindows(stationary, moving) {
|
|
1754
|
-
globalStationaryWindow = stationary;
|
|
1755
|
-
this.movingWindow = moving;
|
|
1756
|
-
}
|
|
1757
|
-
/** **************************************************
|
|
1758
|
-
* *
|
|
1759
|
-
* Calculators - Multiple Positions/Sizes *
|
|
1760
|
-
* *
|
|
1761
|
-
*************************************************** */
|
|
1762
|
-
/**
|
|
1763
|
-
* when a non-docking movement is made, we don't grab the bounds changing events.
|
|
1764
|
-
* So this updates everything. Example: auto-arrange.
|
|
1765
|
-
*/
|
|
1766
|
-
updateWindowPositions() {
|
|
1767
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
1768
|
-
for (const win of dockingPoolIterator) {
|
|
1769
|
-
win.updateState();
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
/**
|
|
1773
|
-
* Returns the movableGroup for a window.
|
|
1774
|
-
*/
|
|
1775
|
-
getMovableGroup(windowName) {
|
|
1776
|
-
const win = this.getWindow(windowName, false);
|
|
1777
|
-
if (!win) {
|
|
1778
|
-
Logger.system.debug(`INVESTIGATE: getMovableGroup failure. No win found for ${windowName}`);
|
|
1779
|
-
return null;
|
|
1780
|
-
}
|
|
1781
|
-
for (let i = 0, len = win.groupNames.length; i < len; i++) {
|
|
1782
|
-
const groupName = win.groupNames[i];
|
|
1783
|
-
const group = this.getGroup(groupName);
|
|
1784
|
-
if (group.isMovable) {
|
|
1785
|
-
return group;
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
return null;
|
|
1789
|
-
}
|
|
1790
|
-
/**
|
|
1791
|
-
* Returns the immobile group for a window. This is one where it is snapped to other windows, but not explicitly grouped by the user.
|
|
1792
|
-
*/
|
|
1793
|
-
getImmobileGroup(windowName) {
|
|
1794
|
-
const win = this.getWindow(windowName, false);
|
|
1795
|
-
if (!win) {
|
|
1796
|
-
Logger.system.debug(`INVESTIGATE: getImmobileGroup failure. No win found for ${windowName}`);
|
|
1797
|
-
return null;
|
|
1798
|
-
}
|
|
1799
|
-
for (let i = 0, len = win.groupNames.length; i < len; i++) {
|
|
1800
|
-
const groupName = win.groupNames[i];
|
|
1801
|
-
const group = this.getGroup(groupName);
|
|
1802
|
-
if (group.isMovable) {
|
|
1803
|
-
continue;
|
|
1804
|
-
}
|
|
1805
|
-
return group;
|
|
1806
|
-
}
|
|
1807
|
-
return null;
|
|
1808
|
-
}
|
|
1809
|
-
/**
|
|
1810
|
-
* Basically just code flow controller. Figures out whether the move will affect just a couple, a single window, or all windows in the group.
|
|
1811
|
-
* @param {moveRequest} moveRequest
|
|
1812
|
-
* @param {function} cb
|
|
1813
|
-
*/
|
|
1814
|
-
handleGroup(moveRequest, cb) {
|
|
1815
|
-
this.setMoveRequest(moveRequest);
|
|
1816
|
-
if (!this.movingGroup)
|
|
1817
|
-
return;
|
|
1818
|
-
// Before beginning a group's move function set each individual window's 'finishedMove' property
|
|
1819
|
-
// This is necessary because the logic which determines whether to set a window's internal bounds after a window aero movement will check to make sure the _user_ is not physically moving the window. As long as the mouse is not causing the movement, and instead the system, we mark all the windows as finished = true. This is just the opposite of that, the group is beginning a movement, so we set finishedMove = false.
|
|
1820
|
-
for (const windowName in this.movingGroup.windows) {
|
|
1821
|
-
const win = this.getWindow(windowName);
|
|
1822
|
-
win.win._startMove();
|
|
1823
|
-
}
|
|
1824
|
-
if (this.movingGroup.isMovable && this.moveRequest && this.moveRequest.changeType === 0) {
|
|
1825
|
-
// Before beginning a group's move function set each individual window's 'finished' property
|
|
1826
|
-
// This is necessary because the logic which determines whether to set a window's internal bounds after a window aero movement will check to make sure the _user_ is not physically moving the window. As long as the mouse is not causing the movement, and instead the system, we mark all the windows as finished = true. This is just the opposite of that, the group is beginning a movement, so we set finished = false.
|
|
1827
|
-
for (const windowName in this.movingGroup.windows) {
|
|
1828
|
-
const win = this.getWindow(windowName);
|
|
1829
|
-
win.finished = false;
|
|
1830
|
-
}
|
|
1831
|
-
this.handleGroupMove(this.moveRequest, cb); // Move a group
|
|
1832
|
-
}
|
|
1833
|
-
else {
|
|
1834
|
-
if (this.resizeObject.scalingGroup) {
|
|
1835
|
-
this.movingAGroupOfWindows = true;
|
|
1836
|
-
}
|
|
1837
|
-
else {
|
|
1838
|
-
this.resizeInteriorWindow(this.moveRequest);
|
|
1839
|
-
}
|
|
1840
|
-
cb({ finished: true });
|
|
1841
|
-
}
|
|
1842
|
-
}
|
|
1843
|
-
/**
|
|
1844
|
-
* Kills any gaps that may have happened after scaling a group proportionately.
|
|
1845
|
-
*/
|
|
1846
|
-
eliminateGaps() {
|
|
1847
|
-
const adjustWindow = (win, windowName, bounds) => {
|
|
1848
|
-
const snappedWin = this.getWindow(windowName);
|
|
1849
|
-
const sharedEdges = win.getSharedEdges(snappedWin, this.bufferSize);
|
|
1850
|
-
for (const edge in sharedEdges) {
|
|
1851
|
-
const oppEdge = OPPOSITE_EDGE_MAP[edge];
|
|
1852
|
-
if (!sharedEdges[edge] || win[edge] === snappedWin[oppEdge])
|
|
1853
|
-
continue;
|
|
1854
|
-
bounds[edge] = snappedWin[oppEdge];
|
|
1855
|
-
expandBoundsAgainstFixedEdge(bounds, edge);
|
|
1856
|
-
}
|
|
1857
|
-
bounds.name = win.name;
|
|
1858
|
-
this.moveWindow(bounds);
|
|
1859
|
-
};
|
|
1860
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
1861
|
-
for (let win of dockingPoolIterator) {
|
|
1862
|
-
const snappableWindows = this.getSnappableWindows(win);
|
|
1863
|
-
let bounds = win.getBounds();
|
|
1864
|
-
snappableWindows.forEach((windowName) => {
|
|
1865
|
-
adjustWindow(win, windowName, bounds);
|
|
1866
|
-
});
|
|
1867
|
-
}
|
|
1868
|
-
}
|
|
1869
|
-
/**
|
|
1870
|
-
* Helper function for snapWindow
|
|
1871
|
-
*/
|
|
1872
|
-
getIntersection({ request, stationaryWindow, region, stationaryBoundingBoxes, movingBoundingBoxes, }) {
|
|
1873
|
-
if (request.changeType === 0) {
|
|
1874
|
-
request.movingRegion = this.getIntersections(request, stationaryWindow, region)[0];
|
|
1875
|
-
}
|
|
1876
|
-
if (!request.movingRegion)
|
|
1877
|
-
return null;
|
|
1878
|
-
let edgesToCheck = [];
|
|
1879
|
-
// When we have diagonal resizes of windows we need to check if we have
|
|
1880
|
-
// intersections against two edges instead of one eg. topLeft requires to check for
|
|
1881
|
-
// both top AND left
|
|
1882
|
-
switch (request.movingRegion) {
|
|
1883
|
-
case "topLeft":
|
|
1884
|
-
case "leftTop":
|
|
1885
|
-
edgesToCheck.push("top", "left");
|
|
1886
|
-
break;
|
|
1887
|
-
case "topRight":
|
|
1888
|
-
case "rightTop":
|
|
1889
|
-
edgesToCheck.push("top", "right");
|
|
1890
|
-
break;
|
|
1891
|
-
case "bottomLeft":
|
|
1892
|
-
case "leftBottom":
|
|
1893
|
-
edgesToCheck.push("bottom", "left");
|
|
1894
|
-
break;
|
|
1895
|
-
case "bottomRight":
|
|
1896
|
-
case "rightBottom":
|
|
1897
|
-
edgesToCheck.push("bottom", "right");
|
|
1898
|
-
break;
|
|
1899
|
-
default:
|
|
1900
|
-
edgesToCheck.push(request.movingRegion);
|
|
1901
|
-
break;
|
|
1902
|
-
}
|
|
1903
|
-
const intersectionExists = edgesToCheck.some((edge) => BoxMath.intersectBoundingBoxes(stationaryBoundingBoxes[region], movingBoundingBoxes[edge]));
|
|
1904
|
-
if (intersectionExists) {
|
|
1905
|
-
return {
|
|
1906
|
-
stationaryRegion: region,
|
|
1907
|
-
movingRegion: request.movingRegion,
|
|
1908
|
-
};
|
|
1909
|
-
}
|
|
1910
|
-
return null;
|
|
1911
|
-
}
|
|
1912
|
-
/**
|
|
1913
|
-
* Helper function for snapWindow
|
|
1914
|
-
*/
|
|
1915
|
-
processIntersection(request, stationaryWindow, intersection) {
|
|
1916
|
-
this.intersection = intersection;
|
|
1917
|
-
// changeType 0 is a move (so get new coordinates) otherwise it's a resize (so adjust its size)
|
|
1918
|
-
const updatedRequest = request.changeType === 0
|
|
1919
|
-
? this.getNewCoordinates({
|
|
1920
|
-
intersection,
|
|
1921
|
-
stationaryWindow: stationaryWindow,
|
|
1922
|
-
request,
|
|
1923
|
-
})
|
|
1924
|
-
: this.adjustSize({
|
|
1925
|
-
intersection,
|
|
1926
|
-
stationaryWindow: stationaryWindow,
|
|
1927
|
-
request,
|
|
1928
|
-
});
|
|
1929
|
-
// if moving window isn't in a group, see if stationary window is. if so, add moving to the stationary group. if not, create a new group with them.
|
|
1930
|
-
// GroupAction is just a placeholder. We only modify groups on mouseDown defers this
|
|
1931
|
-
const sharedEdges = stationaryWindow.getSharedEdges(request);
|
|
1932
|
-
const sharedEdgesArr = Object.keys(sharedEdges).map((edge) => {
|
|
1933
|
-
return { edge: sharedEdges[edge] };
|
|
1934
|
-
});
|
|
1935
|
-
if (!sharedEdgesArr.some((obj) => obj.edge)) {
|
|
1936
|
-
const sharedCorners = stationaryWindow.getSharedCorners(request);
|
|
1937
|
-
const sharedCornersArr = Object.keys(sharedCorners).map((corner) => {
|
|
1938
|
-
return { corner: sharedCorners[corner] };
|
|
1939
|
-
});
|
|
1940
|
-
// Successful modified request
|
|
1941
|
-
if (!sharedCornersArr.some((obj) => obj.corner)) {
|
|
1942
|
-
return {
|
|
1943
|
-
updatedRequest: request,
|
|
1944
|
-
match: true,
|
|
1945
|
-
};
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
if (!groupBlacklist.includes(stationaryWindow.name)) {
|
|
1949
|
-
this.groupAction = this.getDeferredGroupAction(globalStationaryWindow, this.movingWindow);
|
|
1950
|
-
}
|
|
1951
|
-
return {
|
|
1952
|
-
updatedRequest,
|
|
1953
|
-
match: false,
|
|
1954
|
-
};
|
|
1955
|
-
}
|
|
1956
|
-
/** **************************************************
|
|
1957
|
-
* *
|
|
1958
|
-
* Calculators - Individual Window Position/Size *
|
|
1959
|
-
* *
|
|
1960
|
-
*************************************************** */
|
|
1961
|
-
/**
|
|
1962
|
-
* Returns a modified moveRequest. If the code gets here, it's because the moving window was inside of the stationary window's buffer, and a snap needed to occur.
|
|
1963
|
-
* @param {moveRequest} request
|
|
1964
|
-
* @return {moveRequest}
|
|
1965
|
-
*/
|
|
1966
|
-
snapWindow(request) {
|
|
1967
|
-
// order matters here. corners should take precedence, as they'll also handle the vanilla bottom/top/left/right order. The algorithm stops with the first intersection.
|
|
1968
|
-
const regions = [
|
|
1969
|
-
"bottomLeft",
|
|
1970
|
-
"bottomRight",
|
|
1971
|
-
"topLeft",
|
|
1972
|
-
"topRight",
|
|
1973
|
-
"leftTop",
|
|
1974
|
-
"leftBottom",
|
|
1975
|
-
"rightTop",
|
|
1976
|
-
"rightBottom",
|
|
1977
|
-
"top",
|
|
1978
|
-
"left",
|
|
1979
|
-
"right",
|
|
1980
|
-
"bottom",
|
|
1981
|
-
];
|
|
1982
|
-
if (!globalStationaryWindow)
|
|
1983
|
-
return;
|
|
1984
|
-
const stationaryBoundingBoxes = globalStationaryWindow.snappingRegions;
|
|
1985
|
-
const movingBoundingBoxes = request.snappingRegions;
|
|
1986
|
-
const stationaryWindow = globalStationaryWindow;
|
|
1987
|
-
let intersection = null;
|
|
1988
|
-
for (let i = 0; i < regions.length; i++) {
|
|
1989
|
-
const region = regions[i];
|
|
1990
|
-
if (intersection && request.changeType !== 0)
|
|
1991
|
-
break;
|
|
1992
|
-
intersection = null;
|
|
1993
|
-
// Two checks:
|
|
1994
|
-
// 1) Is it inside of the stationary window? If so, exit.
|
|
1995
|
-
// 2) Is it within one of the region bounding boxes.
|
|
1996
|
-
if (BoxMath.intersectBoundingBoxes(stationaryBoundingBoxes[region], request.windowBoundingBox)) {
|
|
1997
|
-
intersection = this.getIntersection({
|
|
1998
|
-
request,
|
|
1999
|
-
stationaryWindow: stationaryWindow,
|
|
2000
|
-
region,
|
|
2001
|
-
stationaryBoundingBoxes,
|
|
2002
|
-
movingBoundingBoxes,
|
|
2003
|
-
});
|
|
2004
|
-
}
|
|
2005
|
-
if (intersection) {
|
|
2006
|
-
const { updatedRequest, match } = this.processIntersection(request, stationaryWindow, intersection);
|
|
2007
|
-
request = updatedRequest;
|
|
2008
|
-
if (match)
|
|
2009
|
-
break;
|
|
2010
|
-
}
|
|
2011
|
-
else {
|
|
2012
|
-
this.intersection = {
|
|
2013
|
-
stationaryRegion: null,
|
|
2014
|
-
movingRegion: null,
|
|
2015
|
-
};
|
|
2016
|
-
}
|
|
2017
|
-
}
|
|
2018
|
-
return request;
|
|
2019
|
-
}
|
|
2020
|
-
/**
|
|
2021
|
-
* When moving a window, we don't want to add it to a group until all the calculations are complete. If two windows snap, this function is called. It figures out which group that the windows should form. Note: It always forms an immobile group (one that allows shared-border resizing). This is because a snap is not an explicit group.
|
|
2022
|
-
*/
|
|
2023
|
-
getDeferredGroupAction(stationaryWin, movingWin) {
|
|
2024
|
-
var _a;
|
|
2025
|
-
const action = this.groupAction;
|
|
2026
|
-
const stationaryGroup = this.getImmobileGroup(stationaryWin.name);
|
|
2027
|
-
const movingWindowGroup = this.getImmobileGroup(movingWin.name);
|
|
2028
|
-
if (stationaryGroup && !movingWindowGroup) {
|
|
2029
|
-
action.name = stationaryGroup.name;
|
|
2030
|
-
action.windows[movingWin.name] = true;
|
|
2031
|
-
}
|
|
2032
|
-
else if (movingWindowGroup && !stationaryGroup) {
|
|
2033
|
-
action.name = movingWindowGroup.name;
|
|
2034
|
-
action.windows[stationaryWin.name] = true;
|
|
2035
|
-
}
|
|
2036
|
-
else if (!movingWindowGroup && !stationaryGroup) {
|
|
2037
|
-
action.name = uuidv4();
|
|
2038
|
-
action.windows[stationaryWin.name] = true;
|
|
2039
|
-
action.windows[movingWin.name] = true;
|
|
2040
|
-
}
|
|
2041
|
-
else {
|
|
2042
|
-
action.name = (_a = stationaryGroup === null || stationaryGroup === void 0 ? void 0 : stationaryGroup.name) !== null && _a !== void 0 ? _a : "unknown";
|
|
2043
|
-
action.windows[stationaryWin.name] = true;
|
|
2044
|
-
action.windows[movingWin.name] = true;
|
|
2045
|
-
}
|
|
2046
|
-
return action;
|
|
2047
|
-
}
|
|
2048
|
-
/**
|
|
2049
|
-
* Calculates resize bounds.
|
|
2050
|
-
* @param {object} params
|
|
2051
|
-
* @return {moveRequest}
|
|
2052
|
-
*/
|
|
2053
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
2054
|
-
adjustSize(params) {
|
|
2055
|
-
let { request } = params;
|
|
2056
|
-
const { stationaryWindow: adjustingStationaryWindow } = params;
|
|
2057
|
-
const { stationaryRegion } = params.intersection;
|
|
2058
|
-
const intersections = this.getIntersections(request, adjustingStationaryWindow, stationaryRegion)
|
|
2059
|
-
.toString()
|
|
2060
|
-
.toLowerCase();
|
|
2061
|
-
if (!intersections) {
|
|
2062
|
-
return request;
|
|
2063
|
-
}
|
|
2064
|
-
switch (stationaryRegion) {
|
|
2065
|
-
case "leftBottom":
|
|
2066
|
-
case "bottomLeft":
|
|
2067
|
-
if (intersections.includes("top") || intersections.includes("topleft") || intersections.includes("topright")) {
|
|
2068
|
-
request.top = adjustingStationaryWindow.bottom;
|
|
2069
|
-
}
|
|
2070
|
-
if (intersections.includes("topright") || intersections.includes("right")) {
|
|
2071
|
-
request.right = adjustingStationaryWindow.left;
|
|
2072
|
-
}
|
|
2073
|
-
if (intersections.includes("topleft") || intersections.includes("left")) {
|
|
2074
|
-
request.left = adjustingStationaryWindow.left;
|
|
2075
|
-
}
|
|
2076
|
-
if (intersections.includes("bottom")) {
|
|
2077
|
-
request.bottom = adjustingStationaryWindow.bottom;
|
|
2078
|
-
}
|
|
2079
|
-
break;
|
|
2080
|
-
case "rightBottom":
|
|
2081
|
-
case "bottomRight":
|
|
2082
|
-
if (intersections.includes("top") || intersections.includes("topleft") || intersections.includes("topright")) {
|
|
2083
|
-
request.top = adjustingStationaryWindow.bottom;
|
|
2084
|
-
}
|
|
2085
|
-
if (intersections.includes("topleft") || intersections.includes("left")) {
|
|
2086
|
-
request.left = adjustingStationaryWindow.right;
|
|
2087
|
-
}
|
|
2088
|
-
if (intersections.includes("topright") || intersections.includes("right")) {
|
|
2089
|
-
request.right = adjustingStationaryWindow.right;
|
|
2090
|
-
}
|
|
2091
|
-
if (intersections.includes("bottom")) {
|
|
2092
|
-
request.bottom = adjustingStationaryWindow.bottom;
|
|
2093
|
-
}
|
|
2094
|
-
break;
|
|
2095
|
-
case "topLeft":
|
|
2096
|
-
case "leftTop":
|
|
2097
|
-
if (intersections.includes("bottom") ||
|
|
2098
|
-
intersections.includes("bottomleft") ||
|
|
2099
|
-
intersections.includes("bottomright")) {
|
|
2100
|
-
request.bottom = adjustingStationaryWindow.top;
|
|
2101
|
-
}
|
|
2102
|
-
if (intersections.includes("bottomleft") || intersections.includes("left")) {
|
|
2103
|
-
request.bottom = adjustingStationaryWindow.top;
|
|
2104
|
-
request.left = adjustingStationaryWindow.left;
|
|
2105
|
-
}
|
|
2106
|
-
if (intersections.includes("bottomright") || intersections.includes("right")) {
|
|
2107
|
-
request.right = adjustingStationaryWindow.left;
|
|
2108
|
-
}
|
|
2109
|
-
if (intersections.includes("top")) {
|
|
2110
|
-
request.top = adjustingStationaryWindow.top;
|
|
2111
|
-
}
|
|
2112
|
-
break;
|
|
2113
|
-
case "rightTop":
|
|
2114
|
-
case "topRight":
|
|
2115
|
-
if (intersections.includes("bottom") ||
|
|
2116
|
-
intersections.includes("bottomleft") ||
|
|
2117
|
-
intersections.includes("bottomright")) {
|
|
2118
|
-
request.bottom = adjustingStationaryWindow.top;
|
|
2119
|
-
}
|
|
2120
|
-
if (intersections.includes("bottomleft") || intersections.includes("left")) {
|
|
2121
|
-
request.left = adjustingStationaryWindow.right;
|
|
2122
|
-
}
|
|
2123
|
-
if (intersections.includes("bottomright") || intersections.includes("right")) {
|
|
2124
|
-
request.right = adjustingStationaryWindow.right;
|
|
2125
|
-
}
|
|
2126
|
-
if (intersections.includes("top")) {
|
|
2127
|
-
request.top = adjustingStationaryWindow.top;
|
|
2128
|
-
}
|
|
2129
|
-
break;
|
|
2130
|
-
case "top":
|
|
2131
|
-
if (intersections.includes("bottom")) {
|
|
2132
|
-
request.bottom = adjustingStationaryWindow.top;
|
|
2133
|
-
}
|
|
2134
|
-
break;
|
|
2135
|
-
case "right":
|
|
2136
|
-
if (intersections.includes("left")) {
|
|
2137
|
-
request.left = adjustingStationaryWindow.right;
|
|
2138
|
-
}
|
|
2139
|
-
break;
|
|
2140
|
-
case "bottom":
|
|
2141
|
-
if (intersections.includes("top")) {
|
|
2142
|
-
request.top = adjustingStationaryWindow.bottom;
|
|
2143
|
-
}
|
|
2144
|
-
break;
|
|
2145
|
-
case "left":
|
|
2146
|
-
if (intersections.includes("right")) {
|
|
2147
|
-
request.right = adjustingStationaryWindow.left;
|
|
2148
|
-
}
|
|
2149
|
-
break;
|
|
2150
|
-
default:
|
|
2151
|
-
}
|
|
2152
|
-
request.width = request.right - request.left;
|
|
2153
|
-
request.height = request.bottom - request.top;
|
|
2154
|
-
request = this.checkShortCircuits(request);
|
|
2155
|
-
return request;
|
|
2156
|
-
}
|
|
2157
|
-
/**
|
|
2158
|
-
* Checks to see if a window has gotten too narrow, or too short.
|
|
2159
|
-
*/
|
|
2160
|
-
checkShortCircuitsWithEdge(request, edge) {
|
|
2161
|
-
let win = this.getWindow(request.name);
|
|
2162
|
-
// The code for resizing groups goes through here. It just passes bounds, not a window. Here, use the global minimums and no maximums (until a global max is allowed...).
|
|
2163
|
-
if (!win || !win.limits) {
|
|
2164
|
-
return {
|
|
2165
|
-
limits: {
|
|
2166
|
-
minHeight: MINIMUM_HEIGHT,
|
|
2167
|
-
minWidth: MINIMUM_WIDTH,
|
|
2168
|
-
maxHeight: Infinity,
|
|
2169
|
-
maxWidth: Infinity,
|
|
2170
|
-
},
|
|
2171
|
-
};
|
|
2172
|
-
}
|
|
2173
|
-
// Checks to see if the height/widths are below the window's minimum height/width. If so, it sets them to the minimum values.
|
|
2174
|
-
switch (edge) {
|
|
2175
|
-
case "top":
|
|
2176
|
-
if (request.height <= win.limits.minHeight) {
|
|
2177
|
-
request.height = win.limits.minHeight;
|
|
2178
|
-
request.bottom = request.top + win.limits.minHeight;
|
|
2179
|
-
}
|
|
2180
|
-
else if (request.height >= win.limits.maxHeight) {
|
|
2181
|
-
request.height = win.limits.maxHeight;
|
|
2182
|
-
request.bottom = request.top + win.limits.maxHeight;
|
|
2183
|
-
}
|
|
2184
|
-
break;
|
|
2185
|
-
case "bottom":
|
|
2186
|
-
if (request.height <= win.limits.minHeight) {
|
|
2187
|
-
request.height = win.limits.minHeight;
|
|
2188
|
-
request.top = request.bottom - win.limits.minHeight;
|
|
2189
|
-
}
|
|
2190
|
-
else if (request.height >= win.limits.maxHeight) {
|
|
2191
|
-
request.height = win.limits.maxHeight;
|
|
2192
|
-
request.top = request.bottom - win.limits.maxHeight;
|
|
2193
|
-
}
|
|
2194
|
-
break;
|
|
2195
|
-
case "left":
|
|
2196
|
-
if (request.width < win.limits.minWidth) {
|
|
2197
|
-
request.width = win.limits.minWidth;
|
|
2198
|
-
request.right = request.left + win.limits.minWidth;
|
|
2199
|
-
}
|
|
2200
|
-
else if (request.width > win.limits.maxWidth) {
|
|
2201
|
-
request.width = win.limits.maxWidth;
|
|
2202
|
-
request.right = request.left + win.limits.maxWidth;
|
|
2203
|
-
}
|
|
2204
|
-
break;
|
|
2205
|
-
case "right":
|
|
2206
|
-
if (request.width < win.limits.minWidth) {
|
|
2207
|
-
request.width = win.limits.minWidth;
|
|
2208
|
-
request.left = request.right - win.limits.minWidth;
|
|
2209
|
-
}
|
|
2210
|
-
else if (request.width > win.limits.maxWidth) {
|
|
2211
|
-
request.width = win.limits.maxWidth;
|
|
2212
|
-
request.left = request.right - win.limits.maxWidth;
|
|
2213
|
-
}
|
|
2214
|
-
break;
|
|
2215
|
-
default:
|
|
2216
|
-
}
|
|
2217
|
-
return request;
|
|
2218
|
-
}
|
|
2219
|
-
/**
|
|
2220
|
-
* Checks to see if a request is allowed. Are you trying to make my window -20px? or 10px? Get out of here.
|
|
2221
|
-
*/
|
|
2222
|
-
checkShortCircuits(request, win) {
|
|
2223
|
-
var _a, _b;
|
|
2224
|
-
let currentBounds;
|
|
2225
|
-
const defaultLimits = {
|
|
2226
|
-
minHeight: MINIMUM_HEIGHT,
|
|
2227
|
-
minWidth: MINIMUM_WIDTH,
|
|
2228
|
-
maxHeight: Infinity,
|
|
2229
|
-
maxWidth: Infinity,
|
|
2230
|
-
};
|
|
2231
|
-
if (typeof win === "undefined") {
|
|
2232
|
-
win = this.getWindow(request.name);
|
|
2233
|
-
}
|
|
2234
|
-
// Note: from Daniel, PR Review on 12/4. Address this at some point.
|
|
2235
|
-
// Looking at the code isolated from it's calling context, it's not obvious to me that this won't throw a null reference error. You're checking to see if request.name is truthy, which to me implies it's optional, but you're accessing it before this check, which looks really dangerous.We should switch the order, and only access request.name when we've confirmed it's really there.
|
|
2236
|
-
if (request.name) {
|
|
2237
|
-
currentBounds = win.getBounds();
|
|
2238
|
-
}
|
|
2239
|
-
else {
|
|
2240
|
-
currentBounds = request;
|
|
2241
|
-
// The code for resizing groups goes through here. It just passes bounds, not a window. Here, use the global minimums and no maximums (until a global max is allowed...).
|
|
2242
|
-
win = {};
|
|
2243
|
-
}
|
|
2244
|
-
if (((_b = (_a = win === null || win === void 0 ? void 0 : win.win) === null || _a === void 0 ? void 0 : _a.windowOptions) === null || _b === void 0 ? void 0 : _b.resizable) === false && (win.limits == null || win.limits.maxHeight == null)) {
|
|
2245
|
-
// non-resizable windows are showing up with undefined limits when Finsemble starts
|
|
2246
|
-
// limits are correctly populated on workspace reloads
|
|
2247
|
-
// in here we just enforce non resizable windows to have the correct dimensions
|
|
2248
|
-
win.limits = {
|
|
2249
|
-
minHeight: win.win.windowOptions.height,
|
|
2250
|
-
minWidth: win.win.windowOptions.width,
|
|
2251
|
-
maxHeight: win.win.windowOptions.height,
|
|
2252
|
-
maxWidth: win.win.windowOptions.width,
|
|
2253
|
-
};
|
|
2254
|
-
}
|
|
2255
|
-
else {
|
|
2256
|
-
win.limits = Object.assign(defaultLimits, win.limits || {});
|
|
2257
|
-
}
|
|
2258
|
-
// CASE: WINDOW IS TOO NARROW
|
|
2259
|
-
// handles shortCircuits for the moving window.
|
|
2260
|
-
if (request.width <= win.limits.minWidth) {
|
|
2261
|
-
request.width = win.limits.minWidth;
|
|
2262
|
-
// If we're dragging the left edge around, anchor the right edge.
|
|
2263
|
-
if (request.left !== currentBounds.left) {
|
|
2264
|
-
request.right = currentBounds.right;
|
|
2265
|
-
request.left = request.right - request.width;
|
|
2266
|
-
}
|
|
2267
|
-
else if (request.right !== currentBounds.right) {
|
|
2268
|
-
// If we're dragging the right edge around, anchor the left edge.
|
|
2269
|
-
request.left = currentBounds.left;
|
|
2270
|
-
request.right = request.left + request.width;
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
else if (request.width >= win.limits.maxWidth) {
|
|
2274
|
-
// CASE: WINDOW IS TOO WIDE
|
|
2275
|
-
request.width = win.limits.maxWidth;
|
|
2276
|
-
// If we're dragging the left edge around, anchor the right edge.
|
|
2277
|
-
if (request.left !== currentBounds.left) {
|
|
2278
|
-
request.right = currentBounds.right;
|
|
2279
|
-
request.left = request.right - request.width;
|
|
2280
|
-
}
|
|
2281
|
-
else if (request.right !== currentBounds.right) {
|
|
2282
|
-
// If we're dragging the right edge around, anchor the left edge.
|
|
2283
|
-
request.left = currentBounds.left;
|
|
2284
|
-
request.right = request.left + request.width;
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
// CASE: WINDOW IS TOO SHORT
|
|
2288
|
-
if (request.height <= win.limits.minHeight) {
|
|
2289
|
-
request.height = win.limits.minHeight;
|
|
2290
|
-
// If we're dragging the top edge around, anchor on the bottom.
|
|
2291
|
-
if (request.top !== currentBounds.top) {
|
|
2292
|
-
request.bottom = currentBounds.bottom;
|
|
2293
|
-
request.top = request.bottom - request.height;
|
|
2294
|
-
}
|
|
2295
|
-
else if (request.bottom !== currentBounds.bottom) {
|
|
2296
|
-
// If we're dragging the bottom edge around, anchor on the top.
|
|
2297
|
-
request.top = currentBounds.top;
|
|
2298
|
-
request.bottom = request.top + request.height;
|
|
2299
|
-
}
|
|
2300
|
-
}
|
|
2301
|
-
else if (request.height >= win.limits.maxHeight) {
|
|
2302
|
-
// CASE: WINDOW IS TOO TALL
|
|
2303
|
-
request.height = win.limits.maxHeight;
|
|
2304
|
-
// If we're dragging the top edge around, anchor on the bottom.
|
|
2305
|
-
if (request.top !== currentBounds.top) {
|
|
2306
|
-
request.bottom = currentBounds.bottom;
|
|
2307
|
-
request.top = request.bottom - request.height;
|
|
2308
|
-
}
|
|
2309
|
-
else if (request.bottom !== currentBounds.bottom) {
|
|
2310
|
-
// If we're dragging the bottom edge around, anchor on the top.
|
|
2311
|
-
request.top = currentBounds.top;
|
|
2312
|
-
request.bottom = request.top + request.height;
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
return request;
|
|
2316
|
-
}
|
|
2317
|
-
/**
|
|
2318
|
-
* Use when a window is moving and needs to be snapped. Width/Height aren't modified like in `this.adjustSize`.
|
|
2319
|
-
* @param {type} params
|
|
2320
|
-
* @return {type}
|
|
2321
|
-
*/
|
|
2322
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
2323
|
-
getNewCoordinates(params) {
|
|
2324
|
-
const { request } = params;
|
|
2325
|
-
const { stationaryWindow } = params;
|
|
2326
|
-
const { movingRegion } = params.intersection;
|
|
2327
|
-
const { stationaryRegion } = params.intersection;
|
|
2328
|
-
switch (stationaryRegion) {
|
|
2329
|
-
case "bottomLeft":
|
|
2330
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2331
|
-
request.top = stationaryWindow.bottom;
|
|
2332
|
-
}
|
|
2333
|
-
if (movingRegion.toLowerCase().includes("right")) {
|
|
2334
|
-
request.left = stationaryWindow.left - request.width;
|
|
2335
|
-
}
|
|
2336
|
-
if (movingRegion.toLowerCase().includes("left")) {
|
|
2337
|
-
request.left = stationaryWindow.left;
|
|
2338
|
-
}
|
|
2339
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2340
|
-
request.top = stationaryWindow.bottom - request.height;
|
|
2341
|
-
}
|
|
2342
|
-
break;
|
|
2343
|
-
case "bottomRight":
|
|
2344
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2345
|
-
request.top = stationaryWindow.bottom;
|
|
2346
|
-
}
|
|
2347
|
-
if (movingRegion.toLowerCase().includes("left")) {
|
|
2348
|
-
request.left = stationaryWindow.right;
|
|
2349
|
-
}
|
|
2350
|
-
if (movingRegion.toLowerCase().includes("right")) {
|
|
2351
|
-
request.left = stationaryWindow.right - request.width;
|
|
2352
|
-
}
|
|
2353
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2354
|
-
request.top = stationaryWindow.bottom - request.height;
|
|
2355
|
-
}
|
|
2356
|
-
break;
|
|
2357
|
-
case "topLeft":
|
|
2358
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2359
|
-
request.top = stationaryWindow.top - request.height;
|
|
2360
|
-
}
|
|
2361
|
-
if (movingRegion.toLowerCase().includes("left")) {
|
|
2362
|
-
request.left = stationaryWindow.left;
|
|
2363
|
-
}
|
|
2364
|
-
if (movingRegion.toLowerCase().includes("right")) {
|
|
2365
|
-
request.left = stationaryWindow.left - request.width;
|
|
2366
|
-
}
|
|
2367
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2368
|
-
request.top = stationaryWindow.top;
|
|
2369
|
-
}
|
|
2370
|
-
break;
|
|
2371
|
-
case "topRight":
|
|
2372
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2373
|
-
request.top = stationaryWindow.top - request.height;
|
|
2374
|
-
}
|
|
2375
|
-
if (movingRegion.toLowerCase().includes("left")) {
|
|
2376
|
-
request.left = stationaryWindow.right;
|
|
2377
|
-
}
|
|
2378
|
-
if (movingRegion.toLowerCase().includes("right")) {
|
|
2379
|
-
request.left = stationaryWindow.right - request.width;
|
|
2380
|
-
}
|
|
2381
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2382
|
-
request.top = stationaryWindow.top;
|
|
2383
|
-
}
|
|
2384
|
-
break;
|
|
2385
|
-
case "leftTop":
|
|
2386
|
-
if (movingRegion.toLowerCase().includes("right")) {
|
|
2387
|
-
request.left = stationaryWindow.left - request.width;
|
|
2388
|
-
}
|
|
2389
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2390
|
-
request.top = stationaryWindow.top;
|
|
2391
|
-
}
|
|
2392
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2393
|
-
request.top = stationaryWindow.top - request.height;
|
|
2394
|
-
}
|
|
2395
|
-
break;
|
|
2396
|
-
case "leftBottom":
|
|
2397
|
-
if (movingRegion.toLowerCase().includes("right")) {
|
|
2398
|
-
request.left = stationaryWindow.left - request.width;
|
|
2399
|
-
}
|
|
2400
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2401
|
-
request.top = stationaryWindow.bottom - request.height;
|
|
2402
|
-
}
|
|
2403
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2404
|
-
request.top = stationaryWindow.bottom;
|
|
2405
|
-
}
|
|
2406
|
-
break;
|
|
2407
|
-
case "rightTop":
|
|
2408
|
-
if (movingRegion.toLowerCase().includes("left")) {
|
|
2409
|
-
request.left = stationaryWindow.right;
|
|
2410
|
-
}
|
|
2411
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2412
|
-
request.top = stationaryWindow.top;
|
|
2413
|
-
}
|
|
2414
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2415
|
-
request.top = stationaryWindow.top - request.height;
|
|
2416
|
-
}
|
|
2417
|
-
break;
|
|
2418
|
-
case "rightBottom":
|
|
2419
|
-
if (movingRegion.toLowerCase().includes("left")) {
|
|
2420
|
-
request.left = stationaryWindow.right;
|
|
2421
|
-
}
|
|
2422
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2423
|
-
request.top = stationaryWindow.bottom - request.height;
|
|
2424
|
-
}
|
|
2425
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2426
|
-
request.top = stationaryWindow.bottom;
|
|
2427
|
-
}
|
|
2428
|
-
break;
|
|
2429
|
-
case "top":
|
|
2430
|
-
if (movingRegion.toLowerCase().includes("bottom")) {
|
|
2431
|
-
request.top = stationaryWindow.top - request.height;
|
|
2432
|
-
}
|
|
2433
|
-
break;
|
|
2434
|
-
case "right":
|
|
2435
|
-
if (movingRegion.toLowerCase().includes("left")) {
|
|
2436
|
-
request.left = stationaryWindow.right;
|
|
2437
|
-
}
|
|
2438
|
-
break;
|
|
2439
|
-
case "bottom":
|
|
2440
|
-
if (movingRegion.toLowerCase().includes("top")) {
|
|
2441
|
-
request.top = stationaryWindow.bottom;
|
|
2442
|
-
}
|
|
2443
|
-
break;
|
|
2444
|
-
case "left":
|
|
2445
|
-
if (movingRegion.toLowerCase().includes("right")) {
|
|
2446
|
-
request.left = stationaryWindow.left - request.width;
|
|
2447
|
-
}
|
|
2448
|
-
break;
|
|
2449
|
-
default:
|
|
2450
|
-
}
|
|
2451
|
-
request.right = request.left + request.width;
|
|
2452
|
-
request.bottom = request.top + request.height;
|
|
2453
|
-
return request;
|
|
2454
|
-
}
|
|
2455
|
-
/**
|
|
2456
|
-
* Helper to return an object that says which edges are moving.
|
|
2457
|
-
* @function this.getMovingEdgesFromResizeHandle
|
|
2458
|
-
* @param {type} handle
|
|
2459
|
-
* @return {type}
|
|
2460
|
-
*/
|
|
2461
|
-
getMovingEdgesFromResizeHandle(handle) {
|
|
2462
|
-
const edges = {
|
|
2463
|
-
top: false,
|
|
2464
|
-
right: false,
|
|
2465
|
-
left: false,
|
|
2466
|
-
bottom: false,
|
|
2467
|
-
};
|
|
2468
|
-
if (!handle) {
|
|
2469
|
-
return edges;
|
|
2470
|
-
}
|
|
2471
|
-
handle = handle.toLowerCase();
|
|
2472
|
-
for (const edge in edges) {
|
|
2473
|
-
if (handle.includes(edge)) {
|
|
2474
|
-
edges[edge] = true;
|
|
2475
|
-
}
|
|
2476
|
-
}
|
|
2477
|
-
return edges;
|
|
2478
|
-
}
|
|
2479
|
-
/**
|
|
2480
|
-
* Bounds are calculated in maskBoundsCalculator.js
|
|
2481
|
-
*/
|
|
2482
|
-
moveGroupMask() {
|
|
2483
|
-
var _a;
|
|
2484
|
-
if (this.moveRequest) {
|
|
2485
|
-
const newBounds = mousePosToBounds(this.moveRequest.mousePosition);
|
|
2486
|
-
console.log(newBounds, this.moveRequest);
|
|
2487
|
-
(_a = this.groupMask) === null || _a === void 0 ? void 0 : _a.setBounds(newBounds);
|
|
2488
|
-
}
|
|
2489
|
-
}
|
|
2490
|
-
/**
|
|
2491
|
-
* NOT CURRENTLY USED.
|
|
2492
|
-
* Will be like `onMouseMove`, but for groups. Goal is to only move all grouped windows `onMouseUp`. In the interim, just move the mask around. Right now I move every window on every resizeEvent
|
|
2493
|
-
*/
|
|
2494
|
-
_moveGroupMaskOld() {
|
|
2495
|
-
if (!this.groupMask)
|
|
2496
|
-
return;
|
|
2497
|
-
const moveRequest = fastClone(this.moveRequest);
|
|
2498
|
-
const bounds = this.groupMask.getBounds();
|
|
2499
|
-
if (moveRequest.changeType !== 0) {
|
|
2500
|
-
const resizeHandle = this.resizeObject.correctedHandle;
|
|
2501
|
-
if (resizeHandle) {
|
|
2502
|
-
const splitHandle = resizeHandle.split(/(?=[A-Z])/).map((s) => s.toLowerCase());
|
|
2503
|
-
splitHandle.forEach((handle) => {
|
|
2504
|
-
if (handle === "top" || handle === "bottom") {
|
|
2505
|
-
bounds[handle] = moveRequest.mousePosition.y || moveRequest.mousePosition.top;
|
|
2506
|
-
}
|
|
2507
|
-
if (handle === "right" || handle === "left") {
|
|
2508
|
-
bounds[handle] = moveRequest.mousePosition.x || moveRequest.mousePosition.left;
|
|
2509
|
-
}
|
|
2510
|
-
});
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
bounds.width = bounds.right - bounds.left;
|
|
2514
|
-
bounds.height = bounds.bottom - bounds.top;
|
|
2515
|
-
bounds.name = "groupMask";
|
|
2516
|
-
this.groupMask.setBounds(bounds);
|
|
2517
|
-
}
|
|
2518
|
-
/**
|
|
2519
|
-
* This returns an object with all of the bounds of all of the windows in a given group. This should be moved in to the dockableGroup.
|
|
2520
|
-
*/
|
|
2521
|
-
getBoundsOfGroupWindows(group) {
|
|
2522
|
-
const groupIter = this.groupWindowIterator(group);
|
|
2523
|
-
const bounds = {};
|
|
2524
|
-
for (const win of groupIter) {
|
|
2525
|
-
bounds[win.name] = win.getBounds();
|
|
2526
|
-
// bounds[win.name].name = win.name;
|
|
2527
|
-
}
|
|
2528
|
-
return bounds;
|
|
2529
|
-
}
|
|
2530
|
-
/**
|
|
2531
|
-
* For a group, it will iterate through its windows and set bounds on each of them.
|
|
2532
|
-
*/
|
|
2533
|
-
setBoundsOfGroupWindows(group, windowBounds, stopMove = false) {
|
|
2534
|
-
const groupIter = this.groupWindowIterator(group);
|
|
2535
|
-
for (const win of groupIter) {
|
|
2536
|
-
windowBounds[win.name].name = win.name;
|
|
2537
|
-
this.moveWindow(windowBounds[win.name]);
|
|
2538
|
-
if (stopMove) {
|
|
2539
|
-
win.win.stopMove();
|
|
2540
|
-
win.win._saveWindowOptions({});
|
|
2541
|
-
}
|
|
2542
|
-
}
|
|
2543
|
-
}
|
|
2544
|
-
/**
|
|
2545
|
-
* Exports an array of bounds for the windows that are currently being managed by docking. This makes it easy to generate oddball test cases.
|
|
2546
|
-
*/
|
|
2547
|
-
export() {
|
|
2548
|
-
const windowList = this.getWindowNames().map((name, i) => {
|
|
2549
|
-
const win = this.getWindow(name);
|
|
2550
|
-
const bounds = win.getBounds();
|
|
2551
|
-
bounds.name = `window${i}`;
|
|
2552
|
-
return bounds;
|
|
2553
|
-
});
|
|
2554
|
-
if (windowList) {
|
|
2555
|
-
return JSON.stringify(windowList);
|
|
2556
|
-
}
|
|
2557
|
-
return "";
|
|
2558
|
-
}
|
|
2559
|
-
/**
|
|
2560
|
-
* Cleans up shared edges of windows in a group
|
|
2561
|
-
* @param {*} group The group to operate on
|
|
2562
|
-
* @param {*} windowBounds An object containing bounds key'ed by window name
|
|
2563
|
-
* @param {*} triggeredByAutoArrange Wether or not this cleanup was trigger by auto arrange (if true will fire stopMove())
|
|
2564
|
-
*/
|
|
2565
|
-
cleanupSharedEdges(group, windowBounds, triggeredByAutoArrange = false) {
|
|
2566
|
-
const groupIter = this.groupWindowIterator(group);
|
|
2567
|
-
for (const win of groupIter) {
|
|
2568
|
-
const edges = {
|
|
2569
|
-
right: 0,
|
|
2570
|
-
left: 0,
|
|
2571
|
-
top: 0,
|
|
2572
|
-
bottom: 0,
|
|
2573
|
-
};
|
|
2574
|
-
// How many things is this window snapped to on each edge??
|
|
2575
|
-
win.snappedWindows.forEach((sWin) => {
|
|
2576
|
-
for (const i in sWin.edges) {
|
|
2577
|
-
if (sWin.edges[i])
|
|
2578
|
-
edges[i]++;
|
|
2579
|
-
}
|
|
2580
|
-
});
|
|
2581
|
-
const maybeAdjustWindow = (sWin, edge) => {
|
|
2582
|
-
const snappedWin = windowBounds[sWin.name];
|
|
2583
|
-
// if a window is snapped to a window (but not grouped with it), that window won't be in the movable group's window bounds. So make sure it exists first.
|
|
2584
|
-
if (!snappedWin || win[edge] === snappedWin[OPPOSITE_EDGE_MAP[edge]])
|
|
2585
|
-
return;
|
|
2586
|
-
windowBounds[win.name][edge] = snappedWin[OPPOSITE_EDGE_MAP[edge]];
|
|
2587
|
-
if (["right", "left"].includes(edge)) {
|
|
2588
|
-
windowBounds[win.name].width = windowBounds[win.name].right - windowBounds[win.name].left;
|
|
2589
|
-
}
|
|
2590
|
-
else {
|
|
2591
|
-
windowBounds[win.name].height = windowBounds[win.name].bottom - windowBounds[win.name].top;
|
|
2592
|
-
}
|
|
2593
|
-
};
|
|
2594
|
-
// If we are only snapped to one thing and are disconnected, reconnect:
|
|
2595
|
-
win.snappedWindows.forEach((sWin) => {
|
|
2596
|
-
for (const edge in sWin.edges) {
|
|
2597
|
-
if (sWin.edges[edge] && edges[edge] === 1) {
|
|
2598
|
-
maybeAdjustWindow(sWin, edge);
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
});
|
|
2602
|
-
}
|
|
2603
|
-
this.setBoundsOfGroupWindows(group, windowBounds, triggeredByAutoArrange);
|
|
2604
|
-
return windowBounds;
|
|
2605
|
-
}
|
|
2606
|
-
/**
|
|
2607
|
-
* Run after everything, it removes any gaps that might have occurred (e.g., from fractional pixels, rounding, etc). It needs better inline documentation.
|
|
2608
|
-
*/
|
|
2609
|
-
cleanupGaps(group, windowBounds) {
|
|
2610
|
-
const groupIter = this.groupWindowIterator(group);
|
|
2611
|
-
const xs = [];
|
|
2612
|
-
const ys = [];
|
|
2613
|
-
for (const win of groupIter) {
|
|
2614
|
-
const bounds = windowBounds[win.name];
|
|
2615
|
-
if (!xs.some((x) => {
|
|
2616
|
-
if (Math.abs(bounds.left - x) < 5) {
|
|
2617
|
-
bounds.left = x;
|
|
2618
|
-
return true;
|
|
2619
|
-
}
|
|
2620
|
-
return false;
|
|
2621
|
-
})) {
|
|
2622
|
-
xs.push(bounds.left);
|
|
2623
|
-
}
|
|
2624
|
-
if (!xs.some((x) => {
|
|
2625
|
-
if (Math.abs(bounds.right - x) < 5) {
|
|
2626
|
-
bounds.right = x;
|
|
2627
|
-
return true;
|
|
2628
|
-
}
|
|
2629
|
-
return false;
|
|
2630
|
-
})) {
|
|
2631
|
-
xs.push(bounds.right);
|
|
2632
|
-
}
|
|
2633
|
-
bounds.width = bounds.right - bounds.left;
|
|
2634
|
-
if (!ys.some((y) => {
|
|
2635
|
-
if (Math.abs(bounds.top - y) < 5) {
|
|
2636
|
-
bounds.top = y;
|
|
2637
|
-
return true;
|
|
2638
|
-
}
|
|
2639
|
-
return false;
|
|
2640
|
-
})) {
|
|
2641
|
-
ys.push(bounds.top);
|
|
2642
|
-
}
|
|
2643
|
-
if (!ys.some((y) => {
|
|
2644
|
-
if (Math.abs(bounds.bottom - y) < 5) {
|
|
2645
|
-
bounds.bottom = y;
|
|
2646
|
-
return true;
|
|
2647
|
-
}
|
|
2648
|
-
return false;
|
|
2649
|
-
})) {
|
|
2650
|
-
ys.push(bounds.bottom);
|
|
2651
|
-
}
|
|
2652
|
-
bounds.height = bounds.bottom - bounds.top;
|
|
2653
|
-
}
|
|
2654
|
-
return windowBounds;
|
|
2655
|
-
}
|
|
2656
|
-
shouldShortCircuit(request) {
|
|
2657
|
-
const shouldShortCircuit = {
|
|
2658
|
-
width: false,
|
|
2659
|
-
height: false,
|
|
2660
|
-
};
|
|
2661
|
-
const win = this.getWindow(request.name);
|
|
2662
|
-
if (win) {
|
|
2663
|
-
if (request.width <= win.limits.minWidth || request.width >= win.limits.maxWidth) {
|
|
2664
|
-
shouldShortCircuit.width = true;
|
|
2665
|
-
}
|
|
2666
|
-
if (request.height <= win.limits.minHeight || request.height >= win.limits.maxHeight) {
|
|
2667
|
-
shouldShortCircuit.height = true;
|
|
2668
|
-
}
|
|
2669
|
-
}
|
|
2670
|
-
return shouldShortCircuit;
|
|
2671
|
-
}
|
|
2672
|
-
recurse({ snapObjectNames, movingWindowSnappedWindows, snappedWindows, handle, originalHandle, }) {
|
|
2673
|
-
const oppEdge = OPPOSITE_EDGE_MAP[handle];
|
|
2674
|
-
for (let i = 0, len = snappedWindows.length; i < len; i++) {
|
|
2675
|
-
const snapObj = snappedWindows[i];
|
|
2676
|
-
const snappedWindow = this.getWindow(snapObj.name);
|
|
2677
|
-
if (!snapObjectNames.includes(snapObj.name + oppEdge)) {
|
|
2678
|
-
snapObjectNames.push(snapObj.name + oppEdge);
|
|
2679
|
-
movingWindowSnappedWindows.push({
|
|
2680
|
-
name: snapObj.name,
|
|
2681
|
-
edge: oppEdge,
|
|
2682
|
-
handle: originalHandle,
|
|
2683
|
-
win: snappedWindow,
|
|
2684
|
-
});
|
|
2685
|
-
this.recurse({
|
|
2686
|
-
snapObjectNames,
|
|
2687
|
-
movingWindowSnappedWindows,
|
|
2688
|
-
snappedWindows: this.getWindowsOnEdge(snappedWindow, oppEdge),
|
|
2689
|
-
handle: oppEdge,
|
|
2690
|
-
originalHandle,
|
|
2691
|
-
});
|
|
2692
|
-
}
|
|
2693
|
-
}
|
|
2694
|
-
}
|
|
2695
|
-
recurseCorner({ snapObjectNames, movingWindowSnappedWindows, cornerWindows, originalHandle, }) {
|
|
2696
|
-
for (let i = 0, len = cornerWindows.length; i < len; i++) {
|
|
2697
|
-
const snapObj = cornerWindows[i];
|
|
2698
|
-
const snappedWindow = this.getWindow(snapObj.name);
|
|
2699
|
-
if (snapObj.corner && !snapObjectNames.includes(snapObj.name + snapObj.corner)) {
|
|
2700
|
-
const dragHandleArray = snapObj.corner.split(/(?=[A-Z])/).map((s) => s.toLowerCase());
|
|
2701
|
-
dragHandleArray.forEach((dragHandle) => {
|
|
2702
|
-
// if handle == bottomLeft and the originalHandle is bottom, we don't want to do anything with the Left edge. The algorithm will run through this function twice.
|
|
2703
|
-
const doStuff = dragHandle === originalHandle || dragHandle === OPPOSITE_EDGE_MAP[originalHandle];
|
|
2704
|
-
if (doStuff && !snapObjectNames.includes(snapObj.name + dragHandle)) {
|
|
2705
|
-
movingWindowSnappedWindows.push({
|
|
2706
|
-
name: snapObj.name,
|
|
2707
|
-
edge: dragHandle,
|
|
2708
|
-
handle: originalHandle,
|
|
2709
|
-
win: snappedWindow,
|
|
2710
|
-
});
|
|
2711
|
-
this.recurse({
|
|
2712
|
-
snapObjectNames,
|
|
2713
|
-
movingWindowSnappedWindows,
|
|
2714
|
-
snappedWindows: this.getWindowsOnEdge(snappedWindow, dragHandle),
|
|
2715
|
-
handle: dragHandle,
|
|
2716
|
-
originalHandle,
|
|
2717
|
-
});
|
|
2718
|
-
snapObjectNames.push(snapObj.name + dragHandle);
|
|
2719
|
-
}
|
|
2720
|
-
});
|
|
2721
|
-
}
|
|
2722
|
-
}
|
|
2723
|
-
}
|
|
2724
|
-
maybeSnapToOtherWindows(moveRequest, snappableWindows, resizeHandle) {
|
|
2725
|
-
if (!this.movingWindow)
|
|
2726
|
-
return moveRequest;
|
|
2727
|
-
const splitHandle = resizeHandle.split(/(?=[A-Z])/).map((s) => s.toLowerCase());
|
|
2728
|
-
const snappedWindowNames = this.movingWindow.snappedWindows.flatMap((snapObj) => {
|
|
2729
|
-
for (let handle in splitHandle) {
|
|
2730
|
-
if (snapObj.edges[handle] || snapObj.corners[resizeHandle])
|
|
2731
|
-
return [snapObj.name];
|
|
2732
|
-
}
|
|
2733
|
-
return [];
|
|
2734
|
-
});
|
|
2735
|
-
// will snap the window to other windows before going and modifying the rest of it
|
|
2736
|
-
let modifiedRequest = fastClone(moveRequest);
|
|
2737
|
-
// will snap the window to other windows before going and modifying the rest of it
|
|
2738
|
-
for (let i = 0; i < snappableWindows.length; i++) {
|
|
2739
|
-
const snappableWindow = snappableWindows[i];
|
|
2740
|
-
if (snappedWindowNames.includes(snappableWindow) ||
|
|
2741
|
-
snappableWindow === this.movingWindow.name ||
|
|
2742
|
-
groupBlacklist.includes(snappableWindow)) {
|
|
2743
|
-
continue;
|
|
2744
|
-
}
|
|
2745
|
-
const win = this.getWindow(snappableWindow);
|
|
2746
|
-
this.setStationaryWindow(win);
|
|
2747
|
-
modifiedRequest = this.snapWindow(Object.assign(Object.assign({}, modifiedRequest), { movingRegion: resizeHandle }));
|
|
2748
|
-
// Check if the side being dragged has been changed, if it's different return the modifiedRequest
|
|
2749
|
-
let shouldContinue = splitHandle.some((handle) => modifiedRequest[handle] === moveRequest[handle]);
|
|
2750
|
-
if (shouldContinue)
|
|
2751
|
-
continue;
|
|
2752
|
-
return modifiedRequest;
|
|
2753
|
-
}
|
|
2754
|
-
return moveRequest;
|
|
2755
|
-
}
|
|
2756
|
-
moveInteriorWindows(moveRequest, movingWindowSnappedWindows) {
|
|
2757
|
-
let movements = {
|
|
2758
|
-
[moveRequest.name]: moveRequest,
|
|
2759
|
-
};
|
|
2760
|
-
let shortCircuits = this.shouldShortCircuit(moveRequest);
|
|
2761
|
-
movingWindowSnappedWindows.forEach((snapObj) => {
|
|
2762
|
-
var _a;
|
|
2763
|
-
const snappedWindow = this.getWindow(snapObj.name);
|
|
2764
|
-
let newBounds = movements[snapObj.name] ? movements[snapObj.name] : snappedWindow.getBounds();
|
|
2765
|
-
newBounds.name = snapObj.name;
|
|
2766
|
-
newBounds[snapObj.edge] = moveRequest[(_a = snapObj.handle) !== null && _a !== void 0 ? _a : "undefined"];
|
|
2767
|
-
// we force non re-sizable windows to keep their original dimensions
|
|
2768
|
-
if (snappedWindow.win.windowOptions.resizable === false) {
|
|
2769
|
-
newBounds.width = snappedWindow.win.windowOptions.width;
|
|
2770
|
-
newBounds.height = snappedWindow.win.windowOptions.height;
|
|
2771
|
-
}
|
|
2772
|
-
else {
|
|
2773
|
-
newBounds.width = newBounds.right - newBounds.left;
|
|
2774
|
-
newBounds.height = newBounds.bottom - newBounds.top;
|
|
2775
|
-
}
|
|
2776
|
-
if (newBounds.width <= snappedWindow.limits.minWidth || newBounds.width >= snappedWindow.limits.maxWidth) {
|
|
2777
|
-
shortCircuits.width = true;
|
|
2778
|
-
}
|
|
2779
|
-
if (newBounds.height <= snappedWindow.limits.minHeight || newBounds.width >= snappedWindow.limits.maxHeight) {
|
|
2780
|
-
shortCircuits.height = true;
|
|
2781
|
-
}
|
|
2782
|
-
newBounds = this.checkShortCircuits(newBounds, snappedWindow);
|
|
2783
|
-
movements[newBounds.name] = newBounds;
|
|
2784
|
-
});
|
|
2785
|
-
Object.entries(movements).forEach(([windowName, movement]) => {
|
|
2786
|
-
if (groupBlacklist.includes(windowName))
|
|
2787
|
-
return;
|
|
2788
|
-
const win = this.getWindow(windowName);
|
|
2789
|
-
if (shortCircuits.width) {
|
|
2790
|
-
movement.width = win.width;
|
|
2791
|
-
movement.left = win.left;
|
|
2792
|
-
movement.right = win.right;
|
|
2793
|
-
}
|
|
2794
|
-
if (shortCircuits.height) {
|
|
2795
|
-
movement.height = win.height;
|
|
2796
|
-
movement.top = win.top;
|
|
2797
|
-
movement.bottom = win.bottom;
|
|
2798
|
-
}
|
|
2799
|
-
this.moveWindow(movement);
|
|
2800
|
-
});
|
|
2801
|
-
}
|
|
2802
|
-
/**
|
|
2803
|
-
* Resizes a window or group of windows on the interior of a group
|
|
2804
|
-
* @param {moveRequest} moveRequest
|
|
2805
|
-
*/
|
|
2806
|
-
resizeInteriorWindow(moveRequest) {
|
|
2807
|
-
var _a;
|
|
2808
|
-
// Hole filling algorithm for tiling calls this method.
|
|
2809
|
-
// It passes in the resize handle. It'll never be a corner. No need for the resizeObject here.
|
|
2810
|
-
const resizeHandle = (_a = (moveRequest.forceResizeHandle ? moveRequest.resizeHandle : undefined)) !== null && _a !== void 0 ? _a : this.resizeObject.correctedHandle;
|
|
2811
|
-
if (!this.movingWindow || !resizeHandle)
|
|
2812
|
-
return;
|
|
2813
|
-
const snappableWindows = this.getSnappableWindows(moveRequest);
|
|
2814
|
-
moveRequest = this.maybeSnapToOtherWindows(moveRequest, snappableWindows, resizeHandle);
|
|
2815
|
-
const movingWindowSnappedWindows = [];
|
|
2816
|
-
const snapObjectNames = [];
|
|
2817
|
-
const movingCorner = CORNERS.includes(resizeHandle);
|
|
2818
|
-
if (movingCorner) {
|
|
2819
|
-
const cornerPoint = this.movingWindow.getPointByVertex(resizeHandle);
|
|
2820
|
-
const cornerWindows = this.getWindowsAtPoint(cornerPoint).map((val) => {
|
|
2821
|
-
return {
|
|
2822
|
-
name: val,
|
|
2823
|
-
corner: this.getWindow(val).getVertexByPoint(cornerPoint),
|
|
2824
|
-
edge: this.getWindow(val).getEdgeByPoint(cornerPoint),
|
|
2825
|
-
};
|
|
2826
|
-
});
|
|
2827
|
-
const splitHandle = resizeHandle.split(/(?=[A-Z])/).map((s) => s.toLowerCase());
|
|
2828
|
-
splitHandle.forEach((handle) => {
|
|
2829
|
-
this.recurseCorner({ snapObjectNames, movingWindowSnappedWindows, cornerWindows, originalHandle: handle });
|
|
2830
|
-
});
|
|
2831
|
-
}
|
|
2832
|
-
else {
|
|
2833
|
-
const clonedSnaps = this.getWindowsOnEdge(this.movingWindow, resizeHandle);
|
|
2834
|
-
this.recurse({
|
|
2835
|
-
snapObjectNames,
|
|
2836
|
-
movingWindowSnappedWindows,
|
|
2837
|
-
snappedWindows: clonedSnaps,
|
|
2838
|
-
handle: resizeHandle,
|
|
2839
|
-
originalHandle: resizeHandle,
|
|
2840
|
-
});
|
|
2841
|
-
}
|
|
2842
|
-
this.moveInteriorWindows(moveRequest, movingWindowSnappedWindows);
|
|
2843
|
-
}
|
|
2844
|
-
/**
|
|
2845
|
-
* function for debugging a 3x3 grid.
|
|
2846
|
-
*/
|
|
2847
|
-
logger() {
|
|
2848
|
-
const boundingBoxes = {};
|
|
2849
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
2850
|
-
for (const win of dockingPoolIterator) {
|
|
2851
|
-
boundingBoxes[window.name] = JSON.stringify(win.windowBoundingBox);
|
|
2852
|
-
}
|
|
2853
|
-
let box = "";
|
|
2854
|
-
box = `${box}+----------------------------------------+\n`;
|
|
2855
|
-
box = `${box}| | | |\n`;
|
|
2856
|
-
box = `${box}| ${boundingBoxes.A} | ${boundingBoxes.B} | ${boundingBoxes.C} |\n`;
|
|
2857
|
-
box = `${box}| | | |\n`;
|
|
2858
|
-
box = `${box}| | | |\n`;
|
|
2859
|
-
box = `${box}+----------------------------------------+\n`;
|
|
2860
|
-
box = `${box}| | | |\n`;
|
|
2861
|
-
box = `${box}| ${boundingBoxes.D} | ${boundingBoxes.E} | ${boundingBoxes.F} |\n`;
|
|
2862
|
-
box = `${box}| | | |\n`;
|
|
2863
|
-
box = `${box}| | | |\n`;
|
|
2864
|
-
box = `${box}+----------------------------------------+\n`;
|
|
2865
|
-
box = `${box}| | | |\n`;
|
|
2866
|
-
box = `${box}| ${boundingBoxes.G} | ${boundingBoxes.H} | ${boundingBoxes.I} |\n`;
|
|
2867
|
-
box = `${box}| | | |\n`;
|
|
2868
|
-
box = `${box}| | | |\n`;
|
|
2869
|
-
box = `${box}+----------------------------------------+\n`;
|
|
2870
|
-
Logger.system.verbose(box);
|
|
2871
|
-
}
|
|
2872
|
-
/**
|
|
2873
|
-
* Helper to determine whether a moveRequest will affect a window, the group, or just a local collection of windows that are snapped to the movingWindow.
|
|
2874
|
-
*/
|
|
2875
|
-
shouldScaleGroup(moveRequest) {
|
|
2876
|
-
var _a;
|
|
2877
|
-
if (!moveRequest.name) {
|
|
2878
|
-
Logger.warn("DockingCalculator.shouldScaleGroup() no name provided in moveRequest", moveRequest);
|
|
2879
|
-
return false;
|
|
2880
|
-
}
|
|
2881
|
-
if (this.groupMode.requireRectangularityForGroupResize) {
|
|
2882
|
-
return (_a = this.shouldMoveAffectGroup(moveRequest)) !== null && _a !== void 0 ? _a : false;
|
|
2883
|
-
}
|
|
2884
|
-
if (!this.groupMode.enabled) {
|
|
2885
|
-
return false;
|
|
2886
|
-
}
|
|
2887
|
-
const win = this.getWindow(moveRequest.name);
|
|
2888
|
-
if (!win || !win.groupNames.length) {
|
|
2889
|
-
return false;
|
|
2890
|
-
}
|
|
2891
|
-
const group = this.getMovingGroup(moveRequest);
|
|
2892
|
-
if (!group) {
|
|
2893
|
-
return false;
|
|
2894
|
-
}
|
|
2895
|
-
const req = new DockableBox(moveRequest);
|
|
2896
|
-
// if the handle that's being dragged is on an exterior edge of a group resizing all.
|
|
2897
|
-
// This used to be derived from the window because it was only calculated on mouseDown. Now that it can be calculated at any time, we need to derive the handle from the request that's coming in. On group resizes, window bounds are only modified on mouse up.
|
|
2898
|
-
const resizeHandle = req.getResizeHandle(moveRequest);
|
|
2899
|
-
if (moveRequest.changeType !== 0 && CORNERS.includes(resizeHandle)) {
|
|
2900
|
-
const cornerPoint = win.getPointByVertex(resizeHandle);
|
|
2901
|
-
const cornersThatCauseScaling = group.getCornersThatCauseScaling();
|
|
2902
|
-
return cornersThatCauseScaling.some((corner) => corner.x === cornerPoint.x && corner.y === cornerPoint.y);
|
|
2903
|
-
}
|
|
2904
|
-
return false;
|
|
2905
|
-
}
|
|
2906
|
-
/**
|
|
2907
|
-
* Helper to determine whether a moveRequest will affect a window, the group, or just a local collection of windows that are snapped to the movingWindow.
|
|
2908
|
-
*/
|
|
2909
|
-
shouldMoveAffectGroup(moveRequest) {
|
|
2910
|
-
if (!this.groupMode.enabled) {
|
|
2911
|
-
return false;
|
|
2912
|
-
}
|
|
2913
|
-
if (!moveRequest.name) {
|
|
2914
|
-
return false;
|
|
2915
|
-
}
|
|
2916
|
-
const win = this.getWindow(moveRequest.name);
|
|
2917
|
-
if (!win || !win.groupNames.length) {
|
|
2918
|
-
return false;
|
|
2919
|
-
}
|
|
2920
|
-
const group = this.getMovingGroup(moveRequest);
|
|
2921
|
-
if (!group) {
|
|
2922
|
-
return false;
|
|
2923
|
-
}
|
|
2924
|
-
// A decision here was made that if we have at least one non-resizable window in the group then
|
|
2925
|
-
// We can't resize the whole group as this would also resize the non-resizable window.
|
|
2926
|
-
// This is specially problematic if we ungroup as the non resizable window won't be able to get its original size.
|
|
2927
|
-
const { windows: groupWindows } = group;
|
|
2928
|
-
if (Object.keys(groupWindows).some((key) => groupWindows[key].win.windowOptions.resizable === false)) {
|
|
2929
|
-
return false;
|
|
2930
|
-
}
|
|
2931
|
-
if (!group.isARectangle()) {
|
|
2932
|
-
return false;
|
|
2933
|
-
}
|
|
2934
|
-
// if the handle that's being dragged is on an exterior edge of a group resizing all.
|
|
2935
|
-
const resizeHandle = this.resizeObject.correctedHandle || win.getResizeHandle(moveRequest);
|
|
2936
|
-
const edges = ["top", "left", "right", "bottom"];
|
|
2937
|
-
if (moveRequest.changeType !== 0 && CORNERS.includes(resizeHandle)) {
|
|
2938
|
-
const cornerPoint = win.getPointByVertex(resizeHandle);
|
|
2939
|
-
return group.pointIsOnBoundingBox(cornerPoint);
|
|
2940
|
-
}
|
|
2941
|
-
if (moveRequest.changeType !== 0) {
|
|
2942
|
-
return win[resizeHandle] === group[resizeHandle];
|
|
2943
|
-
}
|
|
2944
|
-
// never used, but could be used if you wanted to only allow exterior windows the ability to move the group.
|
|
2945
|
-
for (let i = 0, len = edges.length; i < len; i++) {
|
|
2946
|
-
const edge = edges[i];
|
|
2947
|
-
if (win[edge] === group[edge]) {
|
|
2948
|
-
return true;
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
return false;
|
|
2952
|
-
}
|
|
2953
|
-
/**
|
|
2954
|
-
* Should use this. Computes the difference between two boundsObjects.
|
|
2955
|
-
* @param {moveRequest} newBounds
|
|
2956
|
-
* @param {moveRequest} old
|
|
2957
|
-
*/
|
|
2958
|
-
getBoundsDelta(newBounds, old) {
|
|
2959
|
-
const boundsDelta = { right: 0, left: 0 };
|
|
2960
|
-
const widthDelta = newBounds.width - old.width;
|
|
2961
|
-
const heightDelta = newBounds.height - old.height;
|
|
2962
|
-
boundsDelta.width = widthDelta;
|
|
2963
|
-
boundsDelta.height = heightDelta;
|
|
2964
|
-
boundsDelta.top = Math.abs(newBounds.top - old.top);
|
|
2965
|
-
boundsDelta.left = Math.abs(newBounds.left - old.left);
|
|
2966
|
-
if (newBounds.top < old.top) {
|
|
2967
|
-
boundsDelta.top = -boundsDelta.top;
|
|
2968
|
-
}
|
|
2969
|
-
if (newBounds.left < old.left) {
|
|
2970
|
-
boundsDelta.left = -boundsDelta.left;
|
|
2971
|
-
}
|
|
2972
|
-
return boundsDelta;
|
|
2973
|
-
}
|
|
2974
|
-
/**
|
|
2975
|
-
* Will move a group of windows.
|
|
2976
|
-
* @param {moveRequest} moveRequest
|
|
2977
|
-
* @param {function} cb
|
|
2978
|
-
*/
|
|
2979
|
-
handleGroupMove(moveRequest, cb) {
|
|
2980
|
-
const invokeCallback = function () {
|
|
2981
|
-
cb({ finished: true });
|
|
2982
|
-
};
|
|
2983
|
-
const self = this;
|
|
2984
|
-
const group = this.getMovableGroup(moveRequest.name);
|
|
2985
|
-
if (typeof moveRequest.anchor === "undefined") {
|
|
2986
|
-
const movingDirection = this.getMovingDirection(moveRequest, this.movingWindow);
|
|
2987
|
-
// If there is no moving direction (the window and the bounds are the same)
|
|
2988
|
-
// then there is nothing to do
|
|
2989
|
-
if (!movingDirection) {
|
|
2990
|
-
return invokeCallback();
|
|
2991
|
-
}
|
|
2992
|
-
moveRequest.anchor = group === null || group === void 0 ? void 0 : group.getMoveAnchor(movingDirection);
|
|
2993
|
-
}
|
|
2994
|
-
const updateGroupWindowsByDelta = function (delta, moveWindows, updateCB) {
|
|
2995
|
-
if (!group)
|
|
2996
|
-
return;
|
|
2997
|
-
const groupIter = self.groupWindowIterator(group, moveRequest.anchor);
|
|
2998
|
-
// don't need to add anything if the delta is 0.
|
|
2999
|
-
const modifyBounds = delta.x || delta.y;
|
|
3000
|
-
for (const win of groupIter) {
|
|
3001
|
-
const bounds = win.getBounds();
|
|
3002
|
-
if (modifyBounds) {
|
|
3003
|
-
const newLeft = win.left + delta.x;
|
|
3004
|
-
const newTop = win.top + delta.y;
|
|
3005
|
-
bounds.left = newLeft;
|
|
3006
|
-
bounds.top = newTop;
|
|
3007
|
-
bounds.bottom = newTop + bounds.height;
|
|
3008
|
-
bounds.right = newLeft + bounds.width;
|
|
3009
|
-
bounds.name = win.name;
|
|
3010
|
-
}
|
|
3011
|
-
// don't want wrappers saving here..
|
|
3012
|
-
bounds.persistBounds = false;
|
|
3013
|
-
if (moveWindows) {
|
|
3014
|
-
// I'm breaking my own rule by calling setBounds directly. Sadly, isJiggling was being triggered (I think...didn't really investigate), and the window wasn't moving with small adjustments. Set bounds fixes that.
|
|
3015
|
-
win.setBounds(bounds);
|
|
3016
|
-
}
|
|
3017
|
-
else {
|
|
3018
|
-
win.setInternalBounds(bounds);
|
|
3019
|
-
}
|
|
3020
|
-
}
|
|
3021
|
-
group === null || group === void 0 ? void 0 : group.updateBounds();
|
|
3022
|
-
if (updateCB) {
|
|
3023
|
-
updateCB();
|
|
3024
|
-
}
|
|
3025
|
-
};
|
|
3026
|
-
const delta = self.getMoveDelta(moveRequest);
|
|
3027
|
-
// processSnaps was added for moving groups out of claimed space. When you snapped a window to a movable group, the movable group would snap to the top of the other window rather than being dumped below the claimed space. Basically the first request would shift it down 40px, but then it'd snap to the top of the other window. When we move windows out of claimed space, processSnaps is false.
|
|
3028
|
-
if (ALLOW_GROUPS_TO_SNAP) {
|
|
3029
|
-
// make the group get its new bounds, but don't move the windows until the snap calculation is finished.
|
|
3030
|
-
updateGroupWindowsByDelta(delta, false);
|
|
3031
|
-
if (group) {
|
|
3032
|
-
const preSnapBounds = group.getBounds();
|
|
3033
|
-
let mr = group.getBounds();
|
|
3034
|
-
mr.name = moveRequest.name;
|
|
3035
|
-
mr.mousePosition = moveRequest.mousePosition;
|
|
3036
|
-
const groupMoveRequest = this.setMoveRequest(mr);
|
|
3037
|
-
groupMoveRequest.changeType = 0;
|
|
3038
|
-
this.checkBuffers(groupMoveRequest, (modifiedRequest) => {
|
|
3039
|
-
if (modifiedRequest.finished) {
|
|
3040
|
-
const moveDelta = self.getMoveDelta(modifiedRequest, preSnapBounds);
|
|
3041
|
-
updateGroupWindowsByDelta(moveDelta, true, invokeCallback);
|
|
3042
|
-
}
|
|
3043
|
-
});
|
|
3044
|
-
}
|
|
3045
|
-
}
|
|
3046
|
-
else {
|
|
3047
|
-
updateGroupWindowsByDelta(delta, true, invokeCallback);
|
|
3048
|
-
}
|
|
3049
|
-
}
|
|
3050
|
-
/**
|
|
3051
|
-
* Calculates the % change that a moveRequest inflicts on a group of windows.
|
|
3052
|
-
* @param {moveRequest} moveRequest
|
|
3053
|
-
* @return {type}
|
|
3054
|
-
*/
|
|
3055
|
-
getGroupDelta(groupName, moveRequest) {
|
|
3056
|
-
const group = this.getGroup(groupName);
|
|
3057
|
-
const win = this.getWindow(moveRequest.name);
|
|
3058
|
-
const widthDelta = moveRequest.width - win.width;
|
|
3059
|
-
const heightDelta = moveRequest.height - win.height;
|
|
3060
|
-
return {
|
|
3061
|
-
height: BoxMath.getPercentChange(group.height, group.height + heightDelta),
|
|
3062
|
-
width: BoxMath.getPercentChange(group.width, group.width + widthDelta),
|
|
3063
|
-
};
|
|
3064
|
-
}
|
|
3065
|
-
/**
|
|
3066
|
-
* Creates the resizeObject. Put anything here that should be cached onMouseDown. Will be cleared onMouseUp.
|
|
3067
|
-
* @param {moveRequest} moveRequest
|
|
3068
|
-
* @return {resizeObject}
|
|
3069
|
-
*/
|
|
3070
|
-
constructResizeObject(moveRequest) {
|
|
3071
|
-
var _a;
|
|
3072
|
-
const win = this.getWindow(moveRequest.name);
|
|
3073
|
-
const req = new DockableBox(moveRequest);
|
|
3074
|
-
const handle = req.getResizeHandle(moveRequest);
|
|
3075
|
-
// if the handle that's being dragged is on an exterior edge of a group resizing all.
|
|
3076
|
-
let resizeObject = {
|
|
3077
|
-
// This used to be derived from the window because it was only calculated on mouseDown. Now that it can be calculated at any time, we need to derive the handle from the request that's coming in. On group resizes, window bounds are only modified on mouse up.
|
|
3078
|
-
handle,
|
|
3079
|
-
type: "edge",
|
|
3080
|
-
scalingGroup: moveRequest.changeType !== 0 ? this.shouldScaleGroup(moveRequest) : false,
|
|
3081
|
-
correctedHandle: req.getResizeHandle(moveRequest),
|
|
3082
|
-
movingEdges: {
|
|
3083
|
-
top: false,
|
|
3084
|
-
right: false,
|
|
3085
|
-
left: false,
|
|
3086
|
-
bottom: false,
|
|
3087
|
-
},
|
|
3088
|
-
};
|
|
3089
|
-
if (CORNERS.includes(handle)) {
|
|
3090
|
-
resizeObject.type = "corner";
|
|
3091
|
-
if (resizeObject.scalingGroup) {
|
|
3092
|
-
resizeObject = this.correctResizeObject(win, resizeObject);
|
|
3093
|
-
}
|
|
3094
|
-
}
|
|
3095
|
-
resizeObject.movingEdges = this.getMovingEdgesFromResizeHandle(resizeObject.correctedHandle);
|
|
3096
|
-
win.resizeHandle = (_a = resizeObject.correctedHandle) !== null && _a !== void 0 ? _a : null;
|
|
3097
|
-
return resizeObject;
|
|
3098
|
-
}
|
|
3099
|
-
/**
|
|
3100
|
-
* If a corner of a window is on the edge of the group, but it's not an actual corner, we need to treat that as an edge resize. See inline documentation for more. This is basically correcting errant resize-handles.
|
|
3101
|
-
* Note: this behavior is locked behind `requireRectangularityForGroupResize`. Without that flag turned on, there's no need to change the resize handle.
|
|
3102
|
-
*/
|
|
3103
|
-
correctResizeObject(win, resizeObject) {
|
|
3104
|
-
// If we don't require rectangularity, we don't need to change the resize handle.
|
|
3105
|
-
if (this.movingGroup &&
|
|
3106
|
-
resizeObject.handle &&
|
|
3107
|
-
this.groupMode.requireRectangularityForGroupResize &&
|
|
3108
|
-
CORNERS.includes(resizeObject.handle)) {
|
|
3109
|
-
const cornerPoint = win.getPointByVertex(resizeObject.handle);
|
|
3110
|
-
if (this.movingGroup.pointIsOnBoundingBox(cornerPoint, false)) {
|
|
3111
|
-
const splitHandle = resizeObject.handle.split(/(?=[A-Z])/).map((s) => s.toLowerCase());
|
|
3112
|
-
if (this.moveRequest) {
|
|
3113
|
-
// E.g., 'bottomRight'. Takes and resets the bottom to whatever it was before the user started moving. So even if I grab the bottom right corner and drag it down, the window's bottom edge will not shift.
|
|
3114
|
-
if (this.movingWindow)
|
|
3115
|
-
this.moveRequest[splitHandle[0]] = this.movingWindow[splitHandle[0]];
|
|
3116
|
-
this.moveRequest.height = this.moveRequest.bottom - this.moveRequest.top;
|
|
3117
|
-
this.moveRequest.width = this.moveRequest.right - this.moveRequest.left;
|
|
3118
|
-
}
|
|
3119
|
-
resizeObject.type = "edge";
|
|
3120
|
-
// e.g., bottomRight; this will just choose 'right'. This happens when you grab the corner of a window that's also on the edge of the window...but isn't the corner of the group.
|
|
3121
|
-
const groupEdge = this.movingGroup.getWindow(win).getEdgeByPoint(cornerPoint);
|
|
3122
|
-
resizeObject.correctedHandle = groupEdge;
|
|
3123
|
-
}
|
|
3124
|
-
}
|
|
3125
|
-
return resizeObject;
|
|
3126
|
-
}
|
|
3127
|
-
/**
|
|
3128
|
-
* Resizes a window based on some delta.
|
|
3129
|
-
* @param {dockableWindow} win
|
|
3130
|
-
* @param {Object} delta Object with a width/height change.
|
|
3131
|
-
* @return {type}
|
|
3132
|
-
*/
|
|
3133
|
-
resizeByDelta(win, delta) {
|
|
3134
|
-
const bounds = win.getBounds();
|
|
3135
|
-
bounds.width = BoxMath.scaleProportionately(win.width, delta.width);
|
|
3136
|
-
bounds.height = BoxMath.scaleProportionately(win.height, delta.height);
|
|
3137
|
-
if (win.resizeHandle.toLowerCase().includes("right")) {
|
|
3138
|
-
bounds.right = bounds.left + bounds.width;
|
|
3139
|
-
}
|
|
3140
|
-
if (win.resizeHandle.toLowerCase().includes("bottom")) {
|
|
3141
|
-
bounds.bottom = bounds.top + bounds.height;
|
|
3142
|
-
}
|
|
3143
|
-
if (win.resizeHandle.toLowerCase().includes("top")) {
|
|
3144
|
-
bounds.top = bounds.bottom - bounds.height;
|
|
3145
|
-
}
|
|
3146
|
-
if (win.resizeHandle.toLowerCase().includes("left")) {
|
|
3147
|
-
bounds.left = bounds.right - bounds.width;
|
|
3148
|
-
}
|
|
3149
|
-
return bounds;
|
|
3150
|
-
}
|
|
3151
|
-
getMovingDirection(bounds, win) {
|
|
3152
|
-
if (!win) {
|
|
3153
|
-
win = this.getWindow(bounds.name);
|
|
3154
|
-
}
|
|
3155
|
-
let direction = "";
|
|
3156
|
-
if (win.left > bounds.left) {
|
|
3157
|
-
direction = "Left";
|
|
3158
|
-
}
|
|
3159
|
-
if (win.left < bounds.left) {
|
|
3160
|
-
direction = `${direction}Right`;
|
|
3161
|
-
}
|
|
3162
|
-
if (win.top > bounds.top) {
|
|
3163
|
-
direction = `${direction}Top`;
|
|
3164
|
-
}
|
|
3165
|
-
if (win.top < bounds.top) {
|
|
3166
|
-
direction = `${direction}Bottom`;
|
|
3167
|
-
}
|
|
3168
|
-
return direction;
|
|
3169
|
-
}
|
|
3170
|
-
/**
|
|
3171
|
-
* Does the dirty work of actually moving windows.
|
|
3172
|
-
* @param {moveRequest} bounds
|
|
3173
|
-
* @param {function} callback
|
|
3174
|
-
*/
|
|
3175
|
-
moveWindow(bounds, callback) {
|
|
3176
|
-
// if window resize causes ANY window to be smaller than the minimum_width, quit that shit.
|
|
3177
|
-
if (!bounds) {
|
|
3178
|
-
if (callback) {
|
|
3179
|
-
callback();
|
|
3180
|
-
}
|
|
3181
|
-
return;
|
|
3182
|
-
}
|
|
3183
|
-
if (!callback) {
|
|
3184
|
-
callback = function noop() { };
|
|
3185
|
-
}
|
|
3186
|
-
const win = this.getWindow(bounds.name);
|
|
3187
|
-
if (win) {
|
|
3188
|
-
bounds.persistBounds = false;
|
|
3189
|
-
//Fixing the toolbar height on Mac. When Toolbar is running with dashbar on Mac it should be resizable only by X axis.
|
|
3190
|
-
let isMacOs = navigator.platform.indexOf("Mac") != -1;
|
|
3191
|
-
if (isMacOs && bounds.name.indexOf("Toolbar") != -1) {
|
|
3192
|
-
bounds.height = win.limits.maxHeight;
|
|
3193
|
-
}
|
|
3194
|
-
win.setBounds(bounds, callback);
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3197
|
-
checkMoveDockedCommponent(moveRequest, movingWindow) {
|
|
3198
|
-
if (movingWindow.dockedPosition === movingWindow.monitorDockablePositions.TOP) {
|
|
3199
|
-
moveRequest.top = movingWindow.top + this.bufferSize * 2;
|
|
3200
|
-
moveRequest.bottom = moveRequest.top + movingWindow.height;
|
|
3201
|
-
}
|
|
3202
|
-
else if (movingWindow.dockedPosition === movingWindow.monitorDockablePositions.BOTTOM) {
|
|
3203
|
-
moveRequest.bottom = movingWindow.bottom - this.bufferSize * 2;
|
|
3204
|
-
moveRequest.top = moveRequest.bottom - movingWindow.height;
|
|
3205
|
-
}
|
|
3206
|
-
moveRequest.height = movingWindow.undockedPosition.height;
|
|
3207
|
-
moveRequest.width = movingWindow.undockedPosition.width;
|
|
3208
|
-
const { monitor } = movingWindow;
|
|
3209
|
-
if (movingWindow.dockedMonitor) {
|
|
3210
|
-
moveRequest.dockedMonitor = movingWindow.dockedMonitor;
|
|
3211
|
-
delete movingWindow.dockedMonitor;
|
|
3212
|
-
}
|
|
3213
|
-
monitor.undockWindowFromMonitor(movingWindow);
|
|
3214
|
-
this.hideGroupMask();
|
|
3215
|
-
}
|
|
3216
|
-
/**
|
|
3217
|
-
* Checks to see whether a window can be snapped to other windows/monitors.
|
|
3218
|
-
* @param {moveRequest} bounds
|
|
3219
|
-
* @param {function} callback
|
|
3220
|
-
*/
|
|
3221
|
-
checkBuffers(moveRequest, cb) {
|
|
3222
|
-
var _a, _b;
|
|
3223
|
-
if (this.movingWindow && this.movingWindow.ignoreSnappingRequests) {
|
|
3224
|
-
moveRequest.ignoreSnappingRequests = true;
|
|
3225
|
-
}
|
|
3226
|
-
let snappableWindows = this.getSnappableWindows(moveRequest);
|
|
3227
|
-
let snappableMonitors = this.getSnappableMonitors(moveRequest);
|
|
3228
|
-
// When a window is moved (ends up inside checkBuffers) and it is docked, we can safely assume the window is being undocked (why else would you move a window that takes up the width of the window (or height)?). Here, we set the new bounds of the move request and call to undock the window, which will propagate to all the necessary items changing (the window will shrink, undock, etc).
|
|
3229
|
-
if (this.movingWindow && this.movingWindow.win.isDocked) {
|
|
3230
|
-
// if the user tries to resize a docked component, ignore it.
|
|
3231
|
-
if (moveRequest.changeType !== 0) {
|
|
3232
|
-
const req = this.movingWindow.getBounds();
|
|
3233
|
-
req.name = this.movingWindow.name;
|
|
3234
|
-
req.finished = true;
|
|
3235
|
-
this.hideGroupMask();
|
|
3236
|
-
cb(req);
|
|
3237
|
-
return;
|
|
3238
|
-
}
|
|
3239
|
-
this.checkMoveDockedCommponent(moveRequest, this.movingWindow);
|
|
3240
|
-
// Force exit
|
|
3241
|
-
delete this.movingWindow.snappedMonitor;
|
|
3242
|
-
snappableWindows = [];
|
|
3243
|
-
snappableMonitors = [];
|
|
3244
|
-
}
|
|
3245
|
-
// processSnaps was added for moving groups out of claimed space. When you snapped a window to a movable group, the movable group would snap to the top of the other window rather than being dumped below the claimed space. Basically the first request would shift it down 40px, but then it'd snap to the top of the other window. When we move windows out of claimed space, processSnaps is false.
|
|
3246
|
-
const snappable = snappableWindows.length || snappableMonitors.length;
|
|
3247
|
-
if (moveRequest.processSnaps === false || !snappable) {
|
|
3248
|
-
moveRequest.finished = true;
|
|
3249
|
-
this.hideGroupMask();
|
|
3250
|
-
cb(moveRequest);
|
|
3251
|
-
return;
|
|
3252
|
-
}
|
|
3253
|
-
const checkDocked = (movingWindow, monitor, snapRequest) => {
|
|
3254
|
-
var _a;
|
|
3255
|
-
// If we've made it this far we're moving a dockable component and it isn't already docked (which means we're constantly checking for whether we need to dock). Here we do calculations to determine if a 'dockable mask' should be shown.
|
|
3256
|
-
movingWindow.snappedMonitor = monitor;
|
|
3257
|
-
const clonedRequest = fastClone(snapRequest);
|
|
3258
|
-
snapRequest.dockedMonitor = monitor.name;
|
|
3259
|
-
// The weird math of determining dashbar + toolbar height on initialization will cause the
|
|
3260
|
-
// calculated height of the docking mask to be incorrect. Resetting it here with the
|
|
3261
|
-
// params on the window tells the docking mask to be the correct docked height
|
|
3262
|
-
if (movingWindow.dockedParams) {
|
|
3263
|
-
clonedRequest.dockedHeight = movingWindow.dockedParams.height;
|
|
3264
|
-
}
|
|
3265
|
-
clonedRequest.dockableEdges = (_a = movingWindow.dockingOptions) === null || _a === void 0 ? void 0 : _a.dockable;
|
|
3266
|
-
const newBounds = monitor.getDockedPosition(clonedRequest);
|
|
3267
|
-
if (newBounds) {
|
|
3268
|
-
this.showGroupMask({ bounds: newBounds });
|
|
3269
|
-
}
|
|
3270
|
-
};
|
|
3271
|
-
for (let i = 0, len = snappableMonitors.length; i < len; i++) {
|
|
3272
|
-
const monitor = MonitorPoolSingleton.get(snappableMonitors[i]);
|
|
3273
|
-
const snapRequest = monitor.snapWindow(moveRequest);
|
|
3274
|
-
if ((_a = this.movingWindow) === null || _a === void 0 ? void 0 : _a.isDockableComponent) {
|
|
3275
|
-
checkDocked(this.movingWindow, monitor, snapRequest);
|
|
3276
|
-
snappableWindows = []; // Force exit if window docks to monitor
|
|
3277
|
-
}
|
|
3278
|
-
moveRequest = snapRequest !== null && snapRequest !== void 0 ? snapRequest : moveRequest;
|
|
3279
|
-
// If only a monitor is a possible snap then return here (otherwise continue on to add the snappable windows)
|
|
3280
|
-
if (i === snappableMonitors.length - 1 && snappableWindows.length === 0) {
|
|
3281
|
-
moveRequest.finished = true;
|
|
3282
|
-
cb(moveRequest);
|
|
3283
|
-
return;
|
|
3284
|
-
}
|
|
3285
|
-
}
|
|
3286
|
-
for (let i = 0, len = snappableWindows.length; i < len; i++) {
|
|
3287
|
-
const win = this.getWindow(snappableWindows[i]);
|
|
3288
|
-
this.setStationaryWindow(win);
|
|
3289
|
-
win.setOpacity({ opacity: SNAPPING_OPACITY });
|
|
3290
|
-
// The original request has been changed because of a snap to a straddler window. replace the reference so new comparisons are made against the newly snapped window.
|
|
3291
|
-
moveRequest = (_b = this.snapWindow(moveRequest)) !== null && _b !== void 0 ? _b : moveRequest;
|
|
3292
|
-
moveRequest.windowBoundingBox = BoxMath.getWindowBoundingBox(moveRequest);
|
|
3293
|
-
}
|
|
3294
|
-
moveRequest.finished = true;
|
|
3295
|
-
cb(moveRequest);
|
|
3296
|
-
}
|
|
3297
|
-
/**
|
|
3298
|
-
* Spins through windows and fixes opacity. For onMouseMove, we skip any windows that could be snapped to the movingWindow. onMouseUp, everything gets hit.
|
|
3299
|
-
* @param {object} params
|
|
3300
|
-
* @param {object} params.checkForSnappability
|
|
3301
|
-
*/
|
|
3302
|
-
fixWindowOpacity(params) {
|
|
3303
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
3304
|
-
for (const win of dockingPoolIterator) {
|
|
3305
|
-
if (params.checkForSnappability && this.moveRequest && win.canSnapToWindow(this.moveRequest)) {
|
|
3306
|
-
continue;
|
|
3307
|
-
}
|
|
3308
|
-
params.opacity = 1;
|
|
3309
|
-
win.setOpacity(params);
|
|
3310
|
-
}
|
|
3311
|
-
}
|
|
3312
|
-
saveWindowsOpacity() {
|
|
3313
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
3314
|
-
for (const win of dockingPoolIterator) {
|
|
3315
|
-
this.persistedOpacity[win.name] = win.win.windowOptions.opacity;
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
restoreWindowsOpacity() {
|
|
3319
|
-
const dockingPoolIterator = DockingPoolSingleton.iterator();
|
|
3320
|
-
for (const win of dockingPoolIterator) {
|
|
3321
|
-
const params = {
|
|
3322
|
-
opacity: this.persistedOpacity[win.name] || 1,
|
|
3323
|
-
};
|
|
3324
|
-
win.setOpacity(params);
|
|
3325
|
-
}
|
|
3326
|
-
}
|
|
3327
|
-
/**
|
|
3328
|
-
* Happens when config is loaded from the configClient.
|
|
3329
|
-
*/
|
|
3330
|
-
setGlobalMinimums(serviceConfig) {
|
|
3331
|
-
this.MINIMUM_HEIGHT = serviceConfig.MINIMUM_HEIGHT;
|
|
3332
|
-
this.MINIMUM_WIDTH = serviceConfig.MINIMUM_WIDTH;
|
|
3333
|
-
const groups = this.getGroupNames();
|
|
3334
|
-
groups.forEach((name) => {
|
|
3335
|
-
const group = this.getGroup(name);
|
|
3336
|
-
group.setMinimums(serviceConfig);
|
|
3337
|
-
});
|
|
3338
|
-
}
|
|
3339
|
-
/** **************************************
|
|
3340
|
-
* Calculators - general *
|
|
3341
|
-
*************************************** */
|
|
3342
|
-
/**
|
|
3343
|
-
* Given an object, will set boundingboxes on it. If it's a dockableWindow, it'll let the window set itself up.
|
|
3344
|
-
* @param {dockableWindow} win
|
|
3345
|
-
* @return {type}
|
|
3346
|
-
*/
|
|
3347
|
-
setBoundingBoxes(win) {
|
|
3348
|
-
if (win.setBoundingBoxes) {
|
|
3349
|
-
win.setBoundingBoxes();
|
|
3350
|
-
}
|
|
3351
|
-
else {
|
|
3352
|
-
win.buffer = this.getBuffer(win);
|
|
3353
|
-
win.snappingRegions = BoxMath.getSnappingRegions(win, this.bufferSize);
|
|
3354
|
-
win.windowBoundingBox = BoxMath.getWindowBoundingBox(win);
|
|
3355
|
-
win.innerBuffer = this.getInnerBoundingBox(win);
|
|
3356
|
-
}
|
|
3357
|
-
return win;
|
|
3358
|
-
}
|
|
3359
|
-
/**
|
|
3360
|
-
* Returns the difference between the movingWindow's location and the requested movement.
|
|
3361
|
-
* @param {moveRequest} moveRequest
|
|
3362
|
-
* @return {type}
|
|
3363
|
-
*/
|
|
3364
|
-
getMoveDelta(moveRequest, oldBounds) {
|
|
3365
|
-
const movingWin = oldBounds || this.getWindow(moveRequest.name);
|
|
3366
|
-
return {
|
|
3367
|
-
x: moveRequest.left - movingWin.left,
|
|
3368
|
-
y: moveRequest.top - movingWin.top,
|
|
3369
|
-
};
|
|
3370
|
-
}
|
|
3371
|
-
/**
|
|
3372
|
-
* Returns the inner bounds. We use this to give the windows some internal stickiness.
|
|
3373
|
-
* @param {type} bounds
|
|
3374
|
-
* @return {object}
|
|
3375
|
-
*/
|
|
3376
|
-
getInnerBoundingBox(bounds) {
|
|
3377
|
-
return {
|
|
3378
|
-
min: {
|
|
3379
|
-
x: bounds.left + this.bufferSize,
|
|
3380
|
-
y: bounds.top + this.bufferSize,
|
|
3381
|
-
},
|
|
3382
|
-
max: {
|
|
3383
|
-
x: bounds.right - this.bufferSize,
|
|
3384
|
-
y: bounds.bottom - this.bufferSize,
|
|
3385
|
-
},
|
|
3386
|
-
};
|
|
3387
|
-
}
|
|
3388
|
-
/**
|
|
3389
|
-
* Gets the snapping buffer of a request.
|
|
3390
|
-
* @param {type} request
|
|
3391
|
-
* @return {type}
|
|
3392
|
-
*/
|
|
3393
|
-
getBuffer(request) {
|
|
3394
|
-
return {
|
|
3395
|
-
min: {
|
|
3396
|
-
x: request.left - this.bufferSize,
|
|
3397
|
-
y: request.top - this.bufferSize,
|
|
3398
|
-
},
|
|
3399
|
-
max: {
|
|
3400
|
-
x: request.right + this.bufferSize,
|
|
3401
|
-
y: request.bottom + this.bufferSize,
|
|
3402
|
-
},
|
|
3403
|
-
};
|
|
3404
|
-
}
|
|
3405
|
-
/**
|
|
3406
|
-
* Given a request, a window, and a region, it'll tell you whether they intersect. We use this to figure out which corner/edge to snap to.
|
|
3407
|
-
* @param {moveRequest} moveRequest
|
|
3408
|
-
* @param {dockableWindow} stationaryWindow
|
|
3409
|
-
* @param {string} stationaryRegion
|
|
3410
|
-
* @return {object}
|
|
3411
|
-
*/
|
|
3412
|
-
getIntersections(moveRequest, stationaryWindow, stationaryRegion) {
|
|
3413
|
-
const movingBoundingBoxes = moveRequest.snappingRegions;
|
|
3414
|
-
const stationaryBoundingBoxes = stationaryWindow.snappingRegions;
|
|
3415
|
-
const intersections = [];
|
|
3416
|
-
for (const movingRegion in movingBoundingBoxes) {
|
|
3417
|
-
if (movingRegion === "inner") {
|
|
3418
|
-
continue;
|
|
3419
|
-
}
|
|
3420
|
-
if (BoxMath.intersectBoundingBoxes(stationaryBoundingBoxes[stationaryRegion], movingBoundingBoxes[movingRegion])) {
|
|
3421
|
-
intersections.push(movingRegion);
|
|
3422
|
-
}
|
|
3423
|
-
}
|
|
3424
|
-
return intersections;
|
|
3425
|
-
}
|
|
3426
|
-
/** **************************************
|
|
3427
|
-
* Iterators *
|
|
3428
|
-
*************************************** */
|
|
3429
|
-
*groupWindowIterator(group, orderAnchor = this.movingWindow) {
|
|
3430
|
-
const windows = this.orderWindows(group.windows, orderAnchor);
|
|
3431
|
-
// preserves order..for .. in does not.
|
|
3432
|
-
for (let i = 0; i < windows.length; i++) {
|
|
3433
|
-
yield windows[i];
|
|
3434
|
-
}
|
|
3435
|
-
}
|
|
3436
|
-
}
|
|
3437
|
-
export default DockingCalculator;
|
|
3438
|
-
//# sourceMappingURL=dockingCalculator.js.map
|