1 | ;
|
2 | var __extends = (this && this.__extends) || (function () {
|
3 | var extendStatics = function (d, b) {
|
4 | extendStatics = Object.setPrototypeOf ||
|
5 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
6 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
7 | return extendStatics(d, b);
|
8 | }
|
9 | return function (d, b) {
|
10 | extendStatics(d, b);
|
11 | function __() { this.constructor = d; }
|
12 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
13 | };
|
14 | })();
|
15 | Object.defineProperty(exports, "__esModule", { value: true });
|
16 | /*-----------------------------------------------------------------------------
|
17 | | Copyright (c) 2014-2017, PhosphorJS Contributors
|
18 | |
|
19 | | Distributed under the terms of the BSD 3-Clause License.
|
20 | |
|
21 | | The full license is in the file LICENSE, distributed with this software.
|
22 | |----------------------------------------------------------------------------*/
|
23 | var algorithm_1 = require("@phosphor/algorithm");
|
24 | var messaging_1 = require("@phosphor/messaging");
|
25 | var layout_1 = require("./layout");
|
26 | var widget_1 = require("./widget");
|
27 | /**
|
28 | * A concrete layout implementation suitable for many use cases.
|
29 | *
|
30 | * #### Notes
|
31 | * This class is suitable as a base class for implementing a variety of
|
32 | * layouts, but can also be used directly with standard CSS to layout a
|
33 | * collection of widgets.
|
34 | */
|
35 | var PanelLayout = /** @class */ (function (_super) {
|
36 | __extends(PanelLayout, _super);
|
37 | function PanelLayout() {
|
38 | var _this = _super !== null && _super.apply(this, arguments) || this;
|
39 | _this._widgets = [];
|
40 | return _this;
|
41 | }
|
42 | /**
|
43 | * Dispose of the resources held by the layout.
|
44 | *
|
45 | * #### Notes
|
46 | * This will clear and dispose all widgets in the layout.
|
47 | *
|
48 | * All reimplementations should call the superclass method.
|
49 | *
|
50 | * This method is called automatically when the parent is disposed.
|
51 | */
|
52 | PanelLayout.prototype.dispose = function () {
|
53 | while (this._widgets.length > 0) {
|
54 | this._widgets.pop().dispose();
|
55 | }
|
56 | _super.prototype.dispose.call(this);
|
57 | };
|
58 | Object.defineProperty(PanelLayout.prototype, "widgets", {
|
59 | /**
|
60 | * A read-only array of the widgets in the layout.
|
61 | */
|
62 | get: function () {
|
63 | return this._widgets;
|
64 | },
|
65 | enumerable: true,
|
66 | configurable: true
|
67 | });
|
68 | /**
|
69 | * Create an iterator over the widgets in the layout.
|
70 | *
|
71 | * @returns A new iterator over the widgets in the layout.
|
72 | */
|
73 | PanelLayout.prototype.iter = function () {
|
74 | return algorithm_1.iter(this._widgets);
|
75 | };
|
76 | /**
|
77 | * Add a widget to the end of the layout.
|
78 | *
|
79 | * @param widget - The widget to add to the layout.
|
80 | *
|
81 | * #### Notes
|
82 | * If the widget is already contained in the layout, it will be moved.
|
83 | */
|
84 | PanelLayout.prototype.addWidget = function (widget) {
|
85 | this.insertWidget(this._widgets.length, widget);
|
86 | };
|
87 | /**
|
88 | * Insert a widget into the layout at the specified index.
|
89 | *
|
90 | * @param index - The index at which to insert the widget.
|
91 | *
|
92 | * @param widget - The widget to insert into the layout.
|
93 | *
|
94 | * #### Notes
|
95 | * The index will be clamped to the bounds of the widgets.
|
96 | *
|
97 | * If the widget is already added to the layout, it will be moved.
|
98 | *
|
99 | * #### Undefined Behavior
|
100 | * An `index` which is non-integral.
|
101 | */
|
102 | PanelLayout.prototype.insertWidget = function (index, widget) {
|
103 | // Remove the widget from its current parent. This is a no-op
|
104 | // if the widget's parent is already the layout parent widget.
|
105 | widget.parent = this.parent;
|
106 | // Look up the current index of the widget.
|
107 | var i = this._widgets.indexOf(widget);
|
108 | // Clamp the insert index to the array bounds.
|
109 | var j = Math.max(0, Math.min(index, this._widgets.length));
|
110 | // If the widget is not in the array, insert it.
|
111 | if (i === -1) {
|
112 | // Insert the widget into the array.
|
113 | algorithm_1.ArrayExt.insert(this._widgets, j, widget);
|
114 | // If the layout is parented, attach the widget to the DOM.
|
115 | if (this.parent) {
|
116 | this.attachWidget(j, widget);
|
117 | }
|
118 | // There is nothing more to do.
|
119 | return;
|
120 | }
|
121 | // Otherwise, the widget exists in the array and should be moved.
|
122 | // Adjust the index if the location is at the end of the array.
|
123 | if (j === this._widgets.length) {
|
124 | j--;
|
125 | }
|
126 | // Bail if there is no effective move.
|
127 | if (i === j) {
|
128 | return;
|
129 | }
|
130 | // Move the widget to the new location.
|
131 | algorithm_1.ArrayExt.move(this._widgets, i, j);
|
132 | // If the layout is parented, move the widget in the DOM.
|
133 | if (this.parent) {
|
134 | this.moveWidget(i, j, widget);
|
135 | }
|
136 | };
|
137 | /**
|
138 | * Remove a widget from the layout.
|
139 | *
|
140 | * @param widget - The widget to remove from the layout.
|
141 | *
|
142 | * #### Notes
|
143 | * A widget is automatically removed from the layout when its `parent`
|
144 | * is set to `null`. This method should only be invoked directly when
|
145 | * removing a widget from a layout which has yet to be installed on a
|
146 | * parent widget.
|
147 | *
|
148 | * This method does *not* modify the widget's `parent`.
|
149 | */
|
150 | PanelLayout.prototype.removeWidget = function (widget) {
|
151 | this.removeWidgetAt(this._widgets.indexOf(widget));
|
152 | };
|
153 | /**
|
154 | * Remove the widget at a given index from the layout.
|
155 | *
|
156 | * @param index - The index of the widget to remove.
|
157 | *
|
158 | * #### Notes
|
159 | * A widget is automatically removed from the layout when its `parent`
|
160 | * is set to `null`. This method should only be invoked directly when
|
161 | * removing a widget from a layout which has yet to be installed on a
|
162 | * parent widget.
|
163 | *
|
164 | * This method does *not* modify the widget's `parent`.
|
165 | *
|
166 | * #### Undefined Behavior
|
167 | * An `index` which is non-integral.
|
168 | */
|
169 | PanelLayout.prototype.removeWidgetAt = function (index) {
|
170 | // Remove the widget from the array.
|
171 | var widget = algorithm_1.ArrayExt.removeAt(this._widgets, index);
|
172 | // If the layout is parented, detach the widget from the DOM.
|
173 | if (widget && this.parent) {
|
174 | this.detachWidget(index, widget);
|
175 | }
|
176 | };
|
177 | /**
|
178 | * Perform layout initialization which requires the parent widget.
|
179 | */
|
180 | PanelLayout.prototype.init = function () {
|
181 | var _this = this;
|
182 | _super.prototype.init.call(this);
|
183 | algorithm_1.each(this, function (widget, index) {
|
184 | _this.attachWidget(index, widget);
|
185 | });
|
186 | };
|
187 | /**
|
188 | * Attach a widget to the parent's DOM node.
|
189 | *
|
190 | * @param index - The current index of the widget in the layout.
|
191 | *
|
192 | * @param widget - The widget to attach to the parent.
|
193 | *
|
194 | * #### Notes
|
195 | * This method is called automatically by the panel layout at the
|
196 | * appropriate time. It should not be called directly by user code.
|
197 | *
|
198 | * The default implementation adds the widgets's node to the parent's
|
199 | * node at the proper location, and sends the appropriate attach
|
200 | * messages to the widget if the parent is attached to the DOM.
|
201 | *
|
202 | * Subclasses may reimplement this method to control how the widget's
|
203 | * node is added to the parent's node.
|
204 | */
|
205 | PanelLayout.prototype.attachWidget = function (index, widget) {
|
206 | // Look up the next sibling reference node.
|
207 | var ref = this.parent.node.children[index];
|
208 | // Send a `'before-attach'` message if the parent is attached.
|
209 | if (this.parent.isAttached) {
|
210 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
|
211 | }
|
212 | // Insert the widget's node before the sibling.
|
213 | this.parent.node.insertBefore(widget.node, ref);
|
214 | // Send an `'after-attach'` message if the parent is attached.
|
215 | if (this.parent.isAttached) {
|
216 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
|
217 | }
|
218 | };
|
219 | /**
|
220 | * Move a widget in the parent's DOM node.
|
221 | *
|
222 | * @param fromIndex - The previous index of the widget in the layout.
|
223 | *
|
224 | * @param toIndex - The current index of the widget in the layout.
|
225 | *
|
226 | * @param widget - The widget to move in the parent.
|
227 | *
|
228 | * #### Notes
|
229 | * This method is called automatically by the panel layout at the
|
230 | * appropriate time. It should not be called directly by user code.
|
231 | *
|
232 | * The default implementation moves the widget's node to the proper
|
233 | * location in the parent's node and sends the appropriate attach and
|
234 | * detach messages to the widget if the parent is attached to the DOM.
|
235 | *
|
236 | * Subclasses may reimplement this method to control how the widget's
|
237 | * node is moved in the parent's node.
|
238 | */
|
239 | PanelLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
|
240 | // Send a `'before-detach'` message if the parent is attached.
|
241 | if (this.parent.isAttached) {
|
242 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
|
243 | }
|
244 | // Remove the widget's node from the parent.
|
245 | this.parent.node.removeChild(widget.node);
|
246 | // Send an `'after-detach'` and message if the parent is attached.
|
247 | if (this.parent.isAttached) {
|
248 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
|
249 | }
|
250 | // Look up the next sibling reference node.
|
251 | var ref = this.parent.node.children[toIndex];
|
252 | // Send a `'before-attach'` message if the parent is attached.
|
253 | if (this.parent.isAttached) {
|
254 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
|
255 | }
|
256 | // Insert the widget's node before the sibling.
|
257 | this.parent.node.insertBefore(widget.node, ref);
|
258 | // Send an `'after-attach'` message if the parent is attached.
|
259 | if (this.parent.isAttached) {
|
260 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
|
261 | }
|
262 | };
|
263 | /**
|
264 | * Detach a widget from the parent's DOM node.
|
265 | *
|
266 | * @param index - The previous index of the widget in the layout.
|
267 | *
|
268 | * @param widget - The widget to detach from the parent.
|
269 | *
|
270 | * #### Notes
|
271 | * This method is called automatically by the panel layout at the
|
272 | * appropriate time. It should not be called directly by user code.
|
273 | *
|
274 | * The default implementation removes the widget's node from the
|
275 | * parent's node, and sends the appropriate detach messages to the
|
276 | * widget if the parent is attached to the DOM.
|
277 | *
|
278 | * Subclasses may reimplement this method to control how the widget's
|
279 | * node is removed from the parent's node.
|
280 | */
|
281 | PanelLayout.prototype.detachWidget = function (index, widget) {
|
282 | // Send a `'before-detach'` message if the parent is attached.
|
283 | if (this.parent.isAttached) {
|
284 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
|
285 | }
|
286 | // Remove the widget's node from the parent.
|
287 | this.parent.node.removeChild(widget.node);
|
288 | // Send an `'after-detach'` message if the parent is attached.
|
289 | if (this.parent.isAttached) {
|
290 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
|
291 | }
|
292 | };
|
293 | return PanelLayout;
|
294 | }(layout_1.Layout));
|
295 | exports.PanelLayout = PanelLayout;
|