@datagrok-libraries/dock-spawn-dg 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/.eslintrc.json +47 -0
  2. package/CHANGELOG.md +355 -0
  3. package/LICENSE +21 -0
  4. package/README.md +11 -0
  5. package/css/dock-manager-context-menu.css +19 -0
  6. package/css/dock-manager-style.css +190 -0
  7. package/css/dock-manager.css +411 -0
  8. package/images/close.svg +6 -0
  9. package/images/dock_bottom.png +0 -0
  10. package/images/dock_bottom_sel.png +0 -0
  11. package/images/dock_fill.png +0 -0
  12. package/images/dock_fill_sel.png +0 -0
  13. package/images/dock_left.png +0 -0
  14. package/images/dock_left_sel.png +0 -0
  15. package/images/dock_right.png +0 -0
  16. package/images/dock_right_sel.png +0 -0
  17. package/images/dock_top.png +0 -0
  18. package/images/dock_top_sel.png +0 -0
  19. package/index.ts +32 -0
  20. package/lib/BrowserDialogHelper.d.ts +8 -0
  21. package/lib/BrowserDialogHelper.d.ts.map +1 -0
  22. package/lib/BrowserDialogHelper.js +60 -0
  23. package/lib/ContainerType.d.ts +7 -0
  24. package/lib/ContainerType.d.ts.map +1 -0
  25. package/lib/ContainerType.js +7 -0
  26. package/lib/Dialog.d.ts +51 -0
  27. package/lib/Dialog.d.ts.map +1 -0
  28. package/lib/Dialog.js +209 -0
  29. package/lib/DockConfig.d.ts +9 -0
  30. package/lib/DockConfig.d.ts.map +1 -0
  31. package/lib/DockConfig.js +14 -0
  32. package/lib/DockGraphDeserializer.d.ts +19 -0
  33. package/lib/DockGraphDeserializer.d.ts.map +1 -0
  34. package/lib/DockGraphDeserializer.js +114 -0
  35. package/lib/DockGraphSerializer.d.ts +14 -0
  36. package/lib/DockGraphSerializer.d.ts.map +1 -0
  37. package/lib/DockGraphSerializer.js +40 -0
  38. package/lib/DockLayoutEngine.d.ts +36 -0
  39. package/lib/DockLayoutEngine.d.ts.map +1 -0
  40. package/lib/DockLayoutEngine.js +323 -0
  41. package/lib/DockManager.d.ts +155 -0
  42. package/lib/DockManager.d.ts.map +1 -0
  43. package/lib/DockManager.js +752 -0
  44. package/lib/DockManagerContext.d.ts +10 -0
  45. package/lib/DockManagerContext.d.ts.map +1 -0
  46. package/lib/DockManagerContext.js +12 -0
  47. package/lib/DockModel.d.ts +9 -0
  48. package/lib/DockModel.d.ts.map +1 -0
  49. package/lib/DockModel.js +8 -0
  50. package/lib/DockNode.d.ts +16 -0
  51. package/lib/DockNode.d.ts.map +1 -0
  52. package/lib/DockNode.js +64 -0
  53. package/lib/DockWheel.d.ts +41 -0
  54. package/lib/DockWheel.d.ts.map +1 -0
  55. package/lib/DockWheel.js +208 -0
  56. package/lib/DockWheelItem.d.ts +16 -0
  57. package/lib/DockWheelItem.d.ts.map +1 -0
  58. package/lib/DockWheelItem.js +34 -0
  59. package/lib/DocumentManagerContainer.d.ts +16 -0
  60. package/lib/DocumentManagerContainer.d.ts.map +1 -0
  61. package/lib/DocumentManagerContainer.js +28 -0
  62. package/lib/DocumentTabPage.d.ts +11 -0
  63. package/lib/DocumentTabPage.d.ts.map +1 -0
  64. package/lib/DocumentTabPage.js +26 -0
  65. package/lib/DraggableContainer.d.ts +51 -0
  66. package/lib/DraggableContainer.d.ts.map +1 -0
  67. package/lib/DraggableContainer.js +145 -0
  68. package/lib/EventHandler.d.ts +8 -0
  69. package/lib/EventHandler.d.ts.map +1 -0
  70. package/lib/EventHandler.js +14 -0
  71. package/lib/FillDockContainer.d.ts +34 -0
  72. package/lib/FillDockContainer.d.ts.map +1 -0
  73. package/lib/FillDockContainer.js +80 -0
  74. package/lib/HorizontalDockContainer.d.ts +7 -0
  75. package/lib/HorizontalDockContainer.d.ts.map +1 -0
  76. package/lib/HorizontalDockContainer.js +9 -0
  77. package/lib/PanelContainer.d.ts +114 -0
  78. package/lib/PanelContainer.d.ts.map +1 -0
  79. package/lib/PanelContainer.js +517 -0
  80. package/lib/Point.d.ts +6 -0
  81. package/lib/Point.d.ts.map +1 -0
  82. package/lib/Point.js +8 -0
  83. package/lib/ResizableContainer.d.ts +56 -0
  84. package/lib/ResizableContainer.d.ts.map +1 -0
  85. package/lib/ResizableContainer.js +254 -0
  86. package/lib/ResizeHandle.d.ts +16 -0
  87. package/lib/ResizeHandle.d.ts.map +1 -0
  88. package/lib/ResizeHandle.js +58 -0
  89. package/lib/SplitterBar.d.ts +33 -0
  90. package/lib/SplitterBar.d.ts.map +1 -0
  91. package/lib/SplitterBar.js +137 -0
  92. package/lib/SplitterDockContainer.d.ts +36 -0
  93. package/lib/SplitterDockContainer.d.ts.map +1 -0
  94. package/lib/SplitterDockContainer.js +75 -0
  95. package/lib/SplitterPanel.d.ts +27 -0
  96. package/lib/SplitterPanel.d.ts.map +1 -0
  97. package/lib/SplitterPanel.js +195 -0
  98. package/lib/TabHandle.d.ts +56 -0
  99. package/lib/TabHandle.d.ts.map +1 -0
  100. package/lib/TabHandle.js +292 -0
  101. package/lib/TabHost.d.ts +47 -0
  102. package/lib/TabHost.d.ts.map +1 -0
  103. package/lib/TabHost.js +238 -0
  104. package/lib/TabPage.d.ts +20 -0
  105. package/lib/TabPage.d.ts.map +1 -0
  106. package/lib/TabPage.js +81 -0
  107. package/lib/UndockInitiator.d.ts +32 -0
  108. package/lib/UndockInitiator.d.ts.map +1 -0
  109. package/lib/UndockInitiator.js +152 -0
  110. package/lib/Utils.d.ts +15 -0
  111. package/lib/Utils.d.ts.map +1 -0
  112. package/lib/Utils.js +69 -0
  113. package/lib/VerticalDockContainer.d.ts +7 -0
  114. package/lib/VerticalDockContainer.d.ts.map +1 -0
  115. package/lib/VerticalDockContainer.js +9 -0
  116. package/lib/enums/PanelType.d.ts +5 -0
  117. package/lib/enums/PanelType.d.ts.map +1 -0
  118. package/lib/enums/PanelType.js +5 -0
  119. package/lib/enums/TabHostDirection.d.ts +7 -0
  120. package/lib/enums/TabHostDirection.d.ts.map +1 -0
  121. package/lib/enums/TabHostDirection.js +7 -0
  122. package/lib/enums/WheelTypes.d.ts +12 -0
  123. package/lib/enums/WheelTypes.d.ts.map +1 -0
  124. package/lib/enums/WheelTypes.js +14 -0
  125. package/lib/i18n/Defaults.d.ts +12 -0
  126. package/lib/i18n/Defaults.d.ts.map +1 -0
  127. package/lib/i18n/Defaults.js +9 -0
  128. package/lib/i18n/Localizer.d.ts +7 -0
  129. package/lib/i18n/Localizer.d.ts.map +1 -0
  130. package/lib/i18n/Localizer.js +16 -0
  131. package/lib/index.d.ts +33 -0
  132. package/lib/index.d.ts.map +1 -0
  133. package/lib/index.js +32 -0
  134. package/lib/interfaces/IDockContainer.d.ts +26 -0
  135. package/lib/interfaces/IDockContainer.d.ts.map +1 -0
  136. package/lib/interfaces/IDockContainer.js +1 -0
  137. package/lib/interfaces/IDockContainerWithSize.d.ts +6 -0
  138. package/lib/interfaces/IDockContainerWithSize.d.ts.map +1 -0
  139. package/lib/interfaces/IDockContainerWithSize.js +1 -0
  140. package/lib/interfaces/ILayoutEventListener.d.ts +27 -0
  141. package/lib/interfaces/ILayoutEventListener.d.ts.map +1 -0
  142. package/lib/interfaces/ILayoutEventListener.js +1 -0
  143. package/lib/interfaces/IMouseOrTouchEvent.d.ts +7 -0
  144. package/lib/interfaces/IMouseOrTouchEvent.d.ts.map +1 -0
  145. package/lib/interfaces/IMouseOrTouchEvent.js +1 -0
  146. package/lib/interfaces/INodeInfo.d.ts +8 -0
  147. package/lib/interfaces/INodeInfo.d.ts.map +1 -0
  148. package/lib/interfaces/INodeInfo.js +1 -0
  149. package/lib/interfaces/IPanelInfo.d.ts +10 -0
  150. package/lib/interfaces/IPanelInfo.d.ts.map +1 -0
  151. package/lib/interfaces/IPanelInfo.js +1 -0
  152. package/lib/interfaces/IRectangle.d.ts +7 -0
  153. package/lib/interfaces/IRectangle.d.ts.map +1 -0
  154. package/lib/interfaces/IRectangle.js +1 -0
  155. package/lib/interfaces/ISize.d.ts +5 -0
  156. package/lib/interfaces/ISize.d.ts.map +1 -0
  157. package/lib/interfaces/ISize.js +1 -0
  158. package/lib/interfaces/IState.d.ts +12 -0
  159. package/lib/interfaces/IState.d.ts.map +1 -0
  160. package/lib/interfaces/IState.js +1 -0
  161. package/lib/interfaces/IThickness.d.ts +7 -0
  162. package/lib/interfaces/IThickness.d.ts.map +1 -0
  163. package/lib/interfaces/IThickness.js +1 -0
  164. package/lib/webcomponent/DockSpawnTsWebcomponent.d.ts +35 -0
  165. package/lib/webcomponent/DockSpawnTsWebcomponent.d.ts.map +1 -0
  166. package/lib/webcomponent/DockSpawnTsWebcomponent.js +209 -0
  167. package/lib/webcomponent/styles.d.ts +5 -0
  168. package/lib/webcomponent/styles.d.ts.map +1 -0
  169. package/lib/webcomponent/styles.js +537 -0
  170. package/package.json +36 -0
  171. package/src/BrowserDialogHelper.ts +76 -0
  172. package/src/ContainerType.ts +6 -0
  173. package/src/Dialog.ts +253 -0
  174. package/src/DockConfig.ts +15 -0
  175. package/src/DockGraphDeserializer.ts +129 -0
  176. package/src/DockGraphSerializer.ts +53 -0
  177. package/src/DockLayoutEngine.ts +370 -0
  178. package/src/DockManager.ts +880 -0
  179. package/src/DockManagerContext.ts +16 -0
  180. package/src/DockModel.ts +12 -0
  181. package/src/DockNode.ts +81 -0
  182. package/src/DockWheel.ts +215 -0
  183. package/src/DockWheelItem.ts +41 -0
  184. package/src/DocumentManagerContainer.ts +39 -0
  185. package/src/DocumentTabPage.ts +35 -0
  186. package/src/DraggableContainer.ts +177 -0
  187. package/src/EventHandler.ts +17 -0
  188. package/src/FillDockContainer.ts +98 -0
  189. package/src/HorizontalDockContainer.ts +13 -0
  190. package/src/PanelContainer.ts +596 -0
  191. package/src/Point.ts +10 -0
  192. package/src/ResizableContainer.ts +293 -0
  193. package/src/ResizeHandle.ts +59 -0
  194. package/src/SplitterBar.ts +157 -0
  195. package/src/SplitterDockContainer.ts +95 -0
  196. package/src/SplitterPanel.ts +228 -0
  197. package/src/TabHandle.ts +347 -0
  198. package/src/TabHost.ts +267 -0
  199. package/src/TabPage.ts +98 -0
  200. package/src/UndockInitiator.ts +181 -0
  201. package/src/Utils.ts +85 -0
  202. package/src/VerticalDockContainer.ts +13 -0
  203. package/src/enums/PanelType.ts +4 -0
  204. package/src/enums/TabHostDirection.ts +6 -0
  205. package/src/enums/WheelTypes.ts +14 -0
  206. package/src/i18n/Defaults.ts +20 -0
  207. package/src/i18n/Localizer.ts +23 -0
  208. package/src/index.ts +32 -0
  209. package/src/interfaces/IDockContainer.ts +27 -0
  210. package/src/interfaces/IDockContainerWithSize.ts +6 -0
  211. package/src/interfaces/ILayoutEventListener.ts +28 -0
  212. package/src/interfaces/IMouseOrTouchEvent.ts +6 -0
  213. package/src/interfaces/INodeInfo.ts +8 -0
  214. package/src/interfaces/IPanelInfo.ts +10 -0
  215. package/src/interfaces/IRectangle.ts +6 -0
  216. package/src/interfaces/ISize.ts +4 -0
  217. package/src/interfaces/IState.ts +12 -0
  218. package/src/interfaces/IThickness.ts +6 -0
  219. package/src/webcomponent/DockSpawnTsWebcomponent.ts +248 -0
  220. package/src/webcomponent/styles.ts +544 -0
  221. package/tsconfig.json +74 -0
  222. package/tsconfig.tsbuildinfo +1 -0
package/src/Dialog.ts ADDED
@@ -0,0 +1,253 @@
1
+ import {DockManager} from './DockManager.js';
2
+ import {Point} from './Point.js';
3
+ import {PanelContainer} from './PanelContainer.js';
4
+ import {DraggableContainer} from './DraggableContainer.js';
5
+ import {ResizableContainer} from './ResizableContainer.js';
6
+ import {EventHandler} from './EventHandler.js';
7
+ import {Utils} from './Utils.js';
8
+ import {Localizer} from './i18n/Localizer.js';
9
+ import {DockNode} from './DockNode.js';
10
+
11
+ export class Dialog {
12
+ elementDialog: HTMLDivElement & { floatingDialog: Dialog };
13
+ draggable: DraggableContainer;
14
+ panel: PanelContainer;
15
+ dockManager: DockManager;
16
+ eventListener: DockManager;
17
+ position: Point;
18
+ resizable: ResizableContainer;
19
+ disableResize: boolean;
20
+ mouseDownHandler: any;
21
+ onKeyPressBound: any;
22
+ noDocking: boolean;
23
+ isHidden: boolean;
24
+ keyPressHandler: EventHandler;
25
+ focusHandler: EventHandler;
26
+ grayoutParent: PanelContainer;
27
+ contextmenuHandler: EventHandler;
28
+ _ctxMenu: HTMLDivElement;
29
+ _windowsContextMenuCloseBound: any;
30
+
31
+ constructor(panel: PanelContainer, dockManager: DockManager, grayoutParent?: PanelContainer, disableResize?: boolean) {
32
+ this.panel = panel;
33
+ this.dockManager = dockManager;
34
+ this.eventListener = dockManager;
35
+ this.grayoutParent = grayoutParent;
36
+ this.disableResize = disableResize;
37
+ this._initialize();
38
+ this.dockManager.context.model.dialogs.push(this);
39
+ this.position = dockManager.defaultDialogPosition;
40
+ this.dockManager.notifyOnCreateDialog(this);
41
+ panel.isDialog = true;
42
+ }
43
+
44
+ saveState(x: number, y: number) {
45
+ this.position = new Point(x, y);
46
+ this.dockManager.notifyOnChangeDialogPosition(this, x, y);
47
+ }
48
+
49
+ static fromElement(id: string, dockManager: DockManager) {
50
+ return new Dialog(new PanelContainer(<HTMLElement>document.getElementById(id), dockManager), dockManager, null);
51
+ }
52
+
53
+ _initialize() {
54
+ this.panel.floatingDialog = this;
55
+ this.elementDialog = Object.assign(document.createElement('div'), {floatingDialog: this});
56
+ this.elementDialog.tabIndex = 0;
57
+ this.elementDialog.appendChild(this.panel.elementPanel);
58
+ this.draggable = new DraggableContainer(this, this.panel, this.elementDialog, this.panel.elementTitle);
59
+ this.resizable = new ResizableContainer(this, this.draggable, this.draggable.topLevelElement, this.disableResize);
60
+
61
+ this.dockManager.config.dialogRootElement.appendChild(this.elementDialog);
62
+ this.elementDialog.classList.add('dialog-floating');
63
+
64
+ this.focusHandler = new EventHandler(this.elementDialog, 'focus', this.onFocus.bind(this), true);
65
+ this.mouseDownHandler = new EventHandler(this.elementDialog, 'pointerdown', this.onMouseDown.bind(this), true);
66
+ this.keyPressHandler = new EventHandler(this.elementDialog, 'keypress', this.dockManager.onKeyPressBound, true);
67
+ this.contextmenuHandler = new EventHandler(this.panel.elementTitle, 'contextmenu', this.oncontextMenuClicked.bind(this));
68
+
69
+ this.resize(this.panel.elementPanel.clientWidth, this.panel.elementPanel.clientHeight);
70
+ this.isHidden = false;
71
+
72
+ if (this.grayoutParent != null)
73
+ this.grayoutParent.grayOut(true);
74
+
75
+ this.bringToFront();
76
+ }
77
+
78
+ setPosition(x: number, y: number) {
79
+ const rect = this.dockManager.config.dialogRootElement.getBoundingClientRect();
80
+ this.position = new Point(x - rect.left, y - rect.top);
81
+ this.elementDialog.style.left = (x - rect.left) + 'px';
82
+ this.elementDialog.style.top = (y - rect.top) + 'px';
83
+ this.panel.setDialogPosition(x, y);
84
+ this.dockManager.notifyOnChangeDialogPosition(this, x, y);
85
+ }
86
+
87
+ getPosition(): Point {
88
+ return new Point(this.position ? this.position.x : 0, this.position ? this.position.y : 0);
89
+ }
90
+
91
+ onFocus() {
92
+ if (this.dockManager.activePanel != this.panel)
93
+ this.dockManager.activePanel = this.panel;
94
+ }
95
+
96
+ onMouseDown(e: PointerEvent) {
97
+ if (e.button != 2)
98
+ this.bringToFront();
99
+ }
100
+
101
+ destroy() {
102
+ this.panel.lastDialogSize = {width: this.resizable.width, height: this.resizable.height};
103
+
104
+ if (this.focusHandler) {
105
+ this.focusHandler.cancel();
106
+ delete this.focusHandler;
107
+ }
108
+ if (this.mouseDownHandler) {
109
+ this.mouseDownHandler.cancel();
110
+ delete this.mouseDownHandler;
111
+ }
112
+ if (this.keyPressHandler) {
113
+ this.keyPressHandler.cancel();
114
+ delete this.keyPressHandler;
115
+ }
116
+ if (this.contextmenuHandler) {
117
+ this.contextmenuHandler.cancel();
118
+ delete this.contextmenuHandler;
119
+ }
120
+ Utils.removeNode(this.elementDialog);
121
+ this.draggable.removeDecorator();
122
+ Utils.removeNode(this.panel.elementPanel);
123
+ Utils.arrayRemove(this.dockManager.context.model.dialogs, this);
124
+ delete this.panel.floatingDialog;
125
+
126
+ if (this.grayoutParent)
127
+ this.grayoutParent.grayOut(false);
128
+ }
129
+
130
+ resize(width: number, height: number) {
131
+ this.resizable.resize(width, height);
132
+ }
133
+
134
+ setTitle(title: string) {
135
+ this.panel.setTitle(title);
136
+ }
137
+
138
+ setTitleIcon(iconName: string) {
139
+ this.panel.setTitleIcon(iconName);
140
+ }
141
+
142
+ bringToFront() {
143
+ this.panel.elementContentContainer.style.zIndex = <any> this.dockManager.zIndexDialogCounter++;
144
+ this.elementDialog.style.zIndex = <any> this.dockManager.zIndexDialogCounter++;
145
+ this.dockManager.activePanel = this.panel;
146
+ }
147
+
148
+ hide() {
149
+ this.elementDialog.style.zIndex = '0';
150
+ this.panel.elementContentContainer.style.zIndex = '';
151
+ this.elementDialog.style.display = 'none';
152
+ if (!this.isHidden) {
153
+ this.isHidden = true;
154
+ this.dockManager.notifyOnHideDialog(this);
155
+ }
156
+ if (this.grayoutParent)
157
+ this.grayoutParent.grayOut(false);
158
+ }
159
+
160
+ close() {
161
+ this.hide();
162
+ this.remove();
163
+ this.dockManager.notifyOnClosePanel(this.panel);
164
+ this.destroy();
165
+ }
166
+
167
+ remove() {
168
+ this.elementDialog.parentNode.removeChild(this.elementDialog);
169
+ }
170
+
171
+ show() {
172
+ this.panel.elementContentContainer.style.zIndex = <any> this.dockManager.zIndexDialogCounter++;
173
+ this.elementDialog.style.zIndex = <any> this.dockManager.zIndexDialogCounter++;
174
+ this.elementDialog.style.display = 'block';
175
+ if (this.isHidden) {
176
+ this.isHidden = false;
177
+ this.dockManager.notifyOnShowDialog(this);
178
+ }
179
+ }
180
+
181
+ static createContextMenuContentCallback = (dialog: Dialog, documentMangerNodes: DockNode[]): Node[] => {
182
+ if (!dialog.panel._hideCloseButton)
183
+ return [];
184
+
185
+
186
+ const result = [];
187
+
188
+ const btnCloseDialog = document.createElement('div');
189
+ btnCloseDialog.innerText = Localizer.getString('CloseDialog');
190
+ result.push(btnCloseDialog);
191
+
192
+ btnCloseDialog.onclick = () => {
193
+ dialog.panel.close();
194
+ dialog.closeContextMenu();
195
+ };
196
+
197
+ if (dialog.dockManager.config.enableBrowserWindows) {
198
+ const btnNewBrowserWindow = document.createElement('div');
199
+ btnNewBrowserWindow.innerText = Localizer.getString('NewBrowserWindow');
200
+ result.push(btnNewBrowserWindow);
201
+
202
+ btnNewBrowserWindow.onclick = () => {
203
+ dialog.panel.undockToBrowserDialog();
204
+ dialog.closeContextMenu();
205
+ };
206
+ }
207
+
208
+ return result;
209
+ };
210
+
211
+ oncontextMenuClicked(e: MouseEvent) {
212
+ e.preventDefault();
213
+
214
+ if (!this._ctxMenu && Dialog.createContextMenuContentCallback) {
215
+ const menuItems = Dialog.createContextMenuContentCallback(
216
+ this,
217
+ this.dockManager.context.model.documentManagerNode.children,
218
+ );
219
+
220
+ if (menuItems.length == 0)
221
+ return;
222
+
223
+
224
+ this._ctxMenu = document.createElement('div');
225
+ this._ctxMenu.className = 'dockspab-tab-handle-context-menu';
226
+ this._ctxMenu.append(...menuItems);
227
+ this._ctxMenu.style.left = e.pageX + 'px';
228
+ this._ctxMenu.style.top = e.pageY + 'px';
229
+ document.body.appendChild(this._ctxMenu);
230
+ this._windowsContextMenuCloseBound = this.windowsContextMenuClose.bind(this);
231
+ window.addEventListener('pointerup', this._windowsContextMenuCloseBound);
232
+ } else
233
+ this.closeContextMenu();
234
+ }
235
+
236
+ closeContextMenu() {
237
+ if (this._ctxMenu) {
238
+ document.body.removeChild(this._ctxMenu);
239
+ delete this._ctxMenu;
240
+ window.removeEventListener('pointerup', this._windowsContextMenuCloseBound);
241
+ }
242
+ }
243
+
244
+ windowsContextMenuClose(e: Event) {
245
+ const cp = e.composedPath();
246
+ for (const i in cp) {
247
+ const el = cp[i];
248
+ if (el == this._ctxMenu)
249
+ return;
250
+ }
251
+ this.closeContextMenu();
252
+ }
253
+ }
@@ -0,0 +1,15 @@
1
+ export class DockConfig {
2
+ public constructor() {
3
+ this.escClosesWindow = true;
4
+ this.escClosesDialog = true;
5
+ this.dialogRootElement = document.body;
6
+ this.moveOnlyWithinDockConatiner = false;
7
+ this.enableBrowserWindows = true;
8
+ }
9
+
10
+ escClosesWindow?: boolean;
11
+ escClosesDialog?: boolean;
12
+ dialogRootElement: HTMLElement;
13
+ moveOnlyWithinDockConatiner?: boolean;
14
+ enableBrowserWindows?: boolean;
15
+ }
@@ -0,0 +1,129 @@
1
+ import {DockManager} from './DockManager.js';
2
+ import {DockModel} from './DockModel.js';
3
+ import {DockNode} from './DockNode.js';
4
+ import {PanelContainer} from './PanelContainer.js';
5
+ import {HorizontalDockContainer} from './HorizontalDockContainer.js';
6
+ import {VerticalDockContainer} from './VerticalDockContainer.js';
7
+ import {DocumentManagerContainer} from './DocumentManagerContainer.js';
8
+ import {FillDockContainer} from './FillDockContainer.js';
9
+ import {Dialog} from './Dialog.js';
10
+ import {Utils} from './Utils.js';
11
+ import {IPanelInfo} from './interfaces/IPanelInfo.js';
12
+ import {INodeInfo} from './interfaces/INodeInfo.js';
13
+ import {IDockContainer} from './interfaces/IDockContainer.js';
14
+
15
+ /**
16
+ * Deserializes the dock layout hierarchy from JSON and creates a dock hierarhcy graph
17
+ */
18
+ export class DockGraphDeserializer {
19
+ dockManager: DockManager;
20
+ documentManagerNode: DockNode;
21
+
22
+ constructor(dockManager: DockManager) {
23
+ this.dockManager = dockManager;
24
+ }
25
+
26
+ async deserialize(_json: string): Promise<DockModel> {
27
+ const info = JSON.parse(_json);
28
+ const model = new DockModel();
29
+ model.rootNode = await this._buildGraph(info.graphInfo);
30
+ model.dialogs = await this._buildDialogs(info.dialogsInfo);
31
+ model.documentManagerNode = this.documentManagerNode;
32
+ return model;
33
+ }
34
+
35
+ async _buildGraph(nodeInfo: INodeInfo) {
36
+ const childrenInfo = nodeInfo.children;
37
+ const children: DockNode[] = [];
38
+ for (const childInfo of childrenInfo) {
39
+ const childNode = await this._buildGraph(childInfo);
40
+ if (childNode !== null)
41
+ children.push(childNode);
42
+ };
43
+
44
+ // Build the container owned by this node
45
+ const container = await this._createContainer(nodeInfo, children);
46
+ if (container === null)
47
+ return null;
48
+
49
+ // Build the node for this container and attach it's children
50
+ const node = new DockNode(container);
51
+ if (container instanceof DocumentManagerContainer)
52
+ this.documentManagerNode = node;
53
+ node.children = children;
54
+ for (const childNode of node.children.reverse())
55
+ childNode.parent = node;
56
+ ;
57
+ node.children.reverse();
58
+ // node.container.setActiveChild(node.container);
59
+ return node;
60
+ }
61
+
62
+ async _createContainer(nodeInfo: INodeInfo, children: DockNode[]) {
63
+ const containerType = nodeInfo.containerType;
64
+ const containerState = nodeInfo.state;
65
+ let container;
66
+
67
+ const childContainers: IDockContainer[] = [];
68
+ for (const childNode of children)
69
+ childContainers.push(childNode.container);
70
+
71
+
72
+ if (containerType === 'panel') {
73
+ container = await PanelContainer.loadFromState(containerState, this.dockManager);
74
+ if (!container?.prepareForDocking)
75
+ return null;
76
+ container.prepareForDocking();
77
+ Utils.removeNode(container.elementPanel);
78
+ } else if (containerType === 'horizontal')
79
+ container = new HorizontalDockContainer(this.dockManager, childContainers);
80
+ else if (containerType === 'vertical')
81
+ container = new VerticalDockContainer(this.dockManager, childContainers);
82
+ else if (containerType === 'fill') {
83
+ // Check if this is a document manager
84
+
85
+ // TODO: Layout engine compares the string 'fill', so cannot create another subclass type
86
+ // called document_manager and have to resort to this hack. use RTTI in layout engine
87
+ const typeDocumentManager = containerState.documentManager;
88
+ if (typeDocumentManager)
89
+ container = new DocumentManagerContainer(this.dockManager);
90
+ else
91
+ container = new FillDockContainer(this.dockManager);
92
+ } else
93
+ throw new Error('Cannot create dock container of unknown type: ' + containerType);
94
+
95
+ // Restore the state of the container
96
+ container.loadState(containerState);
97
+
98
+ // container.performLayout(childContainers);
99
+ return container;
100
+ }
101
+
102
+ async _buildDialogs(dialogsInfo: IPanelInfo[]) {
103
+ const dialogs: Dialog[] = [];
104
+ for (const dialogInfo of dialogsInfo) {
105
+ const containerType = dialogInfo.containerType;
106
+ const containerState = dialogInfo.state;
107
+ let container;
108
+ if (containerType === 'panel') {
109
+ container = await PanelContainer.loadFromState(containerState, this.dockManager);
110
+ if (container.prepareForDocking) {
111
+ Utils.removeNode(container.elementPanel);
112
+ container.isDialog = true;
113
+ const dialog = new Dialog(container, this.dockManager);
114
+ if (dialogInfo.position.x > document.body.clientWidth ||
115
+ dialogInfo.position.y > document.body.clientHeight - 70) {
116
+ dialogInfo.position.x = 20;
117
+ dialogInfo.position.y = 70;
118
+ }
119
+ dialog.setPosition(dialogInfo.position.x, dialogInfo.position.y);
120
+ dialog.isHidden = dialogInfo.isHidden;
121
+ if (dialog.isHidden)
122
+ dialog.hide();
123
+ dialogs.push(dialog);
124
+ }
125
+ }
126
+ }
127
+ return dialogs;
128
+ }
129
+ }
@@ -0,0 +1,53 @@
1
+ import {DockModel} from './DockModel.js';
2
+ import {DockNode} from './DockNode.js';
3
+ import {Dialog} from './Dialog.js';
4
+ import {IPanelInfo} from './interfaces/IPanelInfo.js';
5
+ import {INodeInfo} from './interfaces/INodeInfo.js';
6
+ import {IState} from './interfaces/IState.js';
7
+
8
+ /**
9
+ * The serializer saves / loads the state of the dock layout hierarchy
10
+ */
11
+ export class DockGraphSerializer {
12
+ serialize(model: DockModel) {
13
+ const graphInfo = this._buildGraphInfo(model.rootNode);
14
+ const dialogs = this._buildDialogsInfo(model.dialogs.sort((x, y)=><number><any>x.elementDialog.style.zIndex-<number><any>y.elementDialog.style.zIndex));
15
+ return JSON.stringify({graphInfo: graphInfo, dialogsInfo: dialogs});
16
+ }
17
+
18
+ _buildGraphInfo(node: DockNode): INodeInfo {
19
+ const nodeState: IState = {};
20
+ node.container.saveState(nodeState);
21
+
22
+ const childrenInfo: INodeInfo[] = [];
23
+ node.children.forEach((childNode) => {
24
+ childrenInfo.push(this._buildGraphInfo(childNode));
25
+ });
26
+
27
+ const nodeInfo: INodeInfo = {
28
+ containerType: node.container.containerType,
29
+ state: nodeState,
30
+ children: childrenInfo,
31
+ };
32
+ return nodeInfo;
33
+ }
34
+
35
+ _buildDialogsInfo(dialogs: Dialog[]): IPanelInfo[] {
36
+ const dialogsInfo: IPanelInfo[] = [];
37
+ dialogs.forEach((dialog) => {
38
+ const panelState: IState = {};
39
+ const panelContainer = dialog.panel;
40
+ panelContainer.saveState(panelState);
41
+
42
+ const panelInfo: IPanelInfo = {
43
+ containerType: panelContainer.containerType,
44
+ state: panelState,
45
+ position: dialog.getPosition(),
46
+ isHidden: dialog.isHidden,
47
+ };
48
+ dialogsInfo.push(panelInfo);
49
+ });
50
+
51
+ return dialogsInfo;
52
+ }
53
+ }