flexlayout-react 0.7.15 → 0.8.0

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 (252) hide show
  1. package/ChangeLog.txt +23 -0
  2. package/README.md +157 -330
  3. package/Screenshot_light.png +0 -0
  4. package/Screenshot_rounded.png +0 -0
  5. package/declarations/Attribute.d.ts +1 -1
  6. package/declarations/AttributeDefinitions.d.ts +1 -1
  7. package/declarations/DockLocation.d.ts +12 -12
  8. package/declarations/DropInfo.d.ts +12 -12
  9. package/declarations/I18nLabel.d.ts +12 -14
  10. package/declarations/Orientation.d.ts +7 -7
  11. package/declarations/PopupMenu.d.ts +1 -1
  12. package/declarations/Rect.d.ts +41 -28
  13. package/declarations/Types.d.ts +95 -79
  14. package/declarations/examples/demo/Utils.d.ts +4 -0
  15. package/declarations/index.d.ts +21 -22
  16. package/declarations/model/Action.d.ts +5 -5
  17. package/declarations/model/Actions.d.ts +127 -110
  18. package/declarations/model/BorderNode.d.ts +30 -34
  19. package/declarations/model/BorderSet.d.ts +3 -4
  20. package/declarations/model/ICloseType.d.ts +5 -5
  21. package/declarations/model/IDraggable.d.ts +2 -2
  22. package/declarations/model/IDropTarget.d.ts +2 -2
  23. package/declarations/model/IJsonModel.d.ts +811 -149
  24. package/declarations/model/LayoutWindow.d.ts +28 -0
  25. package/declarations/model/Model.d.ts +91 -86
  26. package/declarations/model/Node.d.ts +17 -17
  27. package/declarations/model/RowNode.d.ts +10 -11
  28. package/declarations/model/TabNode.d.ts +44 -37
  29. package/declarations/model/TabSetNode.d.ts +44 -41
  30. package/declarations/model/Utils.d.ts +1 -1
  31. package/declarations/model/WindowLayout.d.ts +24 -0
  32. package/declarations/src/Attribute.d.ts +1 -0
  33. package/declarations/src/AttributeDefinitions.d.ts +1 -0
  34. package/declarations/src/DockLocation.d.ts +12 -0
  35. package/declarations/src/DropInfo.d.ts +12 -0
  36. package/declarations/src/I18nLabel.d.ts +10 -0
  37. package/declarations/src/Orientation.d.ts +7 -0
  38. package/declarations/src/PopupMenu.d.ts +1 -0
  39. package/declarations/src/Rect.d.ts +31 -0
  40. package/declarations/src/Types.d.ts +92 -0
  41. package/declarations/src/index.d.ts +20 -0
  42. package/declarations/src/model/Action.d.ts +5 -0
  43. package/declarations/src/model/Actions.d.ts +110 -0
  44. package/declarations/src/model/BorderNode.d.ts +28 -0
  45. package/declarations/src/model/BorderSet.d.ts +3 -0
  46. package/declarations/src/model/ICloseType.d.ts +5 -0
  47. package/declarations/src/model/IDraggable.d.ts +2 -0
  48. package/declarations/src/model/IDropTarget.d.ts +2 -0
  49. package/declarations/src/model/IJsonModel.d.ts +153 -0
  50. package/declarations/src/model/Model.d.ts +98 -0
  51. package/declarations/src/model/Node.d.ts +16 -0
  52. package/declarations/src/model/RowNode.d.ts +11 -0
  53. package/declarations/src/model/TabNode.d.ts +36 -0
  54. package/declarations/src/model/TabSetNode.d.ts +37 -0
  55. package/declarations/src/model/Utils.d.ts +1 -0
  56. package/declarations/src/view/BorderButton.d.ts +1 -0
  57. package/declarations/src/view/BorderTab.d.ts +2 -0
  58. package/declarations/src/view/BorderTabSet.d.ts +1 -0
  59. package/declarations/src/view/DragContainer.d.ts +1 -0
  60. package/declarations/src/view/ErrorBoundary.d.ts +1 -0
  61. package/declarations/src/view/FloatingWindow.d.ts +1 -0
  62. package/declarations/src/view/Icons.d.ts +7 -0
  63. package/declarations/src/view/Layout.d.ts +113 -0
  64. package/declarations/src/view/Overlay.d.ts +1 -0
  65. package/declarations/src/view/PopupMenu.d.ts +1 -0
  66. package/declarations/src/view/Row.d.ts +1 -0
  67. package/declarations/src/view/Splitter.d.ts +1 -0
  68. package/declarations/src/view/Tab.d.ts +1 -0
  69. package/declarations/src/view/TabButton.d.ts +1 -0
  70. package/declarations/src/view/TabButtonStamp.d.ts +1 -0
  71. package/declarations/src/view/TabOverflowHook.d.ts +1 -0
  72. package/declarations/src/view/TabSet.d.ts +1 -0
  73. package/declarations/src/view/Utils.d.ts +4 -0
  74. package/declarations/view/BorderButton.d.ts +1 -1
  75. package/declarations/view/BorderTab.d.ts +2 -0
  76. package/declarations/view/BorderTabSet.d.ts +1 -1
  77. package/declarations/view/DragContainer.d.ts +1 -0
  78. package/declarations/view/ErrorBoundary.d.ts +1 -1
  79. package/declarations/view/ExtendedResizeObserver.d.ts +23 -0
  80. package/declarations/view/FloatingWindow.d.ts +1 -1
  81. package/declarations/view/Icons.d.ts +8 -7
  82. package/declarations/view/Layout.d.ts +139 -161
  83. package/declarations/view/Overlay.d.ts +1 -0
  84. package/declarations/view/PopoutWindow.d.ts +1 -0
  85. package/declarations/view/PopupMenu.d.ts +1 -0
  86. package/declarations/view/Row.d.ts +1 -0
  87. package/declarations/view/SizeTracker.d.ts +10 -0
  88. package/declarations/view/Splitter.d.ts +1 -1
  89. package/declarations/view/Tab.d.ts +1 -1
  90. package/declarations/view/TabButton.d.ts +1 -1
  91. package/declarations/view/TabButtonStamp.d.ts +1 -1
  92. package/declarations/view/TabOverflowHook.d.ts +1 -1
  93. package/declarations/view/TabSet.d.ts +1 -1
  94. package/declarations/view/Utils.d.ts +11 -1
  95. package/dist/bundles/demo.js +232052 -0
  96. package/dist/bundles/demo.js.map +1 -0
  97. package/dist/flexlayout.js +122 -92
  98. package/dist/flexlayout_min.js +1 -1
  99. package/lib/Attribute.js +42 -31
  100. package/lib/Attribute.js.map +1 -1
  101. package/lib/AttributeDefinitions.js +131 -108
  102. package/lib/AttributeDefinitions.js.map +1 -1
  103. package/lib/DockLocation.js +120 -124
  104. package/lib/DockLocation.js.map +1 -1
  105. package/lib/DropInfo.js +9 -13
  106. package/lib/DropInfo.js.map +1 -1
  107. package/lib/I18nLabel.js +13 -18
  108. package/lib/I18nLabel.js.map +1 -1
  109. package/lib/Orientation.js +22 -26
  110. package/lib/Orientation.js.map +1 -1
  111. package/lib/Rect.js +104 -72
  112. package/lib/Rect.js.map +1 -1
  113. package/lib/Types.js +96 -83
  114. package/lib/Types.js.map +1 -1
  115. package/lib/index.js +21 -38
  116. package/lib/index.js.map +1 -1
  117. package/lib/model/Action.js +6 -10
  118. package/lib/model/Action.js.map +1 -1
  119. package/lib/model/Actions.js +169 -155
  120. package/lib/model/Actions.js.map +1 -1
  121. package/lib/model/BorderNode.js +385 -406
  122. package/lib/model/BorderNode.js.map +1 -1
  123. package/lib/model/BorderSet.js +66 -121
  124. package/lib/model/BorderSet.js.map +1 -1
  125. package/lib/model/ICloseType.js +6 -9
  126. package/lib/model/ICloseType.js.map +1 -1
  127. package/lib/model/IDraggable.js +1 -2
  128. package/lib/model/IDropTarget.js +1 -2
  129. package/lib/model/IJsonModel.js +1 -2
  130. package/lib/model/LayoutWindow.js +83 -0
  131. package/lib/model/LayoutWindow.js.map +1 -0
  132. package/lib/model/Model.js +614 -496
  133. package/lib/model/Model.js.map +1 -1
  134. package/lib/model/Node.js +217 -228
  135. package/lib/model/Node.js.map +1 -1
  136. package/lib/model/RowNode.js +491 -504
  137. package/lib/model/RowNode.js.map +1 -1
  138. package/lib/model/TabNode.js +289 -184
  139. package/lib/model/TabNode.js.map +1 -1
  140. package/lib/model/TabSetNode.js +457 -446
  141. package/lib/model/TabSetNode.js.map +1 -1
  142. package/lib/model/Utils.js +47 -82
  143. package/lib/model/Utils.js.map +1 -1
  144. package/lib/view/BorderButton.js +124 -138
  145. package/lib/view/BorderButton.js.map +1 -1
  146. package/lib/view/BorderTab.js +47 -0
  147. package/lib/view/BorderTab.js.map +1 -0
  148. package/lib/view/BorderTabSet.js +134 -128
  149. package/lib/view/BorderTabSet.js.map +1 -1
  150. package/lib/view/DragContainer.js +16 -0
  151. package/lib/view/DragContainer.js.map +1 -0
  152. package/lib/view/ErrorBoundary.js +23 -27
  153. package/lib/view/ErrorBoundary.js.map +1 -1
  154. package/lib/view/Icons.js +40 -45
  155. package/lib/view/Icons.js.map +1 -1
  156. package/lib/view/Layout.js +918 -907
  157. package/lib/view/Layout.js.map +1 -1
  158. package/lib/view/Overlay.js +9 -0
  159. package/lib/view/Overlay.js.map +1 -0
  160. package/lib/view/PopoutWindow.js +129 -0
  161. package/lib/view/PopoutWindow.js.map +1 -0
  162. package/lib/view/PopupMenu.js +71 -0
  163. package/lib/view/PopupMenu.js.map +1 -0
  164. package/lib/view/Row.js +45 -0
  165. package/lib/view/Row.js.map +1 -0
  166. package/lib/view/SizeTracker.js +11 -0
  167. package/lib/view/SizeTracker.js.map +1 -0
  168. package/lib/view/Splitter.js +191 -147
  169. package/lib/view/Splitter.js.map +1 -1
  170. package/lib/view/Tab.js +86 -60
  171. package/lib/view/Tab.js.map +1 -1
  172. package/lib/view/TabButton.js +122 -135
  173. package/lib/view/TabButton.js.map +1 -1
  174. package/lib/view/TabButtonStamp.js +16 -21
  175. package/lib/view/TabButtonStamp.js.map +1 -1
  176. package/lib/view/TabOverflowHook.js +150 -149
  177. package/lib/view/TabOverflowHook.js.map +1 -1
  178. package/lib/view/TabSet.js +267 -234
  179. package/lib/view/TabSet.js.map +1 -1
  180. package/lib/view/Utils.js +126 -68
  181. package/lib/view/Utils.js.map +1 -1
  182. package/package.json +36 -30
  183. package/src/Attribute.ts +23 -0
  184. package/src/AttributeDefinitions.ts +38 -15
  185. package/src/DockLocation.ts +13 -13
  186. package/src/I18nLabel.ts +7 -9
  187. package/src/Rect.ts +53 -1
  188. package/src/Types.ts +16 -0
  189. package/src/index.ts +1 -2
  190. package/src/model/Actions.ts +49 -29
  191. package/src/model/BorderNode.ts +208 -214
  192. package/src/model/BorderSet.ts +42 -91
  193. package/src/model/IJsonModel.ts +883 -103
  194. package/src/model/LayoutWindow.ts +121 -0
  195. package/src/model/Model.ts +488 -366
  196. package/src/model/Node.ts +98 -111
  197. package/src/model/RowNode.ts +323 -319
  198. package/src/model/TabNode.ts +294 -110
  199. package/src/model/TabSetNode.ts +300 -242
  200. package/src/model/Utils.ts +6 -32
  201. package/src/view/BorderButton.tsx +32 -52
  202. package/src/view/BorderTab.tsx +70 -0
  203. package/src/view/BorderTabSet.tsx +64 -52
  204. package/src/view/DragContainer.tsx +32 -0
  205. package/src/view/Icons.tsx +6 -0
  206. package/src/view/Layout.tsx +1051 -1046
  207. package/src/view/Overlay.tsx +22 -0
  208. package/src/view/PopoutWindow.tsx +152 -0
  209. package/src/{PopupMenu.tsx → view/PopupMenu.tsx} +36 -31
  210. package/src/view/Row.tsx +68 -0
  211. package/src/view/SizeTracker.tsx +20 -0
  212. package/src/view/Splitter.tsx +167 -112
  213. package/src/view/Tab.tsx +76 -42
  214. package/src/view/TabButton.tsx +36 -55
  215. package/src/view/TabButtonStamp.tsx +5 -9
  216. package/src/view/TabOverflowHook.tsx +14 -9
  217. package/src/view/TabSet.tsx +217 -176
  218. package/src/view/Utils.tsx +119 -39
  219. package/style/_base.scss +140 -34
  220. package/style/dark.css +685 -580
  221. package/style/dark.css.map +1 -1
  222. package/style/dark.scss +3 -1
  223. package/style/gray.css +668 -563
  224. package/style/gray.css.map +1 -1
  225. package/style/gray.scss +2 -0
  226. package/style/light.css +669 -564
  227. package/style/light.css.map +1 -1
  228. package/style/light.scss +4 -2
  229. package/style/rounded.css +697 -0
  230. package/style/rounded.css.map +1 -0
  231. package/style/rounded.scss +194 -0
  232. package/style/underline.css +690 -585
  233. package/style/underline.css.map +1 -1
  234. package/style/underline.scss +2 -0
  235. package/cypress.config.ts +0 -16
  236. package/lib/DragDrop.js +0 -316
  237. package/lib/DragDrop.js.map +0 -1
  238. package/lib/PopupMenu.js +0 -68
  239. package/lib/PopupMenu.js.map +0 -1
  240. package/lib/model/SplitterNode.js +0 -72
  241. package/lib/model/SplitterNode.js.map +0 -1
  242. package/lib/view/FloatingWindow.js +0 -123
  243. package/lib/view/FloatingWindow.js.map +0 -1
  244. package/lib/view/FloatingWindowTab.js +0 -19
  245. package/lib/view/FloatingWindowTab.js.map +0 -1
  246. package/lib/view/TabFloating.js +0 -66
  247. package/lib/view/TabFloating.js.map +0 -1
  248. package/src/DragDrop.ts +0 -392
  249. package/src/model/SplitterNode.ts +0 -78
  250. package/src/view/FloatingWindow.tsx +0 -140
  251. package/src/view/FloatingWindowTab.tsx +0 -29
  252. package/src/view/TabFloating.tsx +0 -101
@@ -1,908 +1,919 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Layout = void 0;
4
- const React = require("react");
5
- const react_dom_1 = require("react-dom");
6
- const DockLocation_1 = require("../DockLocation");
7
- const DragDrop_1 = require("../DragDrop");
8
- const Actions_1 = require("../model/Actions");
9
- const BorderNode_1 = require("../model/BorderNode");
10
- const SplitterNode_1 = require("../model/SplitterNode");
11
- const TabNode_1 = require("../model/TabNode");
12
- const TabSetNode_1 = require("../model/TabSetNode");
13
- const Rect_1 = require("../Rect");
14
- const Types_1 = require("../Types");
15
- const BorderTabSet_1 = require("./BorderTabSet");
16
- const Splitter_1 = require("./Splitter");
17
- const Tab_1 = require("./Tab");
18
- const TabSet_1 = require("./TabSet");
19
- const FloatingWindow_1 = require("./FloatingWindow");
20
- const FloatingWindowTab_1 = require("./FloatingWindowTab");
21
- const TabFloating_1 = require("./TabFloating");
22
- const Orientation_1 = require("../Orientation");
23
- const Icons_1 = require("./Icons");
24
- const TabButtonStamp_1 = require("./TabButtonStamp");
25
- const defaultIcons = {
26
- close: React.createElement(Icons_1.CloseIcon, null),
27
- closeTabset: React.createElement(Icons_1.CloseIcon, null),
28
- popout: React.createElement(Icons_1.PopoutIcon, null),
29
- maximize: React.createElement(Icons_1.MaximizeIcon, null),
30
- restore: React.createElement(Icons_1.RestoreIcon, null),
31
- more: React.createElement(Icons_1.OverflowIcon, null),
32
- edgeArrow: React.createElement(Icons_1.EdgeIcon, null)
33
- };
34
- // Popout windows work in latest browsers based on webkit (Chrome, Opera, Safari, latest Edge) and Firefox. They do
35
- // not work on any version if IE or the original Edge browser
36
- // Assume any recent desktop browser not IE or original Edge will work
37
- /** @internal */
38
- // @ts-ignore
39
- const isIEorEdge = typeof window !== "undefined" && (window.document.documentMode || /Edge\//.test(window.navigator.userAgent));
40
- /** @internal */
41
- const isDesktop = typeof window !== "undefined" && window.matchMedia && window.matchMedia("(hover: hover) and (pointer: fine)").matches;
42
- /** @internal */
43
- const defaultSupportsPopout = isDesktop && !isIEorEdge;
44
- /**
45
- * A React component that hosts a multi-tabbed layout
46
- */
47
- class Layout extends React.Component {
48
- constructor(props) {
49
- super(props);
50
- /** @internal */
51
- this.firstMove = false;
52
- /** @internal */
53
- this.dragRectRendered = true;
54
- /** @internal */
55
- this.dragDivText = undefined;
56
- /** @internal */
57
- this.edgeRectLength = 100;
58
- /** @internal */
59
- this.edgeRectWidth = 10;
60
- /** @internal */
61
- this.onModelChange = (action) => {
62
- this.forceUpdate();
63
- if (this.props.onModelChange) {
64
- this.props.onModelChange(this.props.model, action);
65
- }
66
- };
67
- /** @internal */
68
- this.updateRect = (domRect) => {
69
- if (!domRect) {
70
- domRect = this.getDomRect();
71
- }
72
- if (!domRect) {
73
- // no dom rect available, return.
74
- return;
75
- }
76
- const rect = new Rect_1.Rect(0, 0, domRect.width, domRect.height);
77
- if (!rect.equals(this.state.rect) && rect.width !== 0 && rect.height !== 0) {
78
- this.setState({ rect });
79
- }
80
- };
81
- /** @internal */
82
- this.updateLayoutMetrics = () => {
83
- if (this.findHeaderBarSizeRef.current) {
84
- const headerBarSize = this.findHeaderBarSizeRef.current.getBoundingClientRect().height;
85
- if (headerBarSize !== this.state.calculatedHeaderBarSize) {
86
- this.setState({ calculatedHeaderBarSize: headerBarSize });
87
- }
88
- }
89
- if (this.findTabBarSizeRef.current) {
90
- const tabBarSize = this.findTabBarSizeRef.current.getBoundingClientRect().height;
91
- if (tabBarSize !== this.state.calculatedTabBarSize) {
92
- this.setState({ calculatedTabBarSize: tabBarSize });
93
- }
94
- }
95
- if (this.findBorderBarSizeRef.current) {
96
- const borderBarSize = this.findBorderBarSizeRef.current.getBoundingClientRect().height;
97
- if (borderBarSize !== this.state.calculatedBorderBarSize) {
98
- this.setState({ calculatedBorderBarSize: borderBarSize });
99
- }
100
- }
101
- };
102
- /** @internal */
103
- this.getClassName = (defaultClassName) => {
104
- if (this.props.classNameMapper === undefined) {
105
- return defaultClassName;
106
- }
107
- else {
108
- return this.props.classNameMapper(defaultClassName);
109
- }
110
- };
111
- /** @internal */
112
- this.onCloseWindow = (id) => {
113
- this.doAction(Actions_1.Actions.unFloatTab(id));
114
- try {
115
- this.props.model.getNodeById(id)._setWindow(undefined);
116
- }
117
- catch (e) {
118
- // catch incase it was a model change
119
- }
120
- };
121
- /** @internal */
122
- this.onSetWindow = (id, window) => {
123
- this.props.model.getNodeById(id)._setWindow(window);
124
- };
125
- /** @internal */
126
- this.onCancelAdd = () => {
127
- var _a, _b;
128
- const rootdiv = this.selfRef.current;
129
- if (rootdiv && this.dragDiv) {
130
- rootdiv.removeChild(this.dragDiv);
131
- }
132
- this.dragDiv = undefined;
133
- this.hidePortal();
134
- if (this.fnNewNodeDropped != null) {
135
- this.fnNewNodeDropped();
136
- this.fnNewNodeDropped = undefined;
137
- }
138
- try {
139
- (_b = (_a = this.customDrop) === null || _a === void 0 ? void 0 : _a.invalidated) === null || _b === void 0 ? void 0 : _b.call(_a);
140
- }
141
- catch (e) {
142
- console.error(e);
143
- }
144
- DragDrop_1.DragDrop.instance.hideGlass();
145
- this.newTabJson = undefined;
146
- this.customDrop = undefined;
147
- };
148
- /** @internal */
149
- this.onCancelDrag = (wasDragging) => {
150
- var _a, _b;
151
- if (wasDragging) {
152
- const rootdiv = this.selfRef.current;
153
- const outlineDiv = this.outlineDiv;
154
- if (rootdiv && outlineDiv) {
155
- try {
156
- rootdiv.removeChild(outlineDiv);
157
- }
158
- catch (e) { }
159
- }
160
- const dragDiv = this.dragDiv;
161
- if (rootdiv && dragDiv) {
162
- try {
163
- rootdiv.removeChild(dragDiv);
164
- }
165
- catch (e) { }
166
- }
167
- this.dragDiv = undefined;
168
- this.hidePortal();
169
- this.setState({ showEdges: false });
170
- if (this.fnNewNodeDropped != null) {
171
- this.fnNewNodeDropped();
172
- this.fnNewNodeDropped = undefined;
173
- }
174
- try {
175
- (_b = (_a = this.customDrop) === null || _a === void 0 ? void 0 : _a.invalidated) === null || _b === void 0 ? void 0 : _b.call(_a);
176
- }
177
- catch (e) {
178
- console.error(e);
179
- }
180
- DragDrop_1.DragDrop.instance.hideGlass();
181
- this.newTabJson = undefined;
182
- this.customDrop = undefined;
183
- }
184
- this.setState({ showHiddenBorder: DockLocation_1.DockLocation.CENTER });
185
- };
186
- /** @internal */
187
- this.onDragDivMouseDown = (event) => {
188
- event.preventDefault();
189
- this.dragStart(event, this.dragDivText, TabNode_1.TabNode._fromJson(this.newTabJson, this.props.model, false), true, undefined, undefined);
190
- };
191
- /** @internal */
192
- this.dragStart = (event, dragDivText, node, allowDrag, onClick, onDoubleClick) => {
193
- var _a, _b;
194
- if (!allowDrag) {
195
- DragDrop_1.DragDrop.instance.startDrag(event, undefined, undefined, undefined, undefined, onClick, onDoubleClick, this.currentDocument, (_a = this.selfRef.current) !== null && _a !== void 0 ? _a : undefined);
196
- }
197
- else {
198
- this.dragNode = node;
199
- this.dragDivText = dragDivText;
200
- DragDrop_1.DragDrop.instance.startDrag(event, this.onDragStart, this.onDragMove, this.onDragEnd, this.onCancelDrag, onClick, onDoubleClick, this.currentDocument, (_b = this.selfRef.current) !== null && _b !== void 0 ? _b : undefined);
201
- }
202
- };
203
- /** @internal */
204
- this.dragRectRender = (text, node, json, onRendered) => {
205
- let content;
206
- if (text !== undefined) {
207
- content = React.createElement("div", { style: { whiteSpace: "pre" } }, text.replace("<br>", "\n"));
208
- }
209
- else {
210
- if (node && node instanceof TabNode_1.TabNode) {
211
- content = (React.createElement(TabButtonStamp_1.TabButtonStamp, { node: node, layout: this, iconFactory: this.props.iconFactory, titleFactory: this.props.titleFactory }));
212
- }
213
- }
214
- if (this.props.onRenderDragRect !== undefined) {
215
- const customContent = this.props.onRenderDragRect(content, node, json);
216
- if (customContent !== undefined) {
217
- content = customContent;
218
- }
219
- }
220
- // hide div until the render is complete
221
- this.dragRectRendered = false;
222
- const dragDiv = this.dragDiv;
223
- if (dragDiv) {
224
- dragDiv.style.visibility = "hidden";
225
- this.showPortal(React.createElement(DragRectRenderWrapper
226
- // wait for it to be rendered
227
- , {
228
- // wait for it to be rendered
229
- onRendered: () => {
230
- this.dragRectRendered = true;
231
- onRendered === null || onRendered === void 0 ? void 0 : onRendered();
232
- } }, content), dragDiv);
233
- }
234
- };
235
- /** @internal */
236
- this.showPortal = (control, element) => {
237
- const portal = (0, react_dom_1.createPortal)(control, element);
238
- this.setState({ portal });
239
- };
240
- /** @internal */
241
- this.hidePortal = () => {
242
- this.setState({ portal: undefined });
243
- };
244
- /** @internal */
245
- this.onDragStart = () => {
246
- var _a;
247
- this.dropInfo = undefined;
248
- this.customDrop = undefined;
249
- const rootdiv = this.selfRef.current;
250
- this.outlineDiv = this.currentDocument.createElement("div");
251
- this.outlineDiv.className = this.getClassName(Types_1.CLASSES.FLEXLAYOUT__OUTLINE_RECT);
252
- this.outlineDiv.style.visibility = "hidden";
253
- if (rootdiv) {
254
- rootdiv.appendChild(this.outlineDiv);
255
- }
256
- if (this.dragDiv == null) {
257
- this.dragDiv = this.currentDocument.createElement("div");
258
- this.dragDiv.className = this.getClassName(Types_1.CLASSES.FLEXLAYOUT__DRAG_RECT);
259
- this.dragDiv.setAttribute("data-layout-path", "/drag-rectangle");
260
- this.dragRectRender(this.dragDivText, this.dragNode, this.newTabJson);
261
- if (rootdiv) {
262
- rootdiv.appendChild(this.dragDiv);
263
- }
264
- }
265
- // add edge indicators
266
- if (this.props.model.getMaximizedTabset() === undefined) {
267
- this.setState({ showEdges: this.props.model.isEnableEdgeDock() });
268
- }
269
- if (this.dragNode && this.outlineDiv && this.dragNode instanceof TabNode_1.TabNode && this.dragNode.getTabRect() !== undefined) {
270
- (_a = this.dragNode.getTabRect()) === null || _a === void 0 ? void 0 : _a.positionElement(this.outlineDiv);
271
- }
272
- this.firstMove = true;
273
- return true;
274
- };
275
- /** @internal */
276
- this.onDragMove = (event) => {
277
- var _a, _b, _c, _d, _e, _f, _g;
278
- if (this.firstMove === false) {
279
- const speed = this.props.model._getAttribute("tabDragSpeed");
280
- if (this.outlineDiv) {
281
- this.outlineDiv.style.transition = `top ${speed}s, left ${speed}s, width ${speed}s, height ${speed}s`;
282
- }
283
- }
284
- this.firstMove = false;
285
- const clientRect = (_a = this.selfRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
286
- const pos = {
287
- x: event.clientX - ((_b = clientRect === null || clientRect === void 0 ? void 0 : clientRect.left) !== null && _b !== void 0 ? _b : 0),
288
- y: event.clientY - ((_c = clientRect === null || clientRect === void 0 ? void 0 : clientRect.top) !== null && _c !== void 0 ? _c : 0),
289
- };
290
- this.checkForBorderToShow(pos.x, pos.y);
291
- // keep it between left & right
292
- const dragRect = (_e = (_d = this.dragDiv) === null || _d === void 0 ? void 0 : _d.getBoundingClientRect()) !== null && _e !== void 0 ? _e : new DOMRect(0, 0, 100, 100);
293
- let newLeft = pos.x - dragRect.width / 2;
294
- if (newLeft + dragRect.width > ((_f = clientRect === null || clientRect === void 0 ? void 0 : clientRect.width) !== null && _f !== void 0 ? _f : 0)) {
295
- newLeft = ((_g = clientRect === null || clientRect === void 0 ? void 0 : clientRect.width) !== null && _g !== void 0 ? _g : 0) - dragRect.width;
296
- }
297
- newLeft = Math.max(0, newLeft);
298
- if (this.dragDiv) {
299
- this.dragDiv.style.left = newLeft + "px";
300
- this.dragDiv.style.top = pos.y + 5 + "px";
301
- if (this.dragRectRendered && this.dragDiv.style.visibility === "hidden") {
302
- // make visible once the drag rect has been rendered
303
- this.dragDiv.style.visibility = "visible";
304
- }
305
- }
306
- let dropInfo = this.props.model._findDropTargetNode(this.dragNode, pos.x, pos.y);
307
- if (dropInfo) {
308
- if (this.props.onTabDrag) {
309
- this.handleCustomTabDrag(dropInfo, pos, event);
310
- }
311
- else {
312
- this.dropInfo = dropInfo;
313
- if (this.outlineDiv) {
314
- this.outlineDiv.className = this.getClassName(dropInfo.className);
315
- dropInfo.rect.positionElement(this.outlineDiv);
316
- this.outlineDiv.style.visibility = "visible";
317
- }
318
- }
319
- }
320
- };
321
- /** @internal */
322
- this.onDragEnd = (event) => {
323
- const rootdiv = this.selfRef.current;
324
- if (rootdiv) {
325
- if (this.outlineDiv) {
326
- rootdiv.removeChild(this.outlineDiv);
327
- }
328
- if (this.dragDiv) {
329
- rootdiv.removeChild(this.dragDiv);
330
- }
331
- }
332
- this.dragDiv = undefined;
333
- this.hidePortal();
334
- this.setState({ showEdges: false });
335
- DragDrop_1.DragDrop.instance.hideGlass();
336
- if (this.dropInfo) {
337
- if (this.customDrop) {
338
- this.newTabJson = undefined;
339
- try {
340
- const { callback, dragging, over, x, y, location } = this.customDrop;
341
- callback(dragging, over, x, y, location);
342
- if (this.fnNewNodeDropped != null) {
343
- this.fnNewNodeDropped();
344
- this.fnNewNodeDropped = undefined;
345
- }
346
- }
347
- catch (e) {
348
- console.error(e);
349
- }
350
- }
351
- else if (this.newTabJson !== undefined) {
352
- const newNode = this.doAction(Actions_1.Actions.addNode(this.newTabJson, this.dropInfo.node.getId(), this.dropInfo.location, this.dropInfo.index));
353
- if (this.fnNewNodeDropped != null) {
354
- this.fnNewNodeDropped(newNode, event);
355
- this.fnNewNodeDropped = undefined;
356
- }
357
- this.newTabJson = undefined;
358
- }
359
- else if (this.dragNode !== undefined) {
360
- this.doAction(Actions_1.Actions.moveNode(this.dragNode.getId(), this.dropInfo.node.getId(), this.dropInfo.location, this.dropInfo.index));
361
- }
362
- }
363
- this.setState({ showHiddenBorder: DockLocation_1.DockLocation.CENTER });
364
- };
365
- this.props.model._setChangeListener(this.onModelChange);
366
- this.tabIds = [];
367
- this.selfRef = React.createRef();
368
- this.findHeaderBarSizeRef = React.createRef();
369
- this.findTabBarSizeRef = React.createRef();
370
- this.findBorderBarSizeRef = React.createRef();
371
- this.supportsPopout = props.supportsPopout !== undefined ? props.supportsPopout : defaultSupportsPopout;
372
- this.popoutURL = props.popoutURL ? props.popoutURL : "popout.html";
373
- this.icons = Object.assign(Object.assign({}, defaultIcons), props.icons);
374
- this.state = {
375
- rect: new Rect_1.Rect(0, 0, 0, 0),
376
- calculatedHeaderBarSize: 25,
377
- calculatedTabBarSize: 26,
378
- calculatedBorderBarSize: 30,
379
- editingTab: undefined,
380
- showHiddenBorder: DockLocation_1.DockLocation.CENTER,
381
- showEdges: false,
382
- };
383
- this.onDragEnter = this.onDragEnter.bind(this);
384
- }
385
- /** @internal */
386
- styleFont(style) {
387
- if (this.props.font) {
388
- if (this.selfRef.current) {
389
- if (this.props.font.size) {
390
- this.selfRef.current.style.setProperty("--font-size", this.props.font.size);
391
- }
392
- if (this.props.font.family) {
393
- this.selfRef.current.style.setProperty("--font-family", this.props.font.family);
394
- }
395
- }
396
- if (this.props.font.style) {
397
- style.fontStyle = this.props.font.style;
398
- }
399
- if (this.props.font.weight) {
400
- style.fontWeight = this.props.font.weight;
401
- }
402
- }
403
- return style;
404
- }
405
- /** @internal */
406
- doAction(action) {
407
- if (this.props.onAction !== undefined) {
408
- const outcome = this.props.onAction(action);
409
- if (outcome !== undefined) {
410
- return this.props.model.doAction(outcome);
411
- }
412
- return undefined;
413
- }
414
- else {
415
- return this.props.model.doAction(action);
416
- }
417
- }
418
- /** @internal */
419
- componentDidMount() {
420
- this.updateRect();
421
- this.updateLayoutMetrics();
422
- // need to re-render if size changes
423
- this.currentDocument = this.selfRef.current.ownerDocument;
424
- this.currentWindow = this.currentDocument.defaultView;
425
- this.resizeObserver = new ResizeObserver(entries => {
426
- this.updateRect(entries[0].contentRect);
427
- });
428
- const selfRefCurr = this.selfRef.current;
429
- if (selfRefCurr) {
430
- this.resizeObserver.observe(selfRefCurr);
431
- }
432
- }
433
- /** @internal */
434
- componentDidUpdate() {
435
- this.updateLayoutMetrics();
436
- if (this.props.model !== this.previousModel) {
437
- if (this.previousModel !== undefined) {
438
- this.previousModel._setChangeListener(undefined); // stop listening to old model
439
- }
440
- this.props.model._setChangeListener(this.onModelChange);
441
- this.previousModel = this.props.model;
442
- }
443
- // console.log("Layout time: " + this.layoutTime + "ms Render time: " + (Date.now() - this.start) + "ms");
444
- }
445
- /** @internal */
446
- getCurrentDocument() {
447
- return this.currentDocument;
448
- }
449
- /** @internal */
450
- getDomRect() {
451
- var _a;
452
- return (_a = this.selfRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
453
- }
454
- /** @internal */
455
- getRootDiv() {
456
- return this.selfRef.current;
457
- }
458
- /** @internal */
459
- isSupportsPopout() {
460
- return this.supportsPopout;
461
- }
462
- /** @internal */
463
- isRealtimeResize() {
464
- var _a;
465
- return (_a = this.props.realtimeResize) !== null && _a !== void 0 ? _a : false;
466
- }
467
- /** @internal */
468
- onTabDrag(...args) {
469
- var _a, _b;
470
- return (_b = (_a = this.props).onTabDrag) === null || _b === void 0 ? void 0 : _b.call(_a, ...args);
471
- }
472
- /** @internal */
473
- getPopoutURL() {
474
- return this.popoutURL;
475
- }
476
- /** @internal */
477
- componentWillUnmount() {
478
- var _a;
479
- const selfRefCurr = this.selfRef.current;
480
- if (selfRefCurr) {
481
- (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.unobserve(selfRefCurr);
482
- }
483
- }
484
- /** @internal */
485
- setEditingTab(tabNode) {
486
- this.setState({ editingTab: tabNode });
487
- }
488
- /** @internal */
489
- getEditingTab() {
490
- return this.state.editingTab;
491
- }
492
- /** @internal */
493
- render() {
494
- // first render will be used to find the size (via selfRef)
495
- if (!this.selfRef.current) {
496
- return (React.createElement("div", { ref: this.selfRef, className: this.getClassName(Types_1.CLASSES.FLEXLAYOUT__LAYOUT) }, this.metricsElements()));
497
- }
498
- this.props.model._setPointerFine(window && window.matchMedia && window.matchMedia("(pointer: fine)").matches);
499
- // this.start = Date.now();
500
- const borderComponents = [];
501
- const tabSetComponents = [];
502
- const floatingWindows = [];
503
- const tabComponents = {};
504
- const splitterComponents = [];
505
- const metrics = {
506
- headerBarSize: this.state.calculatedHeaderBarSize,
507
- tabBarSize: this.state.calculatedTabBarSize,
508
- borderBarSize: this.state.calculatedBorderBarSize
509
- };
510
- this.props.model._setShowHiddenBorder(this.state.showHiddenBorder);
511
- this.centerRect = this.props.model._layout(this.state.rect, metrics);
512
- this.renderBorder(this.props.model.getBorderSet(), borderComponents, tabComponents, floatingWindows, splitterComponents);
513
- this.renderChildren("", this.props.model.getRoot(), tabSetComponents, tabComponents, floatingWindows, splitterComponents);
514
- const nextTopIds = [];
515
- const nextTopIdsMap = {};
516
- // Keep any previous tabs in the same DOM order as before, removing any that have been deleted
517
- for (const t of this.tabIds) {
518
- if (tabComponents[t]) {
519
- nextTopIds.push(t);
520
- nextTopIdsMap[t] = t;
521
- }
522
- }
523
- this.tabIds = nextTopIds;
524
- // Add tabs that have been added to the DOM
525
- for (const t of Object.keys(tabComponents)) {
526
- if (!nextTopIdsMap[t]) {
527
- this.tabIds.push(t);
528
- }
529
- }
530
- const edges = [];
531
- const arrowIcon = this.icons.edgeArrow;
532
- if (this.state.showEdges) {
533
- const r = this.centerRect;
534
- const length = this.edgeRectLength;
535
- const width = this.edgeRectWidth;
536
- const offset = this.edgeRectLength / 2;
537
- const className = this.getClassName(Types_1.CLASSES.FLEXLAYOUT__EDGE_RECT);
538
- const radius = 50;
539
- edges.push(React.createElement("div", { key: "North", style: { top: r.y, left: r.x + r.width / 2 - offset, width: length, height: width, borderBottomLeftRadius: radius, borderBottomRightRadius: radius }, className: className + " " + this.getClassName(Types_1.CLASSES.FLEXLAYOUT__EDGE_RECT_TOP) },
540
- React.createElement("div", { style: { transform: "rotate(180deg)" } }, arrowIcon)));
541
- edges.push(React.createElement("div", { key: "West", style: { top: r.y + r.height / 2 - offset, left: r.x, width: width, height: length, borderTopRightRadius: radius, borderBottomRightRadius: radius }, className: className + " " + this.getClassName(Types_1.CLASSES.FLEXLAYOUT__EDGE_RECT_LEFT) },
542
- React.createElement("div", { style: { transform: "rotate(90deg)" } }, arrowIcon)));
543
- edges.push(React.createElement("div", { key: "South", style: { top: r.y + r.height - width, left: r.x + r.width / 2 - offset, width: length, height: width, borderTopLeftRadius: radius, borderTopRightRadius: radius }, className: className + " " + this.getClassName(Types_1.CLASSES.FLEXLAYOUT__EDGE_RECT_BOTTOM) },
544
- React.createElement("div", null, arrowIcon)));
545
- edges.push(React.createElement("div", { key: "East", style: { top: r.y + r.height / 2 - offset, left: r.x + r.width - width, width: width, height: length, borderTopLeftRadius: radius, borderBottomLeftRadius: radius }, className: className + " " + this.getClassName(Types_1.CLASSES.FLEXLAYOUT__EDGE_RECT_RIGHT) },
546
- React.createElement("div", { style: { transform: "rotate(-90deg)" } }, arrowIcon)));
547
- }
548
- // this.layoutTime = (Date.now() - this.start);
549
- return (React.createElement("div", { ref: this.selfRef, className: this.getClassName(Types_1.CLASSES.FLEXLAYOUT__LAYOUT), onDragEnter: this.props.onExternalDrag ? this.onDragEnter : undefined },
550
- tabSetComponents,
551
- this.tabIds.map((t) => {
552
- return tabComponents[t];
553
- }),
554
- borderComponents,
555
- splitterComponents,
556
- edges,
557
- floatingWindows,
558
- this.metricsElements(),
559
- this.state.portal));
560
- }
561
- /** @internal */
562
- metricsElements() {
563
- // used to measure the tab and border tab sizes
564
- const fontStyle = this.styleFont({ visibility: "hidden" });
565
- return (React.createElement(React.Fragment, null,
566
- React.createElement("div", { key: "findHeaderBarSize", ref: this.findHeaderBarSizeRef, style: fontStyle, className: this.getClassName(Types_1.CLASSES.FLEXLAYOUT__TABSET_HEADER_SIZER) }, "FindHeaderBarSize"),
567
- React.createElement("div", { key: "findTabBarSize", ref: this.findTabBarSizeRef, style: fontStyle, className: this.getClassName(Types_1.CLASSES.FLEXLAYOUT__TABSET_SIZER) }, "FindTabBarSize"),
568
- React.createElement("div", { key: "findBorderBarSize", ref: this.findBorderBarSizeRef, style: fontStyle, className: this.getClassName(Types_1.CLASSES.FLEXLAYOUT__BORDER_SIZER) }, "FindBorderBarSize")));
569
- }
570
- /** @internal */
571
- renderBorder(borderSet, borderComponents, tabComponents, floatingWindows, splitterComponents) {
572
- for (const border of borderSet.getBorders()) {
573
- const borderPath = `/border/${border.getLocation().getName()}`;
574
- if (border.isShowing()) {
575
- borderComponents.push(React.createElement(BorderTabSet_1.BorderTabSet, { key: `border_${border.getLocation().getName()}`, path: borderPath, border: border, layout: this, iconFactory: this.props.iconFactory, titleFactory: this.props.titleFactory, icons: this.icons }));
576
- const drawChildren = border._getDrawChildren();
577
- let i = 0;
578
- let tabCount = 0;
579
- for (const child of drawChildren) {
580
- if (child instanceof SplitterNode_1.SplitterNode) {
581
- let path = borderPath + "/s";
582
- splitterComponents.push(React.createElement(Splitter_1.Splitter, { key: child.getId(), layout: this, node: child, path: path }));
583
- }
584
- else if (child instanceof TabNode_1.TabNode) {
585
- let path = borderPath + "/t" + tabCount++;
586
- if (this.supportsPopout && child.isFloating()) {
587
- const rect = this._getScreenRect(child);
588
- const tabBorderWidth = child._getAttr("borderWidth");
589
- const tabBorderHeight = child._getAttr("borderHeight");
590
- if (rect) {
591
- if (tabBorderWidth !== -1 && border.getLocation().getOrientation() === Orientation_1.Orientation.HORZ) {
592
- rect.width = tabBorderWidth;
593
- }
594
- else if (tabBorderHeight !== -1 && border.getLocation().getOrientation() === Orientation_1.Orientation.VERT) {
595
- rect.height = tabBorderHeight;
596
- }
597
- }
598
- floatingWindows.push(React.createElement(FloatingWindow_1.FloatingWindow, { key: child.getId(), url: this.popoutURL, rect: rect, title: child.getName(), id: child.getId(), onSetWindow: this.onSetWindow, onCloseWindow: this.onCloseWindow },
599
- React.createElement(FloatingWindowTab_1.FloatingWindowTab, { layout: this, node: child, factory: this.props.factory })));
600
- tabComponents[child.getId()] = React.createElement(TabFloating_1.TabFloating, { key: child.getId(), layout: this, path: path, node: child, selected: i === border.getSelected() });
601
- }
602
- else {
603
- tabComponents[child.getId()] = React.createElement(Tab_1.Tab, { key: child.getId(), layout: this, path: path, node: child, selected: i === border.getSelected(), factory: this.props.factory });
604
- }
605
- }
606
- i++;
607
- }
608
- }
609
- }
610
- }
611
- /** @internal */
612
- renderChildren(path, node, tabSetComponents, tabComponents, floatingWindows, splitterComponents) {
613
- const drawChildren = node._getDrawChildren();
614
- let splitterCount = 0;
615
- let tabCount = 0;
616
- let rowCount = 0;
617
- for (const child of drawChildren) {
618
- if (child instanceof SplitterNode_1.SplitterNode) {
619
- const newPath = path + "/s" + (splitterCount++);
620
- splitterComponents.push(React.createElement(Splitter_1.Splitter, { key: child.getId(), layout: this, path: newPath, node: child }));
621
- }
622
- else if (child instanceof TabSetNode_1.TabSetNode) {
623
- const newPath = path + "/ts" + (rowCount++);
624
- tabSetComponents.push(React.createElement(TabSet_1.TabSet, { key: child.getId(), layout: this, path: newPath, node: child, iconFactory: this.props.iconFactory, titleFactory: this.props.titleFactory, icons: this.icons }));
625
- this.renderChildren(newPath, child, tabSetComponents, tabComponents, floatingWindows, splitterComponents);
626
- }
627
- else if (child instanceof TabNode_1.TabNode) {
628
- const newPath = path + "/t" + (tabCount++);
629
- const selectedTab = child.getParent().getChildren()[child.getParent().getSelected()];
630
- if (selectedTab === undefined) {
631
- // this should not happen!
632
- console.warn("undefined selectedTab should not happen");
633
- }
634
- if (this.supportsPopout && child.isFloating()) {
635
- const rect = this._getScreenRect(child);
636
- floatingWindows.push(React.createElement(FloatingWindow_1.FloatingWindow, { key: child.getId(), url: this.popoutURL, rect: rect, title: child.getName(), id: child.getId(), onSetWindow: this.onSetWindow, onCloseWindow: this.onCloseWindow },
637
- React.createElement(FloatingWindowTab_1.FloatingWindowTab, { layout: this, node: child, factory: this.props.factory })));
638
- tabComponents[child.getId()] = React.createElement(TabFloating_1.TabFloating, { key: child.getId(), layout: this, path: newPath, node: child, selected: child === selectedTab });
639
- }
640
- else {
641
- tabComponents[child.getId()] = React.createElement(Tab_1.Tab, { key: child.getId(), layout: this, path: newPath, node: child, selected: child === selectedTab, factory: this.props.factory });
642
- }
643
- }
644
- else {
645
- // is row
646
- const newPath = path + ((child.getOrientation() === Orientation_1.Orientation.HORZ) ? "/r" : "/c") + (rowCount++);
647
- this.renderChildren(newPath, child, tabSetComponents, tabComponents, floatingWindows, splitterComponents);
648
- }
649
- }
650
- }
651
- /** @internal */
652
- _getScreenRect(node) {
653
- var _a;
654
- const rect = node.getRect().clone();
655
- const bodyRect = (_a = this.selfRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
656
- if (!bodyRect) {
657
- return null;
658
- }
659
- const navHeight = Math.min(80, this.currentWindow.outerHeight - this.currentWindow.innerHeight);
660
- const navWidth = Math.min(80, this.currentWindow.outerWidth - this.currentWindow.innerWidth);
661
- rect.x = rect.x + bodyRect.x + this.currentWindow.screenX + navWidth;
662
- rect.y = rect.y + bodyRect.y + this.currentWindow.screenY + navHeight;
663
- return rect;
664
- }
665
- /**
666
- * Adds a new tab to the given tabset
667
- * @param tabsetId the id of the tabset where the new tab will be added
668
- * @param json the json for the new tab node
669
- * @returns the added tab node or undefined
670
- */
671
- addTabToTabSet(tabsetId, json) {
672
- const tabsetNode = this.props.model.getNodeById(tabsetId);
673
- if (tabsetNode !== undefined) {
674
- const node = this.doAction(Actions_1.Actions.addNode(json, tabsetId, DockLocation_1.DockLocation.CENTER, -1));
675
- return node;
676
- }
677
- return undefined;
678
- }
679
- /**
680
- * Adds a new tab to the active tabset (if there is one)
681
- * @param json the json for the new tab node
682
- * @returns the added tab node or undefined
683
- */
684
- addTabToActiveTabSet(json) {
685
- const tabsetNode = this.props.model.getActiveTabset();
686
- if (tabsetNode !== undefined) {
687
- const node = this.doAction(Actions_1.Actions.addNode(json, tabsetNode.getId(), DockLocation_1.DockLocation.CENTER, -1));
688
- return node;
689
- }
690
- return undefined;
691
- }
692
- /**
693
- * Adds a new tab by dragging a labeled panel to the drop location, dragging starts immediatelly
694
- * @param dragText the text to show on the drag panel
695
- * @param json the json for the new tab node
696
- * @param onDrop a callback to call when the drag is complete (node and event will be undefined if the drag was cancelled)
697
- */
698
- addTabWithDragAndDrop(dragText, json, onDrop) {
699
- this.fnNewNodeDropped = onDrop;
700
- this.newTabJson = json;
701
- this.dragStart(undefined, dragText, TabNode_1.TabNode._fromJson(json, this.props.model, false), true, undefined, undefined);
702
- }
703
- /**
704
- * Move a tab/tabset using drag and drop
705
- * @param node the tab or tabset to drag
706
- * @param dragText the text to show on the drag panel
707
- */
708
- moveTabWithDragAndDrop(node, dragText) {
709
- this.dragStart(undefined, dragText, node, true, undefined, undefined);
710
- }
711
- /**
712
- * Adds a new tab by dragging a labeled panel to the drop location, dragging starts when you
713
- * mouse down on the panel
714
- *
715
- * @param dragText the text to show on the drag panel
716
- * @param json the json for the new tab node
717
- * @param onDrop a callback to call when the drag is complete (node and event will be undefined if the drag was cancelled)
718
- */
719
- addTabWithDragAndDropIndirect(dragText, json, onDrop) {
720
- this.fnNewNodeDropped = onDrop;
721
- this.newTabJson = json;
722
- DragDrop_1.DragDrop.instance.addGlass(this.onCancelAdd);
723
- this.dragDivText = dragText;
724
- this.dragDiv = this.currentDocument.createElement("div");
725
- this.dragDiv.className = this.getClassName(Types_1.CLASSES.FLEXLAYOUT__DRAG_RECT);
726
- this.dragDiv.addEventListener("mousedown", this.onDragDivMouseDown);
727
- this.dragDiv.addEventListener("touchstart", this.onDragDivMouseDown, { passive: false });
728
- this.dragRectRender(this.dragDivText, undefined, this.newTabJson, () => {
729
- if (this.dragDiv) {
730
- // now it's been rendered into the dom it can be centered
731
- this.dragDiv.style.visibility = "visible";
732
- const domRect = this.dragDiv.getBoundingClientRect();
733
- const r = new Rect_1.Rect(0, 0, domRect === null || domRect === void 0 ? void 0 : domRect.width, domRect === null || domRect === void 0 ? void 0 : domRect.height);
734
- r.centerInRect(this.state.rect);
735
- this.dragDiv.setAttribute("data-layout-path", "/drag-rectangle");
736
- this.dragDiv.style.left = r.x + "px";
737
- this.dragDiv.style.top = r.y + "px";
738
- }
739
- });
740
- const rootdiv = this.selfRef.current;
741
- rootdiv.appendChild(this.dragDiv);
742
- }
743
- /** @internal */
744
- handleCustomTabDrag(dropInfo, pos, event) {
745
- var _a, _b, _c;
746
- let invalidated = (_a = this.customDrop) === null || _a === void 0 ? void 0 : _a.invalidated;
747
- const currentCallback = (_b = this.customDrop) === null || _b === void 0 ? void 0 : _b.callback;
748
- this.customDrop = undefined;
749
- const dragging = this.newTabJson || (this.dragNode instanceof TabNode_1.TabNode ? this.dragNode : undefined);
750
- if (dragging && (dropInfo.node instanceof TabSetNode_1.TabSetNode || dropInfo.node instanceof BorderNode_1.BorderNode) && dropInfo.index === -1) {
751
- const selected = dropInfo.node.getSelectedNode();
752
- const tabRect = selected === null || selected === void 0 ? void 0 : selected.getRect();
753
- if (selected && (tabRect === null || tabRect === void 0 ? void 0 : tabRect.contains(pos.x, pos.y))) {
754
- let customDrop = undefined;
755
- try {
756
- const dest = this.onTabDrag(dragging, selected, pos.x - tabRect.x, pos.y - tabRect.y, dropInfo.location, () => this.onDragMove(event));
757
- if (dest) {
758
- customDrop = {
759
- rect: new Rect_1.Rect(dest.x + tabRect.x, dest.y + tabRect.y, dest.width, dest.height),
760
- callback: dest.callback,
761
- invalidated: dest.invalidated,
762
- dragging: dragging,
763
- over: selected,
764
- x: pos.x - tabRect.x,
765
- y: pos.y - tabRect.y,
766
- location: dropInfo.location,
767
- cursor: dest.cursor
768
- };
769
- }
770
- }
771
- catch (e) {
772
- console.error(e);
773
- }
774
- if ((customDrop === null || customDrop === void 0 ? void 0 : customDrop.callback) === currentCallback) {
775
- invalidated = undefined;
776
- }
777
- this.customDrop = customDrop;
778
- }
779
- }
780
- this.dropInfo = dropInfo;
781
- if (this.outlineDiv) {
782
- this.outlineDiv.className = this.getClassName(this.customDrop ? Types_1.CLASSES.FLEXLAYOUT__OUTLINE_RECT : dropInfo.className);
783
- if (this.customDrop) {
784
- this.customDrop.rect.positionElement(this.outlineDiv);
785
- }
786
- else {
787
- dropInfo.rect.positionElement(this.outlineDiv);
788
- }
789
- }
790
- DragDrop_1.DragDrop.instance.setGlassCursorOverride((_c = this.customDrop) === null || _c === void 0 ? void 0 : _c.cursor);
791
- if (this.outlineDiv) {
792
- this.outlineDiv.style.visibility = "visible";
793
- }
794
- try {
795
- invalidated === null || invalidated === void 0 ? void 0 : invalidated();
796
- }
797
- catch (e) {
798
- console.error(e);
799
- }
800
- }
801
- /** @internal */
802
- onDragEnter(event) {
803
- // DragDrop keeps track of number of dragenters minus the number of
804
- // dragleaves. Only start a new drag if there isn't one already.
805
- if (DragDrop_1.DragDrop.instance.isDragging())
806
- return;
807
- const drag = this.props.onExternalDrag(event);
808
- if (drag) {
809
- // Mimic addTabWithDragAndDrop, but pass in DragEvent
810
- this.fnNewNodeDropped = drag.onDrop;
811
- this.newTabJson = drag.json;
812
- this.dragStart(event, drag.dragText, TabNode_1.TabNode._fromJson(drag.json, this.props.model, false), true, undefined, undefined);
813
- }
814
- }
815
- /** @internal */
816
- checkForBorderToShow(x, y) {
817
- const r = this.props.model._getOuterInnerRects().outer;
818
- const c = r.getCenter();
819
- const margin = this.edgeRectWidth;
820
- const offset = this.edgeRectLength / 2;
821
- let overEdge = false;
822
- if (this.props.model.isEnableEdgeDock() && this.state.showHiddenBorder === DockLocation_1.DockLocation.CENTER) {
823
- if ((y > c.y - offset && y < c.y + offset) ||
824
- (x > c.x - offset && x < c.x + offset)) {
825
- overEdge = true;
826
- }
827
- }
828
- let location = DockLocation_1.DockLocation.CENTER;
829
- if (!overEdge) {
830
- if (x <= r.x + margin) {
831
- location = DockLocation_1.DockLocation.LEFT;
832
- }
833
- else if (x >= r.getRight() - margin) {
834
- location = DockLocation_1.DockLocation.RIGHT;
835
- }
836
- else if (y <= r.y + margin) {
837
- location = DockLocation_1.DockLocation.TOP;
838
- }
839
- else if (y >= r.getBottom() - margin) {
840
- location = DockLocation_1.DockLocation.BOTTOM;
841
- }
842
- }
843
- if (location !== this.state.showHiddenBorder) {
844
- this.setState({ showHiddenBorder: location });
845
- }
846
- }
847
- /** @internal */
848
- maximize(tabsetNode) {
849
- this.doAction(Actions_1.Actions.maximizeToggle(tabsetNode.getId()));
850
- }
851
- /** @internal */
852
- customizeTab(tabNode, renderValues) {
853
- if (this.props.onRenderTab) {
854
- this.props.onRenderTab(tabNode, renderValues);
855
- }
856
- }
857
- /** @internal */
858
- customizeTabSet(tabSetNode, renderValues) {
859
- if (this.props.onRenderTabSet) {
860
- this.props.onRenderTabSet(tabSetNode, renderValues);
861
- }
862
- }
863
- /** @internal */
864
- i18nName(id, param) {
865
- let message;
866
- if (this.props.i18nMapper) {
867
- message = this.props.i18nMapper(id, param);
868
- }
869
- if (message === undefined) {
870
- message = id + (param === undefined ? "" : param);
871
- }
872
- return message;
873
- }
874
- /** @internal */
875
- getOnRenderFloatingTabPlaceholder() {
876
- return this.props.onRenderFloatingTabPlaceholder;
877
- }
878
- /** @internal */
879
- getShowOverflowMenu() {
880
- return this.props.onShowOverflowMenu;
881
- }
882
- /** @internal */
883
- getTabSetPlaceHolderCallback() {
884
- return this.props.onTabSetPlaceHolder;
885
- }
886
- /** @internal */
887
- showContextMenu(node, event) {
888
- if (this.props.onContextMenu) {
889
- this.props.onContextMenu(node, event);
890
- }
891
- }
892
- /** @internal */
893
- auxMouseClick(node, event) {
894
- if (this.props.onAuxMouseClick) {
895
- this.props.onAuxMouseClick(node, event);
896
- }
897
- }
898
- }
899
- exports.Layout = Layout;
900
- /** @internal */
901
- const DragRectRenderWrapper = (props) => {
902
- React.useEffect(() => {
903
- var _a;
904
- (_a = props.onRendered) === null || _a === void 0 ? void 0 : _a.call(props);
905
- }, [props]);
906
- return (React.createElement(React.Fragment, null, props.children));
907
- };
1
+ import * as React from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { createRoot } from "react-dom/client";
4
+ import { DockLocation } from "../DockLocation";
5
+ import { I18nLabel } from "../I18nLabel";
6
+ import { Orientation } from "../Orientation";
7
+ import { Rect } from "../Rect";
8
+ import { CLASSES } from "../Types";
9
+ import { Actions } from "../model/Actions";
10
+ import { BorderNode } from "../model/BorderNode";
11
+ import { Model } from "../model/Model";
12
+ import { TabNode } from "../model/TabNode";
13
+ import { TabSetNode } from "../model/TabSetNode";
14
+ import { BorderTab } from "./BorderTab";
15
+ import { BorderTabSet } from "./BorderTabSet";
16
+ import { DragContainer } from "./DragContainer";
17
+ import { ErrorBoundary } from "./ErrorBoundary";
18
+ import { PopoutWindow } from "./PopoutWindow";
19
+ import { AsterickIcon, CloseIcon, EdgeIcon, MaximizeIcon, OverflowIcon, PopoutIcon, RestoreIcon } from "./Icons";
20
+ import { Overlay } from "./Overlay";
21
+ import { Row } from "./Row";
22
+ import { Tab } from "./Tab";
23
+ import { copyInlineStyles, enablePointerOnIFrames, isDesktop, isSafari } from "./Utils";
24
+ import { TabButtonStamp } from "./TabButtonStamp";
25
+ import { SizeTracker } from "./SizeTracker";
26
+ /**
27
+ * A React component that hosts a multi-tabbed layout
28
+ */
29
+ export class Layout extends React.Component {
30
+ /** @internal */
31
+ constructor(props) {
32
+ super(props);
33
+ this.selfRef = React.createRef();
34
+ this.revision = 0;
35
+ }
36
+ /** re-render the layout */
37
+ redraw() {
38
+ this.selfRef.current.redraw("parent " + this.revision);
39
+ }
40
+ /**
41
+ * Adds a new tab to the given tabset
42
+ * @param tabsetId the id of the tabset where the new tab will be added
43
+ * @param json the json for the new tab node
44
+ * @returns the added tab node or undefined
45
+ */
46
+ addTabToTabSet(tabsetId, json) {
47
+ return this.selfRef.current.addTabToTabSet(tabsetId, json);
48
+ }
49
+ /**
50
+ * Adds a new tab by dragging an item to the drop location, must be called from within an HTML
51
+ * drag start handler. You can use the setDragComponent() method to set the drag image before calling this
52
+ * method.
53
+ * @param event the drag start event
54
+ * @param json the json for the new tab node
55
+ * @param onDrop a callback to call when the drag is complete
56
+ */
57
+ addTabWithDragAndDrop(event, json, onDrop) {
58
+ this.selfRef.current.addTabWithDragAndDrop(event, json, onDrop);
59
+ }
60
+ /**
61
+ * Move a tab/tabset using drag and drop, must be called from within an HTML
62
+ * drag start handler
63
+ * @param event the drag start event
64
+ * @param node the tab or tabset to drag
65
+ */
66
+ moveTabWithDragAndDrop(event, node) {
67
+ this.selfRef.current.moveTabWithDragAndDrop(event, node);
68
+ }
69
+ /**
70
+ * Adds a new tab to the active tabset (if there is one)
71
+ * @param json the json for the new tab node
72
+ * @returns the added tab node or undefined
73
+ */
74
+ addTabToActiveTabSet(json) {
75
+ return this.selfRef.current.addTabToActiveTabSet(json);
76
+ }
77
+ /**
78
+ * Sets the drag image from a react component for a drag event
79
+ * @param event the drag event
80
+ * @param component the react component to be used for the drag image
81
+ * @param x the x position of the drag cursor on the image
82
+ * @param y the x position of the drag cursor on the image
83
+ */
84
+ setDragComponent(event, component, x, y) {
85
+ this.selfRef.current.setDragComponent(event, component, x, y);
86
+ }
87
+ /** Get the root div element of the layout */
88
+ getRootDiv() {
89
+ return this.selfRef.current.getRootDiv();
90
+ }
91
+ /** @internal */
92
+ render() {
93
+ return (React.createElement(LayoutInternal, Object.assign({ ref: this.selfRef }, this.props, { renderRevision: this.revision++ })));
94
+ }
95
+ }
96
+ /** @internal */
97
+ export class LayoutInternal extends React.Component {
98
+ // private renderCount: any;
99
+ constructor(props) {
100
+ super(props);
101
+ this.moveableElementMap = new Map();
102
+ this.dragEnterCount = 0;
103
+ this.dragging = false;
104
+ this.updateLayoutMetrics = () => {
105
+ if (this.findBorderBarSizeRef.current) {
106
+ const borderBarSize = this.findBorderBarSizeRef.current.getBoundingClientRect().height;
107
+ if (borderBarSize !== this.state.calculatedBorderBarSize) {
108
+ this.setState({ calculatedBorderBarSize: borderBarSize });
109
+ }
110
+ }
111
+ };
112
+ this.onModelChange = (action) => {
113
+ this.redrawInternal("model change");
114
+ if (this.props.onModelChange) {
115
+ this.props.onModelChange(this.props.model, action);
116
+ }
117
+ };
118
+ this.updateRect = () => {
119
+ const rect = this.getDomRect();
120
+ if (!rect.equals(this.state.rect) && rect.width !== 0 && rect.height !== 0) {
121
+ // console.log("updateRect", rect.floor());
122
+ this.setState({ rect });
123
+ if (this.windowId !== Model.MAIN_WINDOW_ID) {
124
+ this.redrawInternal("rect updated");
125
+ }
126
+ }
127
+ };
128
+ this.getClassName = (defaultClassName) => {
129
+ if (this.props.classNameMapper === undefined) {
130
+ return defaultClassName;
131
+ }
132
+ else {
133
+ return this.props.classNameMapper(defaultClassName);
134
+ }
135
+ };
136
+ this.onCloseWindow = (windowLayout) => {
137
+ this.doAction(Actions.closeWindow(windowLayout.windowId));
138
+ };
139
+ this.onSetWindow = (windowLayout, window) => {
140
+ };
141
+ this.showControlInPortal = (control, element) => {
142
+ const portal = createPortal(control, element);
143
+ this.setState({ portal });
144
+ };
145
+ this.hideControlInPortal = () => {
146
+ this.setState({ portal: undefined });
147
+ };
148
+ this.getIcons = () => {
149
+ return this.icons;
150
+ };
151
+ this.setDragNode = (event, node) => {
152
+ LayoutInternal.dragState = new DragState(this.mainLayout, DragSource.Internal, node, undefined, undefined);
153
+ // Note: can only set (very) limited types on android! so cannot set json
154
+ // Note: must set text/plain for android to allow drag,
155
+ // so just set a simple message indicating its a flexlayout drag (this is not used anywhere else)
156
+ event.dataTransfer.setData('text/plain', "--flexlayout--");
157
+ event.dataTransfer.effectAllowed = "copyMove";
158
+ event.dataTransfer.dropEffect = "move";
159
+ this.dragEnterCount = 0;
160
+ if (node instanceof TabSetNode) {
161
+ let rendered = false;
162
+ let content = this.i18nName(I18nLabel.Move_Tabset);
163
+ if (node.getChildren().length > 0) {
164
+ content = this.i18nName(I18nLabel.Move_Tabs).replace("?", String(node.getChildren().length));
165
+ }
166
+ if (this.props.onRenderDragRect) {
167
+ const dragComponent = this.props.onRenderDragRect(content, node, undefined);
168
+ if (dragComponent) {
169
+ this.setDragComponent(event, dragComponent, 10, 10);
170
+ rendered = true;
171
+ }
172
+ }
173
+ if (!rendered) {
174
+ this.setDragComponent(event, content, 10, 10);
175
+ }
176
+ }
177
+ else {
178
+ const element = event.target;
179
+ const rect = element.getBoundingClientRect();
180
+ const offsetX = event.clientX - rect.left;
181
+ const offsetY = event.clientY - rect.top;
182
+ const parentNode = node === null || node === void 0 ? void 0 : node.getParent();
183
+ const isInVerticalBorder = parentNode instanceof BorderNode && parentNode.getOrientation() === Orientation.HORZ;
184
+ const x = isInVerticalBorder ? 10 : offsetX;
185
+ const y = isInVerticalBorder ? 10 : offsetY;
186
+ let rendered = false;
187
+ if (this.props.onRenderDragRect) {
188
+ const content = React.createElement(TabButtonStamp, { key: node.getId(), layout: this, node: node });
189
+ const dragComponent = this.props.onRenderDragRect(content, node, undefined);
190
+ if (dragComponent) {
191
+ this.setDragComponent(event, dragComponent, x, y);
192
+ rendered = true;
193
+ }
194
+ }
195
+ if (!rendered) {
196
+ if (isSafari()) { // safari doesnt render the offscreen tabstamps
197
+ this.setDragComponent(event, React.createElement(TabButtonStamp, { node: node, layout: this }), x, y);
198
+ }
199
+ else {
200
+ event.dataTransfer.setDragImage(node.getTabStamp(), x, y);
201
+ }
202
+ }
203
+ }
204
+ };
205
+ this.onDragEnterRaw = (event) => {
206
+ this.dragEnterCount++;
207
+ if (this.dragEnterCount === 1) {
208
+ this.onDragEnter(event);
209
+ }
210
+ };
211
+ this.onDragLeaveRaw = (event) => {
212
+ this.dragEnterCount--;
213
+ if (this.dragEnterCount === 0) {
214
+ this.onDragLeave(event);
215
+ }
216
+ };
217
+ this.onDragEnter = (event) => {
218
+ // console.log("onDragEnter", this.windowId, this.dragEnterCount);
219
+ var _a;
220
+ if (!LayoutInternal.dragState && this.props.onExternalDrag) { // not internal dragging
221
+ const externalDrag = this.props.onExternalDrag(event);
222
+ if (externalDrag) {
223
+ const tempNode = TabNode.fromJson(externalDrag.json, this.props.model, false);
224
+ LayoutInternal.dragState = new DragState(this.mainLayout, DragSource.External, tempNode, externalDrag.json, externalDrag.onDrop);
225
+ }
226
+ }
227
+ if (LayoutInternal.dragState) {
228
+ if (this.windowId !== Model.MAIN_WINDOW_ID && LayoutInternal.dragState.mainLayout === this.mainLayout) {
229
+ LayoutInternal.dragState.mainLayout.setDraggingOverWindow(true);
230
+ }
231
+ if (LayoutInternal.dragState.mainLayout !== this.mainLayout) {
232
+ return; // drag not by this layout or its popouts
233
+ }
234
+ event.preventDefault();
235
+ this.dropInfo = undefined;
236
+ const rootdiv = this.selfRef.current;
237
+ this.outlineDiv = this.currentDocument.createElement("div");
238
+ this.outlineDiv.className = this.getClassName(CLASSES.FLEXLAYOUT__OUTLINE_RECT);
239
+ this.outlineDiv.style.visibility = "hidden";
240
+ const speed = this.props.model.getAttribute("tabDragSpeed");
241
+ this.outlineDiv.style.transition = `top ${speed}s, left ${speed}s, width ${speed}s, height ${speed}s`;
242
+ rootdiv.appendChild(this.outlineDiv);
243
+ this.dragging = true;
244
+ this.showOverlay(true);
245
+ // add edge indicators
246
+ if (!this.isDraggingOverWindow && this.props.model.getMaximizedTabset(this.windowId) === undefined) {
247
+ this.setState({ showEdges: this.props.model.isEnableEdgeDock() });
248
+ }
249
+ const clientRect = (_a = this.selfRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
250
+ const r = new Rect(event.clientX - (clientRect.left), event.clientY - (clientRect.top), 1, 1);
251
+ r.positionElement(this.outlineDiv);
252
+ }
253
+ };
254
+ this.onDragOver = (event) => {
255
+ var _a, _b, _c;
256
+ if (this.dragging && !this.isDraggingOverWindow) {
257
+ // console.log("onDragOver");
258
+ event.preventDefault();
259
+ const clientRect = (_a = this.selfRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
260
+ const pos = {
261
+ x: event.clientX - ((_b = clientRect === null || clientRect === void 0 ? void 0 : clientRect.left) !== null && _b !== void 0 ? _b : 0),
262
+ y: event.clientY - ((_c = clientRect === null || clientRect === void 0 ? void 0 : clientRect.top) !== null && _c !== void 0 ? _c : 0),
263
+ };
264
+ this.checkForBorderToShow(pos.x, pos.y);
265
+ let dropInfo = this.props.model.findDropTargetNode(this.windowId, LayoutInternal.dragState.dragNode, pos.x, pos.y);
266
+ if (dropInfo) {
267
+ this.dropInfo = dropInfo;
268
+ if (this.outlineDiv) {
269
+ this.outlineDiv.className = this.getClassName(dropInfo.className);
270
+ dropInfo.rect.positionElement(this.outlineDiv);
271
+ this.outlineDiv.style.visibility = "visible";
272
+ }
273
+ }
274
+ }
275
+ };
276
+ this.onDragLeave = (event) => {
277
+ // console.log("onDragLeave", this.windowId, this.dragging);
278
+ if (this.dragging) {
279
+ if (this.windowId !== Model.MAIN_WINDOW_ID) {
280
+ LayoutInternal.dragState.mainLayout.setDraggingOverWindow(false);
281
+ }
282
+ this.clearDragLocal();
283
+ }
284
+ };
285
+ this.onDrop = (event) => {
286
+ // console.log("ondrop", this.windowId, this.dragging, Layout.dragState);
287
+ if (this.dragging) {
288
+ event.preventDefault();
289
+ const dragState = LayoutInternal.dragState;
290
+ if (this.dropInfo) {
291
+ if (dragState.dragJson !== undefined) {
292
+ const newNode = this.doAction(Actions.addNode(dragState.dragJson, this.dropInfo.node.getId(), this.dropInfo.location, this.dropInfo.index));
293
+ if (dragState.fnNewNodeDropped !== undefined) {
294
+ dragState.fnNewNodeDropped(newNode, event);
295
+ }
296
+ }
297
+ else if (dragState.dragNode !== undefined) {
298
+ this.doAction(Actions.moveNode(dragState.dragNode.getId(), this.dropInfo.node.getId(), this.dropInfo.location, this.dropInfo.index));
299
+ }
300
+ }
301
+ this.mainLayout.clearDragMain();
302
+ }
303
+ this.dragEnterCount = 0; // must set to zero here ref sublayouts
304
+ };
305
+ this.orderedIds = [];
306
+ this.selfRef = React.createRef();
307
+ this.moveablesRef = React.createRef();
308
+ this.mainRef = React.createRef();
309
+ this.findBorderBarSizeRef = React.createRef();
310
+ this.supportsPopout = props.supportsPopout !== undefined ? props.supportsPopout : defaultSupportsPopout;
311
+ this.popoutURL = props.popoutURL ? props.popoutURL : "popout.html";
312
+ this.icons = Object.assign(Object.assign({}, defaultIcons), props.icons);
313
+ this.windowId = props.windowId ? props.windowId : Model.MAIN_WINDOW_ID;
314
+ this.mainLayout = this.props.mainLayout ? this.props.mainLayout : this;
315
+ this.isDraggingOverWindow = false;
316
+ this.layoutWindow = this.props.model.getwindowsMap().get(this.windowId);
317
+ this.layoutWindow.layout = this;
318
+ this.popoutWindowName = this.props.popoutWindowName || "Popout Window";
319
+ // this.renderCount = 0;
320
+ this.state = {
321
+ rect: Rect.empty(),
322
+ editingTab: undefined,
323
+ showEdges: false,
324
+ showOverlay: false,
325
+ calculatedBorderBarSize: 29,
326
+ layoutRevision: 0,
327
+ forceRevision: 0,
328
+ showHiddenBorder: DockLocation.CENTER
329
+ };
330
+ this.isMainWindow = this.windowId === Model.MAIN_WINDOW_ID;
331
+ }
332
+ componentDidMount() {
333
+ this.updateRect();
334
+ this.currentDocument = this.selfRef.current.ownerDocument;
335
+ this.currentWindow = this.currentDocument.defaultView;
336
+ this.layoutWindow.window = this.currentWindow;
337
+ this.layoutWindow.toScreenRectFunction = (r) => this.getScreenRect(r);
338
+ this.resizeObserver = new ResizeObserver(entries => {
339
+ requestAnimationFrame(() => {
340
+ this.updateRect();
341
+ });
342
+ });
343
+ if (this.selfRef.current) {
344
+ this.resizeObserver.observe(this.selfRef.current);
345
+ }
346
+ if (this.isMainWindow) {
347
+ this.props.model.addChangeListener(this.onModelChange);
348
+ this.updateLayoutMetrics();
349
+ }
350
+ else {
351
+ // since resizeObserver doesn't always work as expected when observing element in another document
352
+ this.currentWindow.addEventListener("resize", () => {
353
+ this.updateRect();
354
+ });
355
+ const sourceElement = this.props.mainLayout.getRootDiv();
356
+ const targetElement = this.selfRef.current;
357
+ copyInlineStyles(sourceElement, targetElement);
358
+ this.styleObserver = new MutationObserver(() => {
359
+ const changed = copyInlineStyles(sourceElement, targetElement);
360
+ if (changed) {
361
+ this.redraw("mutation observer");
362
+ }
363
+ });
364
+ // Observe changes to the source element's style attribute
365
+ this.styleObserver.observe(sourceElement, { attributeFilter: ['style'] });
366
+ }
367
+ // allow tabs to overlay when hidden
368
+ document.addEventListener('visibilitychange', () => {
369
+ for (const [_, layoutWindow] of this.props.model.getwindowsMap()) {
370
+ const layout = layoutWindow.layout;
371
+ if (layout) {
372
+ this.redraw("visibility change");
373
+ }
374
+ }
375
+ });
376
+ }
377
+ componentDidUpdate() {
378
+ this.currentDocument = this.selfRef.current.ownerDocument;
379
+ this.currentWindow = this.currentDocument.defaultView;
380
+ if (this.isMainWindow) {
381
+ if (this.props.model !== this.previousModel) {
382
+ if (this.previousModel !== undefined) {
383
+ this.previousModel.removeChangeListener(this.onModelChange); // stop listening to old model
384
+ }
385
+ this.props.model.getwindowsMap().get(this.windowId).layout = this;
386
+ this.props.model.addChangeListener(this.onModelChange);
387
+ this.layoutWindow = this.props.model.getwindowsMap().get(this.windowId);
388
+ this.layoutWindow.layout = this;
389
+ this.layoutWindow.toScreenRectFunction = (r) => this.getScreenRect(r);
390
+ this.previousModel = this.props.model;
391
+ this.tidyMoveablesMap();
392
+ }
393
+ this.updateLayoutMetrics();
394
+ }
395
+ }
396
+ componentWillUnmount() {
397
+ var _a, _b;
398
+ if (this.selfRef.current) {
399
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.unobserve(this.selfRef.current);
400
+ }
401
+ (_b = this.styleObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
402
+ }
403
+ render() {
404
+ // console.log("render", this.windowId, this.state.revision, this.renderCount++);
405
+ // first render will be used to find the size (via selfRef)
406
+ if (!this.selfRef.current) {
407
+ return (React.createElement("div", { ref: this.selfRef, className: this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT) },
408
+ React.createElement("div", { ref: this.moveablesRef, key: "__moveables__", className: this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_MOVEABLES) }),
409
+ this.renderMetricsElements()));
410
+ }
411
+ const model = this.props.model;
412
+ model.getRoot(this.windowId).calcMinMaxSize();
413
+ model.getRoot(this.windowId).setPaths("");
414
+ model.getBorderSet().setPaths();
415
+ const inner = this.renderLayout();
416
+ const outer = this.renderBorders(inner);
417
+ const tabs = this.renderTabs();
418
+ const reorderedTabs = this.reorderComponents(tabs, this.orderedIds);
419
+ let floatingWindows = null;
420
+ let tabMoveables = null;
421
+ let tabStamps = null;
422
+ let metricElements = null;
423
+ if (this.isMainWindow) {
424
+ floatingWindows = this.renderWindows();
425
+ metricElements = this.renderMetricsElements();
426
+ tabMoveables = this.renderTabMoveables();
427
+ tabStamps = React.createElement("div", { key: "__tabStamps__", className: this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_TAB_STAMPS) }, this.renderTabStamps());
428
+ }
429
+ return (React.createElement("div", { ref: this.selfRef, className: this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT), onDragEnter: this.onDragEnterRaw, onDragLeave: this.onDragLeaveRaw, onDragOver: this.onDragOver, onDrop: this.onDrop },
430
+ React.createElement("div", { ref: this.moveablesRef, key: "__moveables__", className: this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_MOVEABLES) }),
431
+ metricElements,
432
+ React.createElement(Overlay, { key: "__overlay__", layout: this, show: this.state.showOverlay }),
433
+ outer,
434
+ reorderedTabs,
435
+ tabMoveables,
436
+ tabStamps,
437
+ this.state.portal,
438
+ floatingWindows));
439
+ }
440
+ renderBorders(inner) {
441
+ const classMain = this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_MAIN);
442
+ const borders = this.props.model.getBorderSet().getBorderMap();
443
+ if (this.isMainWindow && borders.size > 0) {
444
+ inner = (React.createElement("div", { className: classMain, ref: this.mainRef }, inner));
445
+ const borderSetComponents = new Map();
446
+ const borderSetContentComponents = new Map();
447
+ for (const [_, location] of DockLocation.values) {
448
+ const border = borders.get(location);
449
+ const showBorder = border && (!border.isAutoHide() ||
450
+ (border.isAutoHide() && (border.getChildren().length > 0 || this.state.showHiddenBorder === location)));
451
+ if (showBorder) {
452
+ borderSetComponents.set(location, React.createElement(BorderTabSet, { layout: this, border: border, size: this.state.calculatedBorderBarSize }));
453
+ borderSetContentComponents.set(location, React.createElement(BorderTab, { layout: this, border: border, show: border.getSelected() !== -1 }));
454
+ }
455
+ }
456
+ const classBorderOuter = this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_BORDER_CONTAINER);
457
+ const classBorderInner = this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_BORDER_CONTAINER_INNER);
458
+ if (this.props.model.getBorderSet().getLayoutHorizontal()) {
459
+ const innerWithBorderTabs = (React.createElement("div", { className: classBorderInner, style: { flexDirection: "column" } },
460
+ borderSetContentComponents.get(DockLocation.TOP),
461
+ React.createElement("div", { className: classBorderInner, style: { flexDirection: "row" } },
462
+ borderSetContentComponents.get(DockLocation.LEFT),
463
+ inner,
464
+ borderSetContentComponents.get(DockLocation.RIGHT)),
465
+ borderSetContentComponents.get(DockLocation.BOTTOM)));
466
+ return (React.createElement("div", { className: classBorderOuter, style: { flexDirection: "column" } },
467
+ borderSetComponents.get(DockLocation.TOP),
468
+ React.createElement("div", { className: classBorderInner, style: { flexDirection: "row" } },
469
+ borderSetComponents.get(DockLocation.LEFT),
470
+ innerWithBorderTabs,
471
+ borderSetComponents.get(DockLocation.RIGHT)),
472
+ borderSetComponents.get(DockLocation.BOTTOM)));
473
+ }
474
+ else {
475
+ const innerWithBorderTabs = (React.createElement("div", { className: classBorderInner, style: { flexDirection: "row" } },
476
+ borderSetContentComponents.get(DockLocation.LEFT),
477
+ React.createElement("div", { className: classBorderInner, style: { flexDirection: "column" } },
478
+ borderSetContentComponents.get(DockLocation.TOP),
479
+ inner,
480
+ borderSetContentComponents.get(DockLocation.BOTTOM)),
481
+ borderSetContentComponents.get(DockLocation.RIGHT)));
482
+ return (React.createElement("div", { className: classBorderOuter, style: { flexDirection: "row" } },
483
+ borderSetComponents.get(DockLocation.LEFT),
484
+ React.createElement("div", { className: classBorderInner, style: { flexDirection: "column" } },
485
+ borderSetComponents.get(DockLocation.TOP),
486
+ innerWithBorderTabs,
487
+ borderSetComponents.get(DockLocation.BOTTOM)),
488
+ borderSetComponents.get(DockLocation.RIGHT)));
489
+ }
490
+ }
491
+ else { // no borders
492
+ return (React.createElement("div", { className: classMain, ref: this.mainRef, style: { position: "absolute", top: 0, left: 0, bottom: 0, right: 0, display: "flex" } }, inner));
493
+ }
494
+ }
495
+ renderLayout() {
496
+ return (React.createElement(React.Fragment, null,
497
+ React.createElement(Row, { key: "__row__", layout: this, node: this.props.model.getRoot(this.windowId) }),
498
+ this.renderEdgeIndicators()));
499
+ }
500
+ renderEdgeIndicators() {
501
+ const edges = [];
502
+ const arrowIcon = this.icons.edgeArrow;
503
+ if (this.state.showEdges) {
504
+ const r = this.props.model.getRoot(this.windowId).getRect();
505
+ const length = edgeRectLength;
506
+ const width = edgeRectWidth;
507
+ const offset = edgeRectLength / 2;
508
+ const className = this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT);
509
+ const radius = 50;
510
+ edges.push(React.createElement("div", { key: "North", style: { top: 0, left: r.width / 2 - offset, width: length, height: width, borderBottomLeftRadius: radius, borderBottomRightRadius: radius }, className: className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_TOP) },
511
+ React.createElement("div", { style: { transform: "rotate(180deg)" } }, arrowIcon)));
512
+ edges.push(React.createElement("div", { key: "West", style: { top: r.height / 2 - offset, left: 0, width: width, height: length, borderTopRightRadius: radius, borderBottomRightRadius: radius }, className: className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_LEFT) },
513
+ React.createElement("div", { style: { transform: "rotate(90deg)" } }, arrowIcon)));
514
+ edges.push(React.createElement("div", { key: "South", style: { top: r.height - width, left: r.width / 2 - offset, width: length, height: width, borderTopLeftRadius: radius, borderTopRightRadius: radius }, className: className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_BOTTOM) },
515
+ React.createElement("div", null, arrowIcon)));
516
+ edges.push(React.createElement("div", { key: "East", style: { top: r.height / 2 - offset, left: r.width - width, width: width, height: length, borderTopLeftRadius: radius, borderBottomLeftRadius: radius }, className: className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_RIGHT) },
517
+ React.createElement("div", { style: { transform: "rotate(-90deg)" } }, arrowIcon)));
518
+ }
519
+ return edges;
520
+ }
521
+ renderWindows() {
522
+ const floatingWindows = [];
523
+ if (this.supportsPopout) {
524
+ const windows = this.props.model.getwindowsMap();
525
+ let i = 1;
526
+ for (const [windowId, layoutWindow] of windows) {
527
+ if (windowId !== Model.MAIN_WINDOW_ID) {
528
+ floatingWindows.push(React.createElement(PopoutWindow, { key: windowId, layout: this, title: this.popoutWindowName + " " + i, layoutWindow: layoutWindow, url: this.popoutURL + "?id=" + windowId, onSetWindow: this.onSetWindow, onCloseWindow: this.onCloseWindow },
529
+ React.createElement(LayoutInternal, Object.assign({}, this.props, { windowId: windowId, mainLayout: this }))));
530
+ i++;
531
+ }
532
+ }
533
+ }
534
+ return floatingWindows;
535
+ }
536
+ renderTabMoveables() {
537
+ const tabMoveables = [];
538
+ this.props.model.visitNodes((node) => {
539
+ if (node instanceof TabNode) {
540
+ const child = node;
541
+ const element = this.getMoveableElement(child.getId());
542
+ child.setMoveableElement(element);
543
+ const selected = child.isSelected();
544
+ const rect = child.getParent().getContentRect();
545
+ // only render first time if size >0
546
+ const renderTab = child.isRendered() ||
547
+ ((selected || !child.isEnableRenderOnDemand()) && (rect.width > 0 && rect.height > 0));
548
+ if (renderTab) {
549
+ // console.log("rendertab", child.getName(), this.props.renderRevision);
550
+ const key = child.getId() + (child.isEnableWindowReMount() ? child.getWindowId() : "");
551
+ tabMoveables.push(createPortal(React.createElement(SizeTracker, { rect: rect, selected: child.isSelected(), forceRevision: this.state.forceRevision, tabsRevision: this.props.renderRevision, key: key },
552
+ React.createElement(ErrorBoundary, { message: this.i18nName(I18nLabel.Error_rendering_component) }, this.props.factory(child))), element, key));
553
+ child.setRendered(renderTab);
554
+ }
555
+ }
556
+ });
557
+ return tabMoveables;
558
+ }
559
+ renderTabStamps() {
560
+ const tabStamps = [];
561
+ this.props.model.visitNodes((node) => {
562
+ if (node instanceof TabNode) {
563
+ const child = node;
564
+ // what the tab should look like when dragged (since images need to have been loaded before drag image can be taken)
565
+ tabStamps.push(React.createElement(DragContainer, { key: child.getId(), layout: this, node: child }));
566
+ }
567
+ });
568
+ return tabStamps;
569
+ }
570
+ renderTabs() {
571
+ const tabs = new Map();
572
+ this.props.model.visitWindowNodes(this.windowId, (node) => {
573
+ if (node instanceof TabNode) {
574
+ const child = node;
575
+ const selected = child.isSelected();
576
+ const path = child.getPath();
577
+ const renderTab = child.isRendered() || selected || !child.isEnableRenderOnDemand();
578
+ if (renderTab) {
579
+ // const rect = (child.getParent() as BorderNode | TabSetNode).getContentRect();
580
+ // const key = child.getId();
581
+ tabs.set(child.getId(), (
582
+ // <SizeTracker rect={rect} forceRevision={this.state.forceRevision} key={key}>
583
+ React.createElement(Tab, { key: child.getId(), layout: this, path: path, node: child, selected: selected })
584
+ // </SizeTracker>
585
+ ));
586
+ }
587
+ }
588
+ });
589
+ return tabs;
590
+ }
591
+ renderMetricsElements() {
592
+ return (React.createElement("div", { key: "findBorderBarSize", ref: this.findBorderBarSizeRef, className: this.getClassName(CLASSES.FLEXLAYOUT__BORDER_SIZER) }, "FindBorderBarSize"));
593
+ }
594
+ checkForBorderToShow(x, y) {
595
+ const r = this.getBoundingClientRect(this.mainRef.current);
596
+ const c = r.getCenter();
597
+ const margin = edgeRectWidth;
598
+ const offset = edgeRectLength / 2;
599
+ let overEdge = false;
600
+ if (this.props.model.isEnableEdgeDock() && this.state.showHiddenBorder === DockLocation.CENTER) {
601
+ if ((y > c.y - offset && y < c.y + offset) ||
602
+ (x > c.x - offset && x < c.x + offset)) {
603
+ overEdge = true;
604
+ }
605
+ }
606
+ let location = DockLocation.CENTER;
607
+ if (!overEdge) {
608
+ if (x <= r.x + margin) {
609
+ location = DockLocation.LEFT;
610
+ }
611
+ else if (x >= r.getRight() - margin) {
612
+ location = DockLocation.RIGHT;
613
+ }
614
+ else if (y <= r.y + margin) {
615
+ location = DockLocation.TOP;
616
+ }
617
+ else if (y >= r.getBottom() - margin) {
618
+ location = DockLocation.BOTTOM;
619
+ }
620
+ }
621
+ if (location !== this.state.showHiddenBorder) {
622
+ this.setState({ showHiddenBorder: location });
623
+ }
624
+ }
625
+ tidyMoveablesMap() {
626
+ // console.log("tidyMoveablesMap");
627
+ const tabs = new Map();
628
+ this.props.model.visitNodes((node, _) => {
629
+ if (node instanceof TabNode) {
630
+ tabs.set(node.getId(), node);
631
+ }
632
+ });
633
+ for (const [nodeId, element] of this.moveableElementMap) {
634
+ if (!tabs.has(nodeId)) {
635
+ // console.log("delete", nodeId);
636
+ element.remove(); // remove from dom
637
+ this.moveableElementMap.delete(nodeId); // remove map entry
638
+ }
639
+ }
640
+ }
641
+ reorderComponents(components, ids) {
642
+ const nextIds = [];
643
+ const nextIdsSet = new Set();
644
+ let reordered = [];
645
+ // Keep any previous tabs in the same DOM order as before, removing any that have been deleted
646
+ for (const id of ids) {
647
+ if (components.get(id)) {
648
+ nextIds.push(id);
649
+ nextIdsSet.add(id);
650
+ }
651
+ }
652
+ ids.splice(0, ids.length, ...nextIds);
653
+ // Add tabs that have been added to the DOM
654
+ for (const [id, _] of components) {
655
+ if (!nextIdsSet.has(id)) {
656
+ ids.push(id);
657
+ }
658
+ }
659
+ reordered = ids.map((id) => {
660
+ return components.get(id);
661
+ });
662
+ return reordered;
663
+ }
664
+ redraw(type) {
665
+ // console.log("redraw", this.windowId, type);
666
+ this.mainLayout.setState((state, props) => { return { forceRevision: state.forceRevision + 1 }; });
667
+ }
668
+ redrawInternal(type) {
669
+ // console.log("redrawInternal", this.windowId, type);
670
+ this.mainLayout.setState((state, props) => { return { layoutRevision: state.layoutRevision + 1 }; });
671
+ }
672
+ doAction(action) {
673
+ if (this.props.onAction !== undefined) {
674
+ const outcome = this.props.onAction(action);
675
+ if (outcome !== undefined) {
676
+ return this.props.model.doAction(outcome);
677
+ }
678
+ return undefined;
679
+ }
680
+ else {
681
+ return this.props.model.doAction(action);
682
+ }
683
+ }
684
+ getBoundingClientRect(div) {
685
+ const layoutRect = this.getDomRect();
686
+ if (layoutRect) {
687
+ return Rect.getBoundingClientRect(div).relativeTo(layoutRect);
688
+ }
689
+ return Rect.empty();
690
+ }
691
+ getMoveableContainer() {
692
+ return this.moveablesRef.current;
693
+ }
694
+ getMoveableElement(id) {
695
+ let moveableElement = this.moveableElementMap.get(id);
696
+ if (moveableElement === undefined) {
697
+ moveableElement = document.createElement("div");
698
+ this.moveablesRef.current.appendChild(moveableElement);
699
+ moveableElement.className = CLASSES.FLEXLAYOUT__TAB_MOVEABLE;
700
+ this.moveableElementMap.set(id, moveableElement);
701
+ }
702
+ return moveableElement;
703
+ }
704
+ getMainLayout() {
705
+ return this.mainLayout;
706
+ }
707
+ getCurrentDocument() {
708
+ return this.currentDocument;
709
+ }
710
+ getDomRect() {
711
+ if (this.selfRef.current) {
712
+ return Rect.fromDomRect(this.selfRef.current.getBoundingClientRect());
713
+ }
714
+ else {
715
+ return Rect.empty();
716
+ }
717
+ }
718
+ getWindowId() {
719
+ return this.windowId;
720
+ }
721
+ getRootDiv() {
722
+ return this.selfRef.current;
723
+ }
724
+ getMainElement() {
725
+ return this.mainRef.current;
726
+ }
727
+ getFactory() {
728
+ return this.props.factory;
729
+ }
730
+ isSupportsPopout() {
731
+ return this.supportsPopout;
732
+ }
733
+ isRealtimeResize() {
734
+ var _a;
735
+ return (_a = this.props.realtimeResize) !== null && _a !== void 0 ? _a : false;
736
+ }
737
+ getPopoutURL() {
738
+ return this.popoutURL;
739
+ }
740
+ setEditingTab(tabNode) {
741
+ this.setState({ editingTab: tabNode });
742
+ }
743
+ getEditingTab() {
744
+ return this.state.editingTab;
745
+ }
746
+ getModel() {
747
+ return this.props.model;
748
+ }
749
+ getScreenRect(inRect) {
750
+ const rect = inRect.clone();
751
+ const layoutRect = this.getDomRect();
752
+ // Note: outerHeight can be less than innerHeight when window is zoomed, so cannot use
753
+ // const navHeight = Math.min(65, this.currentWindow!.outerHeight - this.currentWindow!.innerHeight);
754
+ // const navWidth = Math.min(65, this.currentWindow!.outerWidth - this.currentWindow!.innerWidth);
755
+ const navHeight = 60;
756
+ const navWidth = 2;
757
+ // console.log(rect.y, this.currentWindow!.screenX,layoutRect.y);
758
+ rect.x = this.currentWindow.screenX + this.currentWindow.scrollX + navWidth / 2 + layoutRect.x + rect.x;
759
+ rect.y = this.currentWindow.screenY + this.currentWindow.scrollY + (navHeight - navWidth / 2) + layoutRect.y + rect.y;
760
+ rect.height += navHeight;
761
+ rect.width += navWidth;
762
+ return rect;
763
+ }
764
+ addTabToTabSet(tabsetId, json) {
765
+ const tabsetNode = this.props.model.getNodeById(tabsetId);
766
+ if (tabsetNode !== undefined) {
767
+ const node = this.doAction(Actions.addNode(json, tabsetId, DockLocation.CENTER, -1));
768
+ return node;
769
+ }
770
+ return undefined;
771
+ }
772
+ addTabToActiveTabSet(json) {
773
+ const tabsetNode = this.props.model.getActiveTabset(this.windowId);
774
+ if (tabsetNode !== undefined) {
775
+ const node = this.doAction(Actions.addNode(json, tabsetNode.getId(), DockLocation.CENTER, -1));
776
+ return node;
777
+ }
778
+ return undefined;
779
+ }
780
+ maximize(tabsetNode) {
781
+ this.doAction(Actions.maximizeToggle(tabsetNode.getId(), this.getWindowId()));
782
+ }
783
+ customizeTab(tabNode, renderValues) {
784
+ if (this.props.onRenderTab) {
785
+ this.props.onRenderTab(tabNode, renderValues);
786
+ }
787
+ }
788
+ customizeTabSet(tabSetNode, renderValues) {
789
+ if (this.props.onRenderTabSet) {
790
+ this.props.onRenderTabSet(tabSetNode, renderValues);
791
+ }
792
+ }
793
+ i18nName(id, param) {
794
+ let message;
795
+ if (this.props.i18nMapper) {
796
+ message = this.props.i18nMapper(id, param);
797
+ }
798
+ if (message === undefined) {
799
+ message = id + (param === undefined ? "" : param);
800
+ }
801
+ return message;
802
+ }
803
+ getShowOverflowMenu() {
804
+ return this.props.onShowOverflowMenu;
805
+ }
806
+ getTabSetPlaceHolderCallback() {
807
+ return this.props.onTabSetPlaceHolder;
808
+ }
809
+ showContextMenu(node, event) {
810
+ if (this.props.onContextMenu) {
811
+ this.props.onContextMenu(node, event);
812
+ }
813
+ }
814
+ auxMouseClick(node, event) {
815
+ if (this.props.onAuxMouseClick) {
816
+ this.props.onAuxMouseClick(node, event);
817
+ }
818
+ }
819
+ showOverlay(show) {
820
+ this.setState({ showOverlay: show });
821
+ enablePointerOnIFrames(!show, this.currentDocument);
822
+ }
823
+ // *************************** Start Drag Drop *************************************
824
+ addTabWithDragAndDrop(event, json, onDrop) {
825
+ const tempNode = TabNode.fromJson(json, this.props.model, false);
826
+ LayoutInternal.dragState = new DragState(this.mainLayout, DragSource.Add, tempNode, json, onDrop);
827
+ }
828
+ moveTabWithDragAndDrop(event, node) {
829
+ this.setDragNode(event, node);
830
+ }
831
+ setDragComponent(event, component, x, y) {
832
+ let dragElement = (React.createElement("div", { style: { position: "unset" }, className: this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT) + " " + this.getClassName(CLASSES.FLEXLAYOUT__DRAG_RECT) }, component));
833
+ const tempDiv = this.currentDocument.createElement('div');
834
+ tempDiv.setAttribute("data-layout-path", "/drag-rectangle");
835
+ tempDiv.style.position = "absolute";
836
+ tempDiv.style.left = "-10000px";
837
+ tempDiv.style.top = "-10000px";
838
+ this.currentDocument.body.appendChild(tempDiv);
839
+ createRoot(tempDiv).render(dragElement);
840
+ event.dataTransfer.setDragImage(tempDiv, x, y);
841
+ setTimeout(() => {
842
+ this.currentDocument.body.removeChild(tempDiv);
843
+ }, 0);
844
+ }
845
+ setDraggingOverWindow(overWindow) {
846
+ // console.log("setDraggingOverWindow", overWindow);
847
+ if (this.isDraggingOverWindow !== overWindow) {
848
+ if (this.outlineDiv) {
849
+ this.outlineDiv.style.visibility = overWindow ? "hidden" : "visible";
850
+ }
851
+ if (overWindow) {
852
+ this.setState({ showEdges: false });
853
+ }
854
+ else {
855
+ // add edge indicators
856
+ if (this.props.model.getMaximizedTabset(this.windowId) === undefined) {
857
+ this.setState({ showEdges: this.props.model.isEnableEdgeDock() });
858
+ }
859
+ }
860
+ this.isDraggingOverWindow = overWindow;
861
+ }
862
+ }
863
+ clearDragMain() {
864
+ // console.log("clear drag main");
865
+ LayoutInternal.dragState = undefined;
866
+ if (this.windowId === Model.MAIN_WINDOW_ID) {
867
+ this.isDraggingOverWindow = false;
868
+ }
869
+ for (const [, layoutWindow] of this.props.model.getwindowsMap()) {
870
+ // console.log(layoutWindow);
871
+ layoutWindow.layout.clearDragLocal();
872
+ }
873
+ }
874
+ clearDragLocal() {
875
+ // console.log("clear drag local", this.windowId);
876
+ this.setState({ showEdges: false });
877
+ this.showOverlay(false);
878
+ this.dragEnterCount = 0;
879
+ this.dragging = false;
880
+ if (this.outlineDiv) {
881
+ this.selfRef.current.removeChild(this.outlineDiv);
882
+ this.outlineDiv = undefined;
883
+ }
884
+ }
885
+ }
886
+ LayoutInternal.dragState = undefined;
887
+ const defaultIcons = {
888
+ close: React.createElement(CloseIcon, null),
889
+ closeTabset: React.createElement(CloseIcon, null),
890
+ popout: React.createElement(PopoutIcon, null),
891
+ maximize: React.createElement(MaximizeIcon, null),
892
+ restore: React.createElement(RestoreIcon, null),
893
+ more: React.createElement(OverflowIcon, null),
894
+ edgeArrow: React.createElement(EdgeIcon, null),
895
+ activeTabset: React.createElement(AsterickIcon, null)
896
+ };
897
+ var DragSource;
898
+ (function (DragSource) {
899
+ DragSource["Internal"] = "internal";
900
+ DragSource["External"] = "external";
901
+ DragSource["Add"] = "add";
902
+ })(DragSource || (DragSource = {}));
903
+ /** @internal */
904
+ const defaultSupportsPopout = isDesktop();
905
+ /** @internal */
906
+ const edgeRectLength = 100;
907
+ /** @internal */
908
+ const edgeRectWidth = 10;
909
+ // global layout drag state
910
+ class DragState {
911
+ constructor(mainLayout, dragSource, dragNode, dragJson, fnNewNodeDropped) {
912
+ this.mainLayout = mainLayout;
913
+ this.dragSource = dragSource;
914
+ this.dragNode = dragNode;
915
+ this.dragJson = dragJson;
916
+ this.fnNewNodeDropped = fnNewNodeDropped;
917
+ }
918
+ }
908
919
  //# sourceMappingURL=Layout.js.map