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
@@ -8,9 +8,8 @@ import { CLASSES } from "../Types";
8
8
  import { IDraggable } from "./IDraggable";
9
9
  import { IDropTarget } from "./IDropTarget";
10
10
  import { IJsonBorderNode } from "./IJsonModel";
11
- import { Model, ILayoutMetrics } from "./Model";
11
+ import { Model } from "./Model";
12
12
  import { Node } from "./Node";
13
- import { SplitterNode } from "./SplitterNode";
14
13
  import { TabNode } from "./TabNode";
15
14
  import { TabSetNode } from "./TabSetNode";
16
15
  import { adjustSelectedIndex } from "./Utils";
@@ -19,13 +18,13 @@ export class BorderNode extends Node implements IDropTarget {
19
18
  static readonly TYPE = "border";
20
19
 
21
20
  /** @internal */
22
- static _fromJson(json: any, model: Model) {
21
+ static fromJson(json: any, model: Model) {
23
22
  const location = DockLocation.getByName(json.location);
24
23
  const border = new BorderNode(location, json, model);
25
24
  if (json.children) {
26
- border._children = json.children.map((jsonChild: any) => {
27
- const child = TabNode._fromJson(jsonChild, model);
28
- child._setParent(border);
25
+ border.children = json.children.map((jsonChild: any) => {
26
+ const child = TabNode.fromJson(jsonChild, model);
27
+ child.setParent(border);
29
28
  return child;
30
29
  });
31
30
  }
@@ -33,110 +32,47 @@ export class BorderNode extends Node implements IDropTarget {
33
32
  return border;
34
33
  }
35
34
  /** @internal */
36
- private static _attributeDefinitions: AttributeDefinitions = BorderNode._createAttributeDefinitions();
35
+ private static attributeDefinitions: AttributeDefinitions = BorderNode.createAttributeDefinitions();
37
36
 
38
37
  /** @internal */
39
- private static _createAttributeDefinitions(): AttributeDefinitions {
40
- const attributeDefinitions = new AttributeDefinitions();
41
- attributeDefinitions.add("type", BorderNode.TYPE, true).setType(Attribute.STRING).setFixed();
42
-
43
- attributeDefinitions.add("selected", -1).setType(Attribute.NUMBER);
44
- attributeDefinitions.add("show", true).setType(Attribute.BOOLEAN);
45
- attributeDefinitions.add("config", undefined).setType("any");
46
-
47
- attributeDefinitions.addInherited("barSize", "borderBarSize").setType(Attribute.NUMBER);
48
- attributeDefinitions.addInherited("enableDrop", "borderEnableDrop").setType(Attribute.BOOLEAN);
49
- attributeDefinitions.addInherited("className", "borderClassName").setType(Attribute.STRING);
50
- attributeDefinitions.addInherited("autoSelectTabWhenOpen", "borderAutoSelectTabWhenOpen").setType(Attribute.BOOLEAN);
51
- attributeDefinitions.addInherited("autoSelectTabWhenClosed", "borderAutoSelectTabWhenClosed").setType(Attribute.BOOLEAN);
52
- attributeDefinitions.addInherited("size", "borderSize").setType(Attribute.NUMBER);
53
- attributeDefinitions.addInherited("minSize", "borderMinSize").setType(Attribute.NUMBER);
54
- attributeDefinitions.addInherited("enableAutoHide", "borderEnableAutoHide").setType(Attribute.BOOLEAN);
55
- return attributeDefinitions;
56
- }
57
-
58
- /** @internal */
59
- private _contentRect?: Rect;
38
+ private outerRect: Rect = Rect.empty();
60
39
  /** @internal */
61
- private _tabHeaderRect?: Rect;
40
+ private contentRect: Rect = Rect.empty();
62
41
  /** @internal */
63
- private _location: DockLocation;
42
+ private tabHeaderRect: Rect = Rect.empty();
64
43
  /** @internal */
65
- private _drawChildren: Node[];
66
- /** @internal */
67
- private _adjustedSize: number = 0;
68
- /** @internal */
69
- private _calculatedBorderBarSize: number = 0;
44
+ private location: DockLocation;
70
45
 
71
46
  /** @internal */
72
47
  constructor(location: DockLocation, json: any, model: Model) {
73
48
  super(model);
74
49
 
75
- this._location = location;
76
- this._drawChildren = [];
77
- this._attributes.id = `border_${location.getName()}`;
78
- BorderNode._attributeDefinitions.fromJson(json, this._attributes);
79
- model._addNode(this);
50
+ this.location = location;
51
+ this.attributes.id = `border_${location.getName()}`;
52
+ BorderNode.attributeDefinitions.fromJson(json, this.attributes);
53
+ model.addNode(this);
80
54
  }
81
55
 
82
56
  getLocation() {
83
- return this._location;
84
- }
85
-
86
- getTabHeaderRect() {
87
- return this._tabHeaderRect;
88
- }
89
-
90
- getRect() {
91
- return this._tabHeaderRect!;
92
- }
93
-
94
- getContentRect() {
95
- return this._contentRect;
96
- }
97
-
98
- isEnableDrop() {
99
- return this._getAttr("enableDrop") as boolean;
100
- }
101
-
102
- isAutoSelectTab(whenOpen?: boolean) {
103
- if (whenOpen == null) {
104
- whenOpen = this.getSelected() !== -1;
105
- }
106
- if (whenOpen) {
107
- return this._getAttr("autoSelectTabWhenOpen") as boolean;
108
- } else {
109
- return this._getAttr("autoSelectTabWhenClosed") as boolean;
110
- }
57
+ return this.location;
111
58
  }
112
59
 
113
60
  getClassName() {
114
- return this._getAttr("className") as string | undefined;
61
+ return this.getAttr("className") as string | undefined;
115
62
  }
116
63
 
117
- /** @internal */
118
- calcBorderBarSize(metrics: ILayoutMetrics) {
119
- const barSize = this._getAttr("barSize") as number;
120
- if (barSize !== 0) {
121
- // its defined
122
- this._calculatedBorderBarSize = barSize;
123
- } else {
124
- this._calculatedBorderBarSize = metrics.borderBarSize;
125
- }
126
- }
127
-
128
- getBorderBarSize() {
129
- return this._calculatedBorderBarSize;
64
+ isHorizontal() {
65
+ return this.location.orientation === Orientation.HORZ;
130
66
  }
131
67
 
132
68
  getSize() {
133
- const defaultSize = this._getAttr("size") as number;
69
+ const defaultSize = this.getAttr("size") as number;
134
70
  const selected = this.getSelected();
135
71
  if (selected === -1) {
136
72
  return defaultSize;
137
73
  } else {
138
- const tabNode = this._children[selected] as TabNode;
139
- const tabBorderSize = (this._location._orientation === Orientation.HORZ) ? tabNode._getAttr("borderWidth") : tabNode._getAttr("borderHeight");
74
+ const tabNode = this.children[selected] as TabNode;
75
+ const tabBorderSize = this.isHorizontal() ? tabNode.getAttr("borderWidth") : tabNode.getAttr("borderHeight");
140
76
  if (tabBorderSize === -1) {
141
77
  return defaultSize;
142
78
  } else {
@@ -146,22 +82,42 @@ export class BorderNode extends Node implements IDropTarget {
146
82
  }
147
83
 
148
84
  getMinSize() {
149
- return this._getAttr("minSize") as number;
85
+ const selectedNode = this.getSelectedNode();
86
+ let min = this.getAttr("minSize") as number;
87
+ if (selectedNode) {
88
+ const nodeMin = this.isHorizontal() ? selectedNode.getMinWidth() : selectedNode.getMinHeight();
89
+ min = Math.max(min, nodeMin);
90
+ }
91
+ return min;
92
+ }
93
+
94
+ getMaxSize() {
95
+ const selectedNode = this.getSelectedNode();
96
+ let max = this.getAttr("maxSize") as number;
97
+ if (selectedNode) {
98
+ const nodeMax = this.isHorizontal() ? selectedNode.getMaxWidth() : selectedNode.getMaxHeight();
99
+ max = Math.min(max, nodeMax);
100
+ }
101
+ return max;
150
102
  }
151
103
 
152
104
  getSelected(): number {
153
- return this._attributes.selected as number;
105
+ return this.attributes.selected as number;
106
+ }
107
+
108
+ isAutoHide() {
109
+ return this.getAttr("enableAutoHide") as boolean;
154
110
  }
155
111
 
156
- getSelectedNode(): Node | undefined {
112
+ getSelectedNode(): TabNode | undefined {
157
113
  if (this.getSelected() !== -1) {
158
- return this._children[this.getSelected()];
114
+ return this.children[this.getSelected()] as TabNode;
159
115
  }
160
116
  return undefined;
161
117
  }
162
118
 
163
119
  getOrientation() {
164
- return this._location.getOrientation();
120
+ return this.location.getOrientation();
165
121
  }
166
122
 
167
123
  /**
@@ -172,7 +128,7 @@ export class BorderNode extends Node implements IDropTarget {
172
128
  * FlexLayout.Actions.updateNodeAttributes(node.getId(), {config:myConfigObject}));
173
129
  */
174
130
  getConfig() {
175
- return this._attributes.config;
131
+ return this.attributes.config;
176
132
  }
177
133
 
178
134
  isMaximized() {
@@ -180,106 +136,102 @@ export class BorderNode extends Node implements IDropTarget {
180
136
  }
181
137
 
182
138
  isShowing() {
183
- const show = this._attributes.show as boolean;
184
- if (show) {
185
- if (this._model._getShowHiddenBorder() !== this._location && this.isAutoHide() && this._children.length === 0) {
186
- return false;
187
- }
188
- return true;
189
- } else {
190
- return false;
191
- }
192
- }
193
-
194
- isAutoHide() {
195
- return this._getAttr("enableAutoHide") as boolean;
139
+ return this.attributes.show as boolean;
196
140
  }
197
141
 
198
- /** @internal */
199
- _setSelected(index: number) {
200
- this._attributes.selected = index;
142
+ toJson(): IJsonBorderNode {
143
+ const json: any = {};
144
+ BorderNode.attributeDefinitions.toJson(json, this.attributes);
145
+ json.location = this.location.getName();
146
+ json.children = this.children.map((child) => (child as TabNode).toJson());
147
+ return json;
201
148
  }
202
149
 
203
150
  /** @internal */
204
- _setSize(pos: number) {
205
- const selected = this.getSelected();
206
- if (selected === -1) {
207
- this._attributes.size = pos;
151
+ isAutoSelectTab(whenOpen?: boolean) {
152
+ if (whenOpen == null) {
153
+ whenOpen = this.getSelected() !== -1;
154
+ }
155
+ if (whenOpen) {
156
+ return this.getAttr("autoSelectTabWhenOpen") as boolean;
208
157
  } else {
209
- const tabNode = this._children[selected] as TabNode;
210
- const tabBorderSize = (this._location._orientation === Orientation.HORZ) ? tabNode._getAttr("borderWidth") : tabNode._getAttr("borderHeight");
211
- if (tabBorderSize === -1) {
212
- this._attributes.size = pos;
213
- } else {
214
- if (this._location._orientation === Orientation.HORZ) {
215
- tabNode._setBorderWidth(pos);
216
- } else {
217
- tabNode._setBorderHeight(pos);
218
- }
219
- }
158
+ return this.getAttr("autoSelectTabWhenClosed") as boolean;
220
159
  }
221
160
  }
222
161
 
223
162
  /** @internal */
224
- _updateAttrs(json: any) {
225
- BorderNode._attributeDefinitions.update(json, this._attributes);
163
+ setSelected(index: number) {
164
+ this.attributes.selected = index;
226
165
  }
227
166
 
228
167
  /** @internal */
229
- _getDrawChildren() {
230
- return this._drawChildren;
168
+ getTabHeaderRect() {
169
+ return this.tabHeaderRect;
231
170
  }
232
171
 
233
172
  /** @internal */
234
- _setAdjustedSize(size: number) {
235
- this._adjustedSize = size;
173
+ setTabHeaderRect(r: Rect) {
174
+ this.tabHeaderRect = r;
236
175
  }
237
176
 
238
177
  /** @internal */
239
- _getAdjustedSize() {
240
- return this._adjustedSize;
178
+ getOuterRect() {
179
+ return this.outerRect;
241
180
  }
242
181
 
243
182
  /** @internal */
244
- _layoutBorderOuter(outer: Rect, metrics: ILayoutMetrics) {
245
- this.calcBorderBarSize(metrics);
246
- const split1 = this._location.split(outer, this.getBorderBarSize()); // split border outer
247
- this._tabHeaderRect = split1.start;
248
- return split1.end;
183
+ setOuterRect(r: Rect) {
184
+ this.outerRect = r;
249
185
  }
250
186
 
251
187
  /** @internal */
252
- _layoutBorderInner(inner: Rect, metrics: ILayoutMetrics) {
253
- this._drawChildren = [];
254
- const location = this._location;
188
+ getRect() {
189
+ return this.tabHeaderRect!;
190
+ }
255
191
 
256
- const split1 = location.split(inner, this._adjustedSize + this._model.getSplitterSize()); // split off tab contents
257
- const split2 = location.reflect().split(split1.start, this._model.getSplitterSize()); // split contents into content and splitter
192
+ /** @internal */
193
+ getContentRect() {
194
+ return this.contentRect;
195
+ }
258
196
 
259
- this._contentRect = split2.end;
197
+ /** @internal */
198
+ setContentRect(r: Rect) {
199
+ this.contentRect = r;
200
+ }
260
201
 
261
- for (let i = 0; i< this._children.length; i++) {
262
- const child = this._children[i];
263
- child._layout(this._contentRect!, metrics);
264
- child._setVisible(i === this.getSelected());
265
- this._drawChildren.push(child);
266
- }
202
+ /** @internal */
203
+ isEnableDrop() {
204
+ return this.getAttr("enableDrop") as boolean;
205
+ }
267
206
 
268
- if (this.getSelected() === -1) {
269
- return inner;
207
+ /** @internal */
208
+ setSize(pos: number) {
209
+ const selected = this.getSelected();
210
+ if (selected === -1) {
211
+ this.attributes.size = pos;
270
212
  } else {
271
- const newSplitter = new SplitterNode(this._model);
272
- newSplitter._setParent(this);
273
- newSplitter._setRect(split2.start);
274
- this._drawChildren.push(newSplitter);
275
-
276
- return split1.end;
213
+ const tabNode = this.children[selected] as TabNode;
214
+ const tabBorderSize = this.isHorizontal() ? tabNode.getAttr("borderWidth") : tabNode.getAttr("borderHeight");
215
+ if (tabBorderSize === -1) {
216
+ this.attributes.size = pos;
217
+ } else {
218
+ if (this.isHorizontal()) {
219
+ tabNode.setBorderWidth(pos);
220
+ } else {
221
+ tabNode.setBorderHeight(pos);
222
+ }
223
+ }
277
224
  }
278
225
  }
279
226
 
280
227
  /** @internal */
281
- _remove(node: TabNode) {
282
- const removedIndex = this._removeChild(node);
228
+ updateAttrs(json: any) {
229
+ BorderNode.attributeDefinitions.update(json, this.attributes);
230
+ }
231
+
232
+ /** @internal */
233
+ remove(node: TabNode) {
234
+ const removedIndex = this.removeChild(node);
283
235
  if (this.getSelected() !== -1) {
284
236
  adjustSelectedIndex(this, removedIndex);
285
237
  }
@@ -287,26 +239,26 @@ export class BorderNode extends Node implements IDropTarget {
287
239
 
288
240
  /** @internal */
289
241
  canDrop(dragNode: Node & IDraggable, x: number, y: number): DropInfo | undefined {
290
- if (dragNode.getType() !== TabNode.TYPE) {
242
+ if (!(dragNode instanceof TabNode)) {
291
243
  return undefined;
292
244
  }
293
245
 
294
246
  let dropInfo;
295
247
  const dockLocation = DockLocation.CENTER;
296
248
 
297
- if (this._tabHeaderRect!.contains(x, y)) {
298
- if (this._location._orientation === Orientation.VERT) {
299
- if (this._children.length > 0) {
300
- let child = this._children[0];
249
+ if (this.tabHeaderRect!.contains(x, y)) {
250
+ if (this.location.orientation === Orientation.VERT) {
251
+ if (this.children.length > 0) {
252
+ let child = this.children[0];
301
253
  let childRect = (child as TabNode).getTabRect()!;
302
254
  const childY = childRect.y;
303
255
 
304
256
  const childHeight = childRect.height;
305
257
 
306
- let pos = this._tabHeaderRect!.x;
258
+ let pos = this.tabHeaderRect!.x;
307
259
  let childCenter = 0;
308
- for (let i = 0; i < this._children.length; i++) {
309
- child = this._children[i];
260
+ for (let i = 0; i < this.children.length; i++) {
261
+ child = this.children[i];
310
262
  childRect = (child as TabNode).getTabRect()!;
311
263
  childCenter = childRect.x + childRect.width / 2;
312
264
  if (x >= pos && x < childCenter) {
@@ -318,23 +270,23 @@ export class BorderNode extends Node implements IDropTarget {
318
270
  }
319
271
  if (dropInfo == null) {
320
272
  const outlineRect = new Rect(childRect.getRight() - 2, childY, 3, childHeight);
321
- dropInfo = new DropInfo(this, outlineRect, dockLocation, this._children.length, CLASSES.FLEXLAYOUT__OUTLINE_RECT);
273
+ dropInfo = new DropInfo(this, outlineRect, dockLocation, this.children.length, CLASSES.FLEXLAYOUT__OUTLINE_RECT);
322
274
  }
323
275
  } else {
324
- const outlineRect = new Rect(this._tabHeaderRect!.x + 1, this._tabHeaderRect!.y + 2, 3, 18);
276
+ const outlineRect = new Rect(this.tabHeaderRect!.x + 1, this.tabHeaderRect!.y + 2, 3, 18);
325
277
  dropInfo = new DropInfo(this, outlineRect, dockLocation, 0, CLASSES.FLEXLAYOUT__OUTLINE_RECT);
326
278
  }
327
279
  } else {
328
- if (this._children.length > 0) {
329
- let child = this._children[0];
280
+ if (this.children.length > 0) {
281
+ let child = this.children[0];
330
282
  let childRect = (child as TabNode).getTabRect()!;
331
283
  const childX = childRect.x;
332
284
  const childWidth = childRect.width;
333
285
 
334
- let pos = this._tabHeaderRect!.y;
286
+ let pos = this.tabHeaderRect!.y;
335
287
  let childCenter = 0;
336
- for (let i = 0; i < this._children.length; i++) {
337
- child = this._children[i];
288
+ for (let i = 0; i < this.children.length; i++) {
289
+ child = this.children[i];
338
290
  childRect = (child as TabNode).getTabRect()!;
339
291
  childCenter = childRect.y + childRect.height / 2;
340
292
  if (y >= pos && y < childCenter) {
@@ -346,20 +298,20 @@ export class BorderNode extends Node implements IDropTarget {
346
298
  }
347
299
  if (dropInfo == null) {
348
300
  const outlineRect = new Rect(childX, childRect.getBottom() - 2, childWidth, 3);
349
- dropInfo = new DropInfo(this, outlineRect, dockLocation, this._children.length, CLASSES.FLEXLAYOUT__OUTLINE_RECT);
301
+ dropInfo = new DropInfo(this, outlineRect, dockLocation, this.children.length, CLASSES.FLEXLAYOUT__OUTLINE_RECT);
350
302
  }
351
303
  } else {
352
- const outlineRect = new Rect(this._tabHeaderRect!.x + 2, this._tabHeaderRect!.y + 1, 18, 3);
304
+ const outlineRect = new Rect(this.tabHeaderRect!.x + 2, this.tabHeaderRect!.y + 1, 18, 3);
353
305
  dropInfo = new DropInfo(this, outlineRect, dockLocation, 0, CLASSES.FLEXLAYOUT__OUTLINE_RECT);
354
306
  }
355
307
  }
356
- if (!dragNode._canDockInto(dragNode, dropInfo)) {
308
+ if (!dragNode.canDockInto(dragNode, dropInfo)) {
357
309
  return undefined;
358
310
  }
359
- } else if (this.getSelected() !== -1 && this._contentRect!.contains(x, y)) {
360
- const outlineRect = this._contentRect;
311
+ } else if (this.getSelected() !== -1 && this.outerRect!.contains(x, y)) {
312
+ const outlineRect = this.outerRect;
361
313
  dropInfo = new DropInfo(this, outlineRect!, dockLocation, -1, CLASSES.FLEXLAYOUT__OUTLINE_RECT);
362
- if (!dragNode._canDockInto(dragNode, dropInfo)) {
314
+ if (!dragNode.canDockInto(dragNode, dropInfo)) {
363
315
  return undefined;
364
316
  }
365
317
  }
@@ -372,72 +324,73 @@ export class BorderNode extends Node implements IDropTarget {
372
324
  let fromIndex = 0;
373
325
  const dragParent = dragNode.getParent() as BorderNode | TabSetNode;
374
326
  if (dragParent !== undefined) {
375
- fromIndex = dragParent._removeChild(dragNode);
327
+ fromIndex = dragParent.removeChild(dragNode);
376
328
  // if selected node in border is being docked into a different border then deselect border tabs
377
329
  if (dragParent !== this && dragParent instanceof BorderNode && dragParent.getSelected() === fromIndex) {
378
- dragParent._setSelected(-1);
330
+ dragParent.setSelected(-1);
379
331
  } else {
380
332
  adjustSelectedIndex(dragParent, fromIndex);
381
333
  }
382
334
  }
383
335
 
384
336
  // if dropping a tab back to same tabset and moving to forward position then reduce insertion index
385
- if (dragNode.getType() === TabNode.TYPE && dragParent === this && fromIndex < index && index > 0) {
337
+ if (dragNode instanceof TabNode && dragParent === this && fromIndex < index && index > 0) {
386
338
  index--;
387
339
  }
388
340
 
389
341
  // simple_bundled dock to existing tabset
390
342
  let insertPos = index;
391
343
  if (insertPos === -1) {
392
- insertPos = this._children.length;
344
+ insertPos = this.children.length;
393
345
  }
394
346
 
395
- if (dragNode.getType() === TabNode.TYPE) {
396
- this._addChild(dragNode, insertPos);
347
+ if (dragNode instanceof TabNode) {
348
+ this.addChild(dragNode, insertPos);
397
349
  }
398
350
 
399
351
  if (select || (select !== false && this.isAutoSelectTab())) {
400
- this._setSelected(insertPos);
352
+ this.setSelected(insertPos);
401
353
  }
402
354
 
403
- this._model._tidy();
404
- }
405
-
406
- toJson(): IJsonBorderNode {
407
- const json: any = {};
408
- BorderNode._attributeDefinitions.toJson(json, this._attributes);
409
- json.location = this._location.getName();
410
- json.children = this._children.map((child) => (child as TabNode).toJson());
411
- return json;
355
+ this.model.tidy();
412
356
  }
413
357
 
414
358
  /** @internal */
415
- _getSplitterBounds(splitter: SplitterNode, useMinSize: boolean = false) {
359
+ getSplitterBounds(index: number, useMinSize: boolean = false) {
416
360
  const pBounds = [0, 0];
417
361
  const minSize = useMinSize ? this.getMinSize() : 0;
418
- const outerRect = this._model._getOuterInnerRects().outer;
419
- const innerRect = this._model._getOuterInnerRects().inner;
420
- const rootRow = this._model.getRoot();
421
- if (this._location === DockLocation.TOP) {
422
- pBounds[0] = outerRect.y + minSize;
423
- pBounds[1] = Math.max(pBounds[0], innerRect.getBottom() - splitter.getHeight() - rootRow.getMinHeight());
424
- } else if (this._location === DockLocation.LEFT) {
425
- pBounds[0] = outerRect.x + minSize;
426
- pBounds[1] = Math.max(pBounds[0], innerRect.getRight() - splitter.getWidth() - rootRow.getMinWidth());
427
- } else if (this._location === DockLocation.BOTTOM) {
428
- pBounds[1] = outerRect.getBottom() - splitter.getHeight() - minSize;
362
+ const maxSize = useMinSize ? this.getMaxSize() : 99999;
363
+ const rootRow = this.model.getRoot(Model.MAIN_WINDOW_ID);
364
+ const innerRect = rootRow.getRect();
365
+ const splitterSize = this.model.getSplitterSize()
366
+ if (this.location === DockLocation.TOP) {
367
+ pBounds[0] = this.tabHeaderRect!.getBottom() + minSize;
368
+ const maxPos = this.tabHeaderRect!.getBottom() + maxSize;
369
+ pBounds[1] = Math.max(pBounds[0], innerRect.getBottom() - rootRow.getMinHeight() - splitterSize);
370
+ pBounds[1] = Math.min(pBounds[1], maxPos);
371
+ } else if (this.location === DockLocation.LEFT) {
372
+ pBounds[0] = this.tabHeaderRect!.getRight() + minSize;
373
+ const maxPos = this.tabHeaderRect!.getRight() + maxSize;
374
+ pBounds[1] = Math.max(pBounds[0], innerRect.getRight() - rootRow.getMinWidth() - splitterSize);
375
+ pBounds[1] = Math.min(pBounds[1], maxPos);
376
+ } else if (this.location === DockLocation.BOTTOM) {
377
+ pBounds[1] = this.tabHeaderRect!.y - minSize - splitterSize;
378
+ const maxPos = this.tabHeaderRect!.y - maxSize - splitterSize;
429
379
  pBounds[0] = Math.min(pBounds[1], innerRect.y + rootRow.getMinHeight());
430
- } else if (this._location === DockLocation.RIGHT) {
431
- pBounds[1] = outerRect.getRight() - splitter.getWidth() - minSize;
380
+ pBounds[0] = Math.max(pBounds[0], maxPos);
381
+ } else if (this.location === DockLocation.RIGHT) {
382
+ pBounds[1] = this.tabHeaderRect!.x - minSize - splitterSize;
383
+ const maxPos = this.tabHeaderRect!.x - maxSize - splitterSize;
432
384
  pBounds[0] = Math.min(pBounds[1], innerRect.x + rootRow.getMinWidth());
385
+ pBounds[0] = Math.max(pBounds[0], maxPos);
433
386
  }
434
387
  return pBounds;
435
388
  }
436
389
 
437
390
  /** @internal */
438
- _calculateSplit(splitter: SplitterNode, splitterPos: number) {
439
- const pBounds = this._getSplitterBounds(splitter);
440
- if (this._location === DockLocation.BOTTOM || this._location === DockLocation.RIGHT) {
391
+ calculateSplit(splitter: BorderNode, splitterPos: number) {
392
+ const pBounds = this.getSplitterBounds(splitterPos);
393
+ if (this.location === DockLocation.BOTTOM || this.location === DockLocation.RIGHT) {
441
394
  return Math.max(0, pBounds[1] - splitterPos);
442
395
  } else {
443
396
  return Math.max(0, splitterPos - pBounds[0]);
@@ -445,13 +398,54 @@ export class BorderNode extends Node implements IDropTarget {
445
398
  }
446
399
 
447
400
  /** @internal */
448
- _getAttributeDefinitions() {
449
- return BorderNode._attributeDefinitions;
401
+ getAttributeDefinitions() {
402
+ return BorderNode.attributeDefinitions;
450
403
  }
451
404
 
452
405
  /** @internal */
453
406
  static getAttributeDefinitions() {
454
- return BorderNode._attributeDefinitions;
407
+ return BorderNode.attributeDefinitions;
455
408
  }
456
409
 
410
+ /** @internal */
411
+ private static createAttributeDefinitions(): AttributeDefinitions {
412
+ const attributeDefinitions = new AttributeDefinitions();
413
+ attributeDefinitions.add("type", BorderNode.TYPE, true).setType(Attribute.STRING).setFixed();
414
+
415
+ attributeDefinitions.add("selected", -1).setType(Attribute.NUMBER).setDescription(
416
+ `index of selected/visible tab in border; -1 means no tab selected`
417
+ );
418
+ attributeDefinitions.add("show", true).setType(Attribute.BOOLEAN).setDescription(
419
+ `show/hide this border`
420
+ );
421
+ attributeDefinitions.add("config", undefined).setType("any").setDescription(
422
+ `a place to hold json config used in your own code`
423
+ );
424
+
425
+ attributeDefinitions.addInherited("enableDrop", "borderEnableDrop").setType(Attribute.BOOLEAN).setDescription(
426
+ `whether tabs can be dropped into this border`
427
+ );
428
+ attributeDefinitions.addInherited("className", "borderClassName").setType(Attribute.STRING).setDescription(
429
+ `class applied to tab button`
430
+ );
431
+ attributeDefinitions.addInherited("autoSelectTabWhenOpen", "borderAutoSelectTabWhenOpen").setType(Attribute.BOOLEAN).setDescription(
432
+ `whether to select new/moved tabs in border when the border is already open`
433
+ );
434
+ attributeDefinitions.addInherited("autoSelectTabWhenClosed", "borderAutoSelectTabWhenClosed").setType(Attribute.BOOLEAN).setDescription(
435
+ `whether to select new/moved tabs in border when the border is currently closed`
436
+ );
437
+ attributeDefinitions.addInherited("size", "borderSize").setType(Attribute.NUMBER).setDescription(
438
+ `size of the tab area when selected`
439
+ );
440
+ attributeDefinitions.addInherited("minSize", "borderMinSize").setType(Attribute.NUMBER).setDescription(
441
+ `the minimum size of the tab area`
442
+ );
443
+ attributeDefinitions.addInherited("maxSize", "borderMaxSize").setType(Attribute.NUMBER).setDescription(
444
+ `the maximum size of the tab area`
445
+ );
446
+ attributeDefinitions.addInherited("enableAutoHide", "borderEnableAutoHide").setType(Attribute.BOOLEAN).setDescription(
447
+ `hide border if it has zero tabs`
448
+ );
449
+ return attributeDefinitions;
450
+ }
457
451
  }