flexlayout-react 0.7.14 → 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 +26 -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 -6
  82. package/declarations/view/Layout.d.ts +139 -160
  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 -40
  155. package/lib/view/Icons.js.map +1 -1
  156. package/lib/view/Layout.js +918 -901
  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 +13 -0
  206. package/src/view/Layout.tsx +1071 -1047
  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 +143 -35
  220. package/style/dark.css +685 -577
  221. package/style/dark.css.map +1 -1
  222. package/style/dark.scss +4 -1
  223. package/style/gray.css +668 -560
  224. package/style/gray.css.map +1 -1
  225. package/style/gray.scss +4 -1
  226. package/style/light.css +669 -561
  227. package/style/light.css.map +1 -1
  228. package/style/light.scss +6 -3
  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 -582
  233. package/style/underline.css.map +1 -1
  234. package/style/underline.scss +4 -1
  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
@@ -4,350 +4,324 @@ import { AttributeDefinitions } from "../AttributeDefinitions";
4
4
  import { DockLocation } from "../DockLocation";
5
5
  import { DropInfo } from "../DropInfo";
6
6
  import { Orientation } from "../Orientation";
7
- import { Rect } from "../Rect";
8
7
  import { CLASSES } from "../Types";
9
8
  import { BorderNode } from "./BorderNode";
10
9
  import { IDraggable } from "./IDraggable";
11
10
  import { IDropTarget } from "./IDropTarget";
12
11
  import { IJsonRowNode } from "./IJsonModel";
13
- import { Model, ILayoutMetrics } from "./Model";
12
+ import { DefaultMax, DefaultMin, Model } from "./Model";
14
13
  import { Node } from "./Node";
15
- import { SplitterNode } from "./SplitterNode";
16
14
  import { TabSetNode } from "./TabSetNode";
15
+ import { canDockToWindow } from "../view/Utils";
16
+ import { LayoutWindow } from "./LayoutWindow";
17
17
 
18
18
  export class RowNode extends Node implements IDropTarget {
19
19
  static readonly TYPE = "row";
20
20
 
21
21
  /** @internal */
22
- static _fromJson(json: any, model: Model) {
23
- const newLayoutNode = new RowNode(model, json);
22
+ static fromJson(json: any, model: Model, layoutWindow: LayoutWindow) {
23
+ const newLayoutNode = new RowNode(model, layoutWindow.windowId, json);
24
24
 
25
25
  if (json.children != null) {
26
26
  for (const jsonChild of json.children) {
27
27
  if (jsonChild.type === TabSetNode.TYPE) {
28
- const child = TabSetNode._fromJson(jsonChild, model);
29
- newLayoutNode._addChild(child);
28
+ const child = TabSetNode.fromJson(jsonChild, model, layoutWindow);
29
+ newLayoutNode.addChild(child);
30
30
  } else {
31
- const child = RowNode._fromJson(jsonChild, model);
32
- newLayoutNode._addChild(child);
31
+ const child = RowNode.fromJson(jsonChild, model, layoutWindow);
32
+ newLayoutNode.addChild(child);
33
33
  }
34
34
  }
35
35
  }
36
36
 
37
37
  return newLayoutNode;
38
38
  }
39
- /** @internal */
40
- private static _attributeDefinitions: AttributeDefinitions = RowNode._createAttributeDefinitions();
41
39
 
42
40
  /** @internal */
43
- private static _createAttributeDefinitions(): AttributeDefinitions {
44
- const attributeDefinitions = new AttributeDefinitions();
45
- attributeDefinitions.add("type", RowNode.TYPE, true).setType(Attribute.STRING).setFixed();
46
- attributeDefinitions.add("id", undefined).setType(Attribute.STRING);
47
-
48
- attributeDefinitions.add("weight", 100).setType(Attribute.NUMBER);
49
- attributeDefinitions.add("width", undefined).setType(Attribute.NUMBER);
50
- attributeDefinitions.add("height", undefined).setType(Attribute.NUMBER);
41
+ private static attributeDefinitions: AttributeDefinitions = RowNode.createAttributeDefinitions();
51
42
 
52
- return attributeDefinitions;
53
- }
54
43
  /** @internal */
55
- private _drawChildren: (TabSetNode | RowNode | SplitterNode)[];
44
+ private windowId: string;
45
+ /** @internal */
46
+ private minHeight: number;
47
+ /** @internal */
48
+ private minWidth: number;
56
49
  /** @internal */
57
- private _minHeight: number;
50
+ private maxHeight: number;
58
51
  /** @internal */
59
- private _minWidth: number;
52
+ private maxWidth: number;
60
53
 
61
54
  /** @internal */
62
- constructor(model: Model, json: any) {
55
+ constructor(model: Model, windowId: string, json: any) {
63
56
  super(model);
64
57
 
65
- this._dirty = true;
66
- this._drawChildren = [];
67
- this._minHeight = 0;
68
- this._minWidth = 0;
69
- RowNode._attributeDefinitions.fromJson(json, this._attributes);
70
- model._addNode(this);
58
+ this.windowId = windowId;
59
+ this.minHeight = DefaultMin;
60
+ this.minWidth = DefaultMin;
61
+ this.maxHeight = DefaultMax;
62
+ this.maxWidth = DefaultMax;
63
+ RowNode.attributeDefinitions.fromJson(json, this.attributes);
64
+ this.normalizeWeights();
65
+ model.addNode(this);
71
66
  }
72
67
 
73
68
  getWeight() {
74
- return this._attributes.weight as number;
69
+ return this.attributes.weight as number;
75
70
  }
76
71
 
77
- getWidth() {
78
- return this._getAttr("width") as number | undefined;
72
+ toJson(): IJsonRowNode {
73
+ const json: any = {};
74
+ RowNode.attributeDefinitions.toJson(json, this.attributes);
75
+
76
+ json.children = [];
77
+ for (const child of this.children) {
78
+ json.children.push(child.toJson());
79
+ }
80
+
81
+ return json;
82
+ }
83
+
84
+ /** @internal */
85
+ getWindowId() {
86
+ return this.windowId;
79
87
  }
80
88
 
81
- getHeight() {
82
- return this._getAttr("height") as number | undefined;
89
+ setWindowId(windowId: string) {
90
+ this.windowId = windowId;
83
91
  }
84
92
 
85
93
  /** @internal */
86
- _setWeight(weight: number) {
87
- this._attributes.weight = weight;
94
+ setWeight(weight: number) {
95
+ this.attributes.weight = weight;
88
96
  }
89
97
 
90
98
  /** @internal */
91
- _layout(rect: Rect, metrics: ILayoutMetrics) {
92
- super._layout(rect, metrics);
93
-
94
- const pixelSize = this._rect._getSize(this.getOrientation());
95
-
96
- let totalWeight = 0;
97
- let fixedPixels = 0;
98
- let prefPixels = 0;
99
- let totalPrefWeight = 0;
100
- const drawChildren = this._getDrawChildren() as (RowNode | TabSetNode | SplitterNode)[];
101
-
102
- for (const child of drawChildren) {
103
- const prefSize = child._getPrefSize(this.getOrientation());
104
- if (child._isFixed()) {
105
- if (prefSize !== undefined) {
106
- fixedPixels += prefSize;
107
- }
108
- } else {
109
- if (prefSize === undefined) {
110
- totalWeight += child.getWeight();
111
- } else {
112
- prefPixels += prefSize;
113
- totalPrefWeight += child.getWeight();
114
- }
99
+ getSplitterBounds(index: number) {
100
+ const h = this.getOrientation() === Orientation.HORZ;
101
+ const c = this.getChildren();
102
+ const ss = this.model.getSplitterSize();
103
+ const fr = c[0].getRect();
104
+ const lr = c[c.length - 1].getRect();
105
+ let p = h ? [fr.x, lr.getRight()] : [fr.y, lr.getBottom()];
106
+ const q = h ? [fr.x, lr.getRight()] : [fr.y, lr.getBottom()];
107
+
108
+ for (let i = 0; i < index; i++) {
109
+ const n = c[i] as TabSetNode | RowNode;
110
+ p[0] += h ? n.getMinWidth() : n.getMinHeight();
111
+ q[0] += h ? n.getMaxWidth() : n.getMaxHeight();
112
+ if (i > 0) {
113
+ p[0] += ss;
114
+ q[0] += ss;
115
115
  }
116
116
  }
117
117
 
118
- let resizePreferred = false;
119
- let availablePixels = pixelSize - fixedPixels - prefPixels;
120
- if (availablePixels < 0) {
121
- availablePixels = pixelSize - fixedPixels;
122
- resizePreferred = true;
123
- totalWeight += totalPrefWeight;
118
+ for (let i = c.length - 1; i >= index; i--) {
119
+ const n = c[i] as TabSetNode | RowNode;
120
+ p[1] -= (h ? n.getMinWidth() : n.getMinHeight()) + ss;
121
+ q[1] -= (h ? n.getMaxWidth() : n.getMaxHeight()) + ss;
124
122
  }
125
- // assign actual pixel sizes
126
- let totalSizeGiven = 0;
127
- let variableSize = 0;
128
- for (const child of drawChildren) {
129
- const prefSize = child._getPrefSize(this.getOrientation());
130
- if (child._isFixed()) {
131
- if (prefSize !== undefined) {
132
- child._setTempSize(prefSize);
133
- }
123
+
124
+ p = [Math.max(q[1], p[0]), Math.min(q[0], p[1])];
125
+
126
+ return p;
127
+ }
128
+
129
+ /** @internal */
130
+ getSplitterInitials(index: number) {
131
+ const h = this.getOrientation() === Orientation.HORZ;
132
+ const c = this.getChildren();
133
+ const ss = this.model.getSplitterSize();
134
+ const initialSizes = [];
135
+
136
+ let sum = 0;
137
+
138
+ for (let i = 0; i < c.length; i++) {
139
+ const n = c[i] as TabSetNode | RowNode;
140
+ const r = n.getRect();
141
+ const s = h ? r.width : r.height;
142
+ initialSizes.push(s);
143
+ sum += s;
144
+ }
145
+
146
+ const startRect = c[index].getRect()
147
+ const startPosition = (h ? startRect.x : startRect.y) - ss;
148
+
149
+ return { initialSizes, sum, startPosition };
150
+ }
151
+
152
+ /** @internal */
153
+ calculateSplit(index: number, splitterPos: number, initialSizes: number[], sum: number, startPosition: number) {
154
+ const h = this.getOrientation() === Orientation.HORZ;
155
+ const c = this.getChildren();
156
+ const sn = c[index] as TabSetNode | RowNode;
157
+ const smax = h ? sn.getMaxWidth() : sn.getMaxHeight();
158
+
159
+ const sizes = [...initialSizes];
160
+
161
+ if (splitterPos < startPosition) { // moved left
162
+ let shift = startPosition - splitterPos;
163
+ let altShift = 0;
164
+ if (sizes[index] + shift > smax) {
165
+ altShift = sizes[index] + shift - smax;
166
+ sizes[index] = smax;
134
167
  } else {
135
- if (prefSize == null || resizePreferred) {
136
- if (totalWeight === 0) {
137
- child._setTempSize(0);
138
- } else {
139
- const minSize = child.getMinSize(this.getOrientation());
140
- const size = Math.floor(availablePixels * (child.getWeight() / totalWeight));
141
- child._setTempSize(Math.max(minSize, size));
142
- }
143
- variableSize += child._getTempSize();
168
+ sizes[index] += shift;
169
+ }
170
+
171
+ for (let i = index - 1; i >= 0; i--) {
172
+ const n = c[i] as TabSetNode | RowNode;
173
+ const m = h ? n.getMinWidth() : n.getMinHeight();
174
+ if (sizes[i] - shift > m) {
175
+ sizes[i] -= shift;
176
+ break;
144
177
  } else {
145
- child._setTempSize(prefSize);
178
+ shift -= sizes[i] - m;
179
+ sizes[i] = m;
146
180
  }
147
181
  }
148
182
 
149
- totalSizeGiven += child._getTempSize();
150
- }
151
-
152
- // adjust sizes to exactly fit
153
- if (variableSize > 0) {
154
- while (totalSizeGiven < pixelSize) {
155
- for (const child of drawChildren) {
156
- if (!(child instanceof SplitterNode)) {
157
- const prefSize = child._getPrefSize(this.getOrientation());
158
- if (!child._isFixed() && (prefSize === undefined || resizePreferred) && totalSizeGiven < pixelSize) {
159
- child._setTempSize(child._getTempSize() + 1);
160
- totalSizeGiven++;
161
- }
162
- }
183
+ for (let i = index+1; i < c.length; i++) {
184
+ const n = c[i] as TabSetNode | RowNode;
185
+ const m = h ? n.getMaxWidth() : n.getMaxHeight();
186
+ if (sizes[i] + altShift < m) {
187
+ sizes[i] += altShift;
188
+ break;
189
+ } else {
190
+ altShift -= m - sizes[i];
191
+ sizes[i] = m;
163
192
  }
164
193
  }
165
194
 
166
- // decrease size using nodes not at there minimum
167
- while (totalSizeGiven > pixelSize) {
168
- let changed = false;
169
- for (const child of drawChildren) {
170
- if (!(child instanceof SplitterNode)) {
171
- const minSize = child.getMinSize(this.getOrientation());
172
- const size = child._getTempSize();
173
- if (size > minSize && totalSizeGiven > pixelSize) {
174
- child._setTempSize(child._getTempSize() - 1);
175
- totalSizeGiven--;
176
- changed = true;
177
- }
178
- }
179
- }
180
- if (!changed) {
181
- // all children are at min values
195
+
196
+ } else {
197
+ let shift = splitterPos - startPosition;
198
+ let altShift = 0;
199
+ if (sizes[index-1] + shift > smax) {
200
+ altShift = sizes[index-1] + shift - smax;
201
+ sizes[index-1] = smax;
202
+ } else {
203
+ sizes[index-1] += shift;
204
+ }
205
+
206
+ for (let i = index; i < c.length; i++) {
207
+ const n = c[i] as TabSetNode | RowNode;
208
+ const m = h ? n.getMinWidth() : n.getMinHeight();
209
+ if (sizes[i] - shift > m) {
210
+ sizes[i] -= shift;
182
211
  break;
212
+ } else {
213
+ shift -= sizes[i] - m;
214
+ sizes[i] = m;
183
215
  }
184
216
  }
185
217
 
186
- // if still too big then simply reduce all nodes until fits
187
- while (totalSizeGiven > pixelSize) {
188
- let changed = false;
189
- for (const child of drawChildren) {
190
- if (!(child instanceof SplitterNode)) {
191
- const size = child._getTempSize();
192
- if (size > 0 && totalSizeGiven > pixelSize) {
193
- child._setTempSize(child._getTempSize() - 1);
194
- totalSizeGiven--;
195
- changed = true;
196
- }
197
- }
198
- }
199
- if (!changed) {
200
- // all children are at 0 values
218
+ for (let i = index - 1; i >= 0; i--) {
219
+ const n = c[i] as TabSetNode | RowNode;
220
+ const m = h ? n.getMaxWidth() : n.getMaxHeight();
221
+ if (sizes[i] + altShift < m) {
222
+ sizes[i] += altShift;
201
223
  break;
224
+ } else {
225
+ altShift -= m - sizes[i];
226
+ sizes[i] = m;
202
227
  }
203
228
  }
204
229
  }
205
230
 
206
- // layout children
207
- let p = 0;
208
- for (const child of drawChildren) {
209
- if (this.getOrientation() === Orientation.HORZ) {
210
- child._layout(new Rect(this._rect.x + p, this._rect.y, child._getTempSize(), this._rect.height), metrics);
211
- } else {
212
- child._layout(new Rect(this._rect.x, this._rect.y + p, this._rect.width, child._getTempSize()), metrics);
213
- }
214
- p += child._getTempSize();
215
- }
231
+ // 0.1 is to prevent weight ever going to zero
232
+ const weights = sizes.map(s => Math.max(0.1, s) * 100 / sum);
216
233
 
217
- return true;
234
+ // console.log(splitterPos, startPosition, "sizes", sizes);
235
+ // console.log("weights",weights);
236
+ return weights;
218
237
  }
219
238
 
220
239
  /** @internal */
221
- _getSplitterBounds(splitterNode: SplitterNode, useMinSize: boolean = false) {
222
- const pBounds = [0, 0];
223
- const drawChildren = this._getDrawChildren() as (RowNode | TabSetNode | SplitterNode)[];
224
- const p = drawChildren.indexOf(splitterNode);
225
- const node1 = drawChildren[p - 1];
226
- const node2 = drawChildren[p + 1];
227
- if (this.getOrientation() === Orientation.HORZ) {
228
- const minSize1 = useMinSize ? node1.getMinWidth() : 0;
229
- const minSize2 = useMinSize ? node2.getMinWidth() : 0;
230
- pBounds[0] = node1.getRect().x + minSize1;
231
- pBounds[1] = node2.getRect().getRight() - splitterNode.getWidth() - minSize2;
240
+ getMinSize(orientation: Orientation) {
241
+ if (orientation === Orientation.HORZ) {
242
+ return this.getMinWidth();
232
243
  } else {
233
- const minSize1 = useMinSize ? node1.getMinHeight() : 0;
234
- const minSize2 = useMinSize ? node2.getMinHeight() : 0;
235
- pBounds[0] = node1.getRect().y + minSize1;
236
- pBounds[1] = node2.getRect().getBottom() - splitterNode.getHeight() - minSize2;
244
+ return this.getMinHeight();
237
245
  }
238
- return pBounds;
239
246
  }
240
247
 
241
248
  /** @internal */
242
- _calculateSplit(splitter: SplitterNode, splitterPos: number) {
243
- let rtn;
244
- const drawChildren = this._getDrawChildren() as (RowNode | TabSetNode | SplitterNode)[];
245
- const p = drawChildren.indexOf(splitter);
246
- const pBounds = this._getSplitterBounds(splitter);
247
-
248
- const weightedLength = drawChildren[p - 1].getWeight() + drawChildren[p + 1].getWeight();
249
-
250
- const pixelWidth1 = Math.max(0, splitterPos - pBounds[0]);
251
- const pixelWidth2 = Math.max(0, pBounds[1] - splitterPos);
252
-
253
- if (pixelWidth1 + pixelWidth2 > 0) {
254
- const weight1 = (pixelWidth1 * weightedLength) / (pixelWidth1 + pixelWidth2);
255
- const weight2 = (pixelWidth2 * weightedLength) / (pixelWidth1 + pixelWidth2);
256
-
257
- rtn = {
258
- node1Id: drawChildren[p - 1].getId(),
259
- weight1,
260
- pixelWidth1,
261
- node2Id: drawChildren[p + 1].getId(),
262
- weight2,
263
- pixelWidth2,
264
- };
265
- }
266
-
267
- return rtn;
249
+ getMinWidth() {
250
+ return this.minWidth;
268
251
  }
269
252
 
270
253
  /** @internal */
271
- _getDrawChildren(): Node[] | undefined {
272
- if (this._dirty) {
273
- this._drawChildren = [];
274
-
275
- for (let i = 0; i < this._children.length; i++) {
276
- const child = this._children[i] as RowNode | TabSetNode;
277
- if (i !== 0) {
278
- const newSplitter = new SplitterNode(this._model);
279
- newSplitter._setParent(this);
280
- this._drawChildren.push(newSplitter);
281
- }
282
- this._drawChildren.push(child);
283
- }
284
- this._dirty = false;
285
- }
286
-
287
- return this._drawChildren;
254
+ getMinHeight() {
255
+ return this.minHeight;
288
256
  }
289
257
 
290
258
  /** @internal */
291
- getMinSize(orientation: Orientation) {
259
+ getMaxSize(orientation: Orientation) {
292
260
  if (orientation === Orientation.HORZ) {
293
- return this.getMinWidth();
261
+ return this.getMaxWidth();
294
262
  } else {
295
- return this.getMinHeight();
263
+ return this.getMaxHeight();
296
264
  }
297
265
  }
298
266
 
299
267
  /** @internal */
300
- getMinWidth() {
301
- return this._minWidth;
268
+ getMaxWidth() {
269
+ return this.maxWidth;
302
270
  }
303
271
 
304
272
  /** @internal */
305
- getMinHeight() {
306
- return this._minHeight;
273
+ getMaxHeight() {
274
+ return this.maxHeight;
307
275
  }
308
276
 
309
277
  /** @internal */
310
- calcMinSize() {
311
- this._minHeight = 0;
312
- this._minWidth = 0;
278
+ calcMinMaxSize() {
279
+ this.minHeight = DefaultMin;
280
+ this.minWidth = DefaultMin;
281
+ this.maxHeight = DefaultMax;
282
+ this.maxWidth = DefaultMax;
313
283
  let first = true;
314
- for (const child of this._children) {
284
+ for (const child of this.children) {
315
285
  const c = child as RowNode | TabSetNode;
316
- if (c instanceof RowNode) {
317
- c.calcMinSize();
318
- }
286
+ c.calcMinMaxSize();
319
287
  if (this.getOrientation() === Orientation.VERT) {
320
- this._minHeight += c.getMinHeight();
288
+ this.minHeight += c.getMinHeight();
289
+ this.maxHeight += c.getMaxHeight();
321
290
  if (!first) {
322
- this._minHeight += this._model.getSplitterSize();
291
+ this.minHeight += this.model.getSplitterSize();
292
+ this.maxHeight += this.model.getSplitterSize();
323
293
  }
324
- this._minWidth = Math.max(this._minWidth, c.getMinWidth());
294
+ this.minWidth = Math.max(this.minWidth, c.getMinWidth());
295
+ this.maxWidth = Math.min(this.maxWidth, c.getMaxWidth());
325
296
  } else {
326
- this._minWidth += c.getMinWidth();
297
+ this.minWidth += c.getMinWidth();
298
+ this.maxWidth += c.getMaxWidth();
327
299
  if (!first) {
328
- this._minWidth += this._model.getSplitterSize();
300
+ this.minWidth += this.model.getSplitterSize();
301
+ this.maxWidth += this.model.getSplitterSize();
329
302
  }
330
- this._minHeight = Math.max(this._minHeight, c.getMinHeight());
303
+ this.minHeight = Math.max(this.minHeight, c.getMinHeight());
304
+ this.maxHeight = Math.min(this.maxHeight, c.getMaxHeight());
331
305
  }
332
306
  first = false;
333
307
  }
334
308
  }
335
309
 
336
310
  /** @internal */
337
- _tidy() {
311
+ tidy() {
338
312
  let i = 0;
339
- while (i < this._children.length) {
340
- const child = this._children[i];
313
+ while (i < this.children.length) {
314
+ const child = this.children[i];
341
315
  if (child instanceof RowNode) {
342
- child._tidy();
316
+ child.tidy();
343
317
 
344
318
  const childChildren = child.getChildren();
345
319
  if (childChildren.length === 0) {
346
- this._removeChild(child);
320
+ this.removeChild(child);
347
321
  } else if (childChildren.length === 1) {
348
322
  // hoist child/children up to this level
349
323
  const subchild = childChildren[0];
350
- this._removeChild(child);
324
+ this.removeChild(child);
351
325
  if (subchild instanceof RowNode) {
352
326
  let subChildrenTotal = 0;
353
327
  const subChildChildren = subchild.getChildren();
@@ -357,21 +331,21 @@ export class RowNode extends Node implements IDropTarget {
357
331
  }
358
332
  for (let j = 0; j < subChildChildren.length; j++) {
359
333
  const subsubChild = subChildChildren[j] as RowNode | TabSetNode;
360
- subsubChild._setWeight((child.getWeight() * subsubChild.getWeight()) / subChildrenTotal);
361
- this._addChild(subsubChild, i + j);
334
+ subsubChild.setWeight((child.getWeight() * subsubChild.getWeight()) / subChildrenTotal);
335
+ this.addChild(subsubChild, i + j);
362
336
  }
363
337
  } else {
364
- subchild._setWeight(child.getWeight());
365
- this._addChild(subchild, i);
338
+ subchild.setWeight(child.getWeight());
339
+ this.addChild(subchild, i);
366
340
  }
367
341
  } else {
368
342
  i++;
369
343
  }
370
344
  } else if (child instanceof TabSetNode && child.getChildren().length === 0) {
371
345
  if (child.isEnableDeleteWhenEmpty()) {
372
- this._removeChild(child);
373
- if (child === this._model.getMaximizedTabset()) {
374
- this._model._setMaximizedTabset(undefined);
346
+ this.removeChild(child);
347
+ if (child === this.model.getMaximizedTabset(this.windowId)) {
348
+ this.model.setMaximizedTabset(undefined, this.windowId);
375
349
  }
376
350
  } else {
377
351
  i++;
@@ -382,55 +356,58 @@ export class RowNode extends Node implements IDropTarget {
382
356
  }
383
357
 
384
358
  // add tabset into empty root
385
- if (this === this._model.getRoot() && this._children.length === 0) {
386
- const callback = this._model._getOnCreateTabSet();
359
+ if (this === this.model.getRoot(this.windowId) && this.children.length === 0) {
360
+ const callback = this.model.getOnCreateTabSet();
387
361
  let attrs = callback ? callback() : {};
388
362
  attrs = { ...attrs, selected: -1 };
389
- const child = new TabSetNode(this._model, attrs);
390
- this._model._setActiveTabset(child);
391
- this._addChild(child);
363
+ const child = new TabSetNode(this.model, attrs);
364
+ this.model.setActiveTabset(child, this.windowId);
365
+ this.addChild(child);
392
366
  }
393
367
 
394
368
  }
395
369
 
396
370
  /** @internal */
397
371
  canDrop(dragNode: Node & IDraggable, x: number, y: number): DropInfo | undefined {
398
- const yy = y - this._rect.y;
399
- const xx = x - this._rect.x;
400
- const w = this._rect.width;
401
- const h = this._rect.height;
372
+ const yy = y - this.rect.y;
373
+ const xx = x - this.rect.x;
374
+ const w = this.rect.width;
375
+ const h = this.rect.height;
402
376
  const margin = 10; // height of edge rect
403
377
  const half = 50; // half width of edge rect
404
378
  let dropInfo;
405
379
 
406
- if (this._model.isEnableEdgeDock() && this._parent === undefined) {
407
- // _root row
408
- if (x < this._rect.x + margin && yy > h / 2 - half && yy < h / 2 + half) {
380
+ if (this.getWindowId() !== Model.MAIN_WINDOW_ID && !canDockToWindow(dragNode)) {
381
+ return undefined;
382
+ }
383
+
384
+ if (this.model.isEnableEdgeDock() && this.parent === undefined) {
385
+ if (x < this.rect.x + margin && yy > h / 2 - half && yy < h / 2 + half) {
409
386
  const dockLocation = DockLocation.LEFT;
410
- const outlineRect = dockLocation.getDockRect(this._rect);
387
+ const outlineRect = dockLocation.getDockRect(this.rect);
411
388
  outlineRect.width = outlineRect.width / 2;
412
389
  dropInfo = new DropInfo(this, outlineRect, dockLocation, -1, CLASSES.FLEXLAYOUT__OUTLINE_RECT_EDGE);
413
- } else if (x > this._rect.getRight() - margin && yy > h / 2 - half && yy < h / 2 + half) {
390
+ } else if (x > this.rect.getRight() - margin && yy > h / 2 - half && yy < h / 2 + half) {
414
391
  const dockLocation = DockLocation.RIGHT;
415
- const outlineRect = dockLocation.getDockRect(this._rect);
392
+ const outlineRect = dockLocation.getDockRect(this.rect);
416
393
  outlineRect.width = outlineRect.width / 2;
417
394
  outlineRect.x += outlineRect.width;
418
395
  dropInfo = new DropInfo(this, outlineRect, dockLocation, -1, CLASSES.FLEXLAYOUT__OUTLINE_RECT_EDGE);
419
- } else if (y < this._rect.y + margin && xx > w / 2 - half && xx < w / 2 + half) {
396
+ } else if (y < this.rect.y + margin && xx > w / 2 - half && xx < w / 2 + half) {
420
397
  const dockLocation = DockLocation.TOP;
421
- const outlineRect = dockLocation.getDockRect(this._rect);
398
+ const outlineRect = dockLocation.getDockRect(this.rect);
422
399
  outlineRect.height = outlineRect.height / 2;
423
400
  dropInfo = new DropInfo(this, outlineRect, dockLocation, -1, CLASSES.FLEXLAYOUT__OUTLINE_RECT_EDGE);
424
- } else if (y > this._rect.getBottom() - margin && xx > w / 2 - half && xx < w / 2 + half) {
401
+ } else if (y > this.rect.getBottom() - margin && xx > w / 2 - half && xx < w / 2 + half) {
425
402
  const dockLocation = DockLocation.BOTTOM;
426
- const outlineRect = dockLocation.getDockRect(this._rect);
403
+ const outlineRect = dockLocation.getDockRect(this.rect);
427
404
  outlineRect.height = outlineRect.height / 2;
428
405
  outlineRect.y += outlineRect.height;
429
406
  dropInfo = new DropInfo(this, outlineRect, dockLocation, -1, CLASSES.FLEXLAYOUT__OUTLINE_RECT_EDGE);
430
407
  }
431
408
 
432
409
  if (dropInfo !== undefined) {
433
- if (!dragNode._canDockInto(dragNode, dropInfo)) {
410
+ if (!dragNode.canDockInto(dragNode, dropInfo)) {
434
411
  return undefined;
435
412
  }
436
413
  }
@@ -440,32 +417,38 @@ export class RowNode extends Node implements IDropTarget {
440
417
  }
441
418
 
442
419
  /** @internal */
443
- drop(dragNode: Node & IDraggable, location: DockLocation, index: number): void {
420
+ drop(dragNode: Node, location: DockLocation, index: number): void {
444
421
  const dockLocation = location;
445
422
 
446
423
  const parent = dragNode.getParent();
447
424
 
448
425
  if (parent) {
449
- parent._removeChild(dragNode);
426
+ parent.removeChild(dragNode);
450
427
  }
451
428
 
452
- if (parent !== undefined && parent!.getType() === TabSetNode.TYPE) {
453
- parent._setSelected(0);
429
+ if (parent !== undefined && parent! instanceof TabSetNode) {
430
+ parent.setSelected(0);
454
431
  }
455
432
 
456
- if (parent !== undefined && parent!.getType() === BorderNode.TYPE) {
457
- parent._setSelected(-1);
433
+ if (parent !== undefined && parent! instanceof BorderNode) {
434
+ parent.setSelected(-1);
458
435
  }
459
436
 
460
- let tabSet: TabSetNode | undefined;
461
- if (dragNode instanceof TabSetNode) {
462
- tabSet = dragNode;
437
+ let node: TabSetNode | RowNode | undefined;
438
+ if (dragNode instanceof TabSetNode || dragNode instanceof RowNode) {
439
+ node = dragNode;
440
+ // need to turn round if same orientation unless docking oposite direction
441
+ if (node instanceof RowNode && node.getOrientation() === this.getOrientation() &&
442
+ (location.getOrientation() === this.getOrientation() || location === DockLocation.CENTER)) {
443
+ node = new RowNode(this.model, this.windowId, {});
444
+ node.addChild(dragNode);
445
+ }
463
446
  } else {
464
- const callback = this._model._getOnCreateTabSet();
465
- tabSet = new TabSetNode(this._model, callback ? callback(dragNode as TabNode) : {});
466
- tabSet._addChild(dragNode);
447
+ const callback = this.model.getOnCreateTabSet();
448
+ node = new TabSetNode(this.model, callback ? callback(dragNode as TabNode) : {});
449
+ node.addChild(dragNode);
467
450
  }
468
- let size = this._children.reduce((sum, child) => {
451
+ let size = this.children.reduce((sum, child) => {
469
452
  return sum + (child as RowNode | TabSetNode).getWeight();
470
453
  }, 0);
471
454
 
@@ -473,83 +456,104 @@ export class RowNode extends Node implements IDropTarget {
473
456
  size = 100;
474
457
  }
475
458
 
476
- tabSet._setWeight(size / 3);
477
-
478
- const horz = !this._model.isRootOrientationVertical();
459
+ node.setWeight(size / 3);
479
460
 
480
- if (horz && dockLocation === DockLocation.LEFT || !horz && dockLocation === DockLocation.TOP) {
481
- this._addChild(tabSet, 0);
461
+ const horz = !this.model.isRootOrientationVertical();
462
+ if (dockLocation === DockLocation.CENTER) {
463
+ if (index === -1) {
464
+ this.addChild(node, this.children.length);
465
+ } else {
466
+ this.addChild(node, index);
467
+ }
468
+ } else if (horz && dockLocation === DockLocation.LEFT || !horz && dockLocation === DockLocation.TOP) {
469
+ this.addChild(node, 0);
482
470
  } else if (horz && dockLocation === DockLocation.RIGHT || !horz && dockLocation === DockLocation.BOTTOM) {
483
- this._addChild(tabSet);
471
+ this.addChild(node);
484
472
  } else if (horz && dockLocation === DockLocation.TOP || !horz && dockLocation === DockLocation.LEFT) {
485
- const vrow = new RowNode(this._model, {});
486
- const hrow = new RowNode(this._model, {});
487
- hrow._setWeight(75);
488
- tabSet._setWeight(25);
489
- for (const child of this._children) {
490
- hrow._addChild(child);
473
+ const vrow = new RowNode(this.model, this.windowId, {});
474
+ const hrow = new RowNode(this.model, this.windowId, {});
475
+ hrow.setWeight(75);
476
+ node.setWeight(25);
477
+ for (const child of this.children) {
478
+ hrow.addChild(child);
491
479
  }
492
- this._removeAll();
493
- vrow._addChild(tabSet);
494
- vrow._addChild(hrow);
495
- this._addChild(vrow);
480
+ this.removeAll();
481
+ vrow.addChild(node);
482
+ vrow.addChild(hrow);
483
+ this.addChild(vrow);
496
484
  } else if (horz && dockLocation === DockLocation.BOTTOM || !horz && dockLocation === DockLocation.RIGHT) {
497
- const vrow = new RowNode(this._model, {});
498
- const hrow = new RowNode(this._model, {});
499
- hrow._setWeight(75);
500
- tabSet._setWeight(25);
501
- for (const child of this._children) {
502
- hrow._addChild(child);
485
+ const vrow = new RowNode(this.model, this.windowId, {});
486
+ const hrow = new RowNode(this.model, this.windowId, {});
487
+ hrow.setWeight(75);
488
+ node.setWeight(25);
489
+ for (const child of this.children) {
490
+ hrow.addChild(child);
503
491
  }
504
- this._removeAll();
505
- vrow._addChild(hrow);
506
- vrow._addChild(tabSet);
507
- this._addChild(vrow);
492
+ this.removeAll();
493
+ vrow.addChild(hrow);
494
+ vrow.addChild(node);
495
+ this.addChild(vrow);
508
496
  }
509
497
 
510
- this._model._setActiveTabset(tabSet);
498
+ if (node instanceof TabSetNode) {
499
+ this.model.setActiveTabset(node, this.windowId);
500
+ }
511
501
 
512
- this._model._tidy();
502
+ this.model.tidy();
513
503
  }
514
504
 
515
- toJson(): IJsonRowNode {
516
- const json: any = {};
517
- RowNode._attributeDefinitions.toJson(json, this._attributes);
518
-
519
- json.children = [];
520
- for (const child of this._children) {
521
- json.children.push(child.toJson());
522
- }
523
505
 
524
- return json;
525
- }
526
506
 
507
+ /** @internal */
527
508
  isEnableDrop() {
528
509
  return true;
529
510
  }
530
511
 
531
512
  /** @internal */
532
- _getPrefSize(orientation: Orientation) {
533
- let prefSize = this.getWidth();
534
- if (orientation === Orientation.VERT) {
535
- prefSize = this.getHeight();
536
- }
537
- return prefSize;
513
+ getAttributeDefinitions() {
514
+ return RowNode.attributeDefinitions;
538
515
  }
539
516
 
540
517
  /** @internal */
541
- _getAttributeDefinitions() {
542
- return RowNode._attributeDefinitions;
518
+ updateAttrs(json: any) {
519
+ RowNode.attributeDefinitions.update(json, this.attributes);
543
520
  }
544
521
 
545
522
  /** @internal */
546
- _updateAttrs(json: any) {
547
- RowNode._attributeDefinitions.update(json, this._attributes);
523
+ static getAttributeDefinitions() {
524
+ return RowNode.attributeDefinitions;
548
525
  }
549
526
 
550
- /** @internal */
551
- static getAttributeDefinitions() {
552
- return RowNode._attributeDefinitions;
527
+
528
+ // NOTE: flex-grow cannot have values < 1 otherwise will not fill parent, need to normalize
529
+ normalizeWeights() {
530
+ let sum = 0;
531
+ for (const n of this.children) {
532
+ const node = (n as TabSetNode | RowNode);
533
+ sum += node.getWeight();
534
+ }
535
+
536
+ if (sum === 0) {
537
+ sum = 1;
538
+ }
539
+
540
+ for (const n of this.children) {
541
+ const node = (n as TabSetNode | RowNode);
542
+ node.setWeight(Math.max(0.001, 100 * node.getWeight() / sum));
543
+ }
553
544
  }
554
545
 
546
+ /** @internal */
547
+ private static createAttributeDefinitions(): AttributeDefinitions {
548
+ const attributeDefinitions = new AttributeDefinitions();
549
+ attributeDefinitions.add("type", RowNode.TYPE, true).setType(Attribute.STRING).setFixed();
550
+ attributeDefinitions.add("id", undefined).setType(Attribute.STRING).setDescription(
551
+ `the unique id of the row, if left undefined a uuid will be assigned`
552
+ );
553
+ attributeDefinitions.add("weight", 100).setType(Attribute.NUMBER).setDescription(
554
+ `relative weight for sizing of this row in parent row`
555
+ );
556
+
557
+ return attributeDefinitions;
558
+ }
555
559
  }