1 | "use strict";
|
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 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | var algorithm_1 = require("@phosphor/algorithm");
|
24 | var domutils_1 = require("@phosphor/domutils");
|
25 | var messaging_1 = require("@phosphor/messaging");
|
26 | var properties_1 = require("@phosphor/properties");
|
27 | var boxengine_1 = require("./boxengine");
|
28 | var layout_1 = require("./layout");
|
29 | var panellayout_1 = require("./panellayout");
|
30 | var widget_1 = require("./widget");
|
31 |
|
32 |
|
33 |
|
34 | var SplitLayout = (function (_super) {
|
35 | __extends(SplitLayout, _super);
|
36 | |
37 |
|
38 |
|
39 |
|
40 |
|
41 | function SplitLayout(options) {
|
42 | var _this = _super.call(this) || this;
|
43 | _this._fixed = 0;
|
44 | _this._spacing = 4;
|
45 | _this._dirty = false;
|
46 | _this._hasNormedSizes = false;
|
47 | _this._sizers = [];
|
48 | _this._items = [];
|
49 | _this._handles = [];
|
50 | _this._box = null;
|
51 | _this._alignment = 'start';
|
52 | _this._orientation = 'horizontal';
|
53 | _this.renderer = options.renderer;
|
54 | if (options.orientation !== undefined) {
|
55 | _this._orientation = options.orientation;
|
56 | }
|
57 | if (options.alignment !== undefined) {
|
58 | _this._alignment = options.alignment;
|
59 | }
|
60 | if (options.spacing !== undefined) {
|
61 | _this._spacing = Private.clampSpacing(options.spacing);
|
62 | }
|
63 | return _this;
|
64 | }
|
65 | |
66 |
|
67 |
|
68 | SplitLayout.prototype.dispose = function () {
|
69 |
|
70 | algorithm_1.each(this._items, function (item) { item.dispose(); });
|
71 |
|
72 | this._box = null;
|
73 | this._items.length = 0;
|
74 | this._sizers.length = 0;
|
75 | this._handles.length = 0;
|
76 |
|
77 | _super.prototype.dispose.call(this);
|
78 | };
|
79 | Object.defineProperty(SplitLayout.prototype, "orientation", {
|
80 | |
81 |
|
82 |
|
83 | get: function () {
|
84 | return this._orientation;
|
85 | },
|
86 | |
87 |
|
88 |
|
89 | set: function (value) {
|
90 | if (this._orientation === value) {
|
91 | return;
|
92 | }
|
93 | this._orientation = value;
|
94 | if (!this.parent) {
|
95 | return;
|
96 | }
|
97 | this.parent.dataset['orientation'] = value;
|
98 | this.parent.fit();
|
99 | },
|
100 | enumerable: true,
|
101 | configurable: true
|
102 | });
|
103 | Object.defineProperty(SplitLayout.prototype, "alignment", {
|
104 | |
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 | get: function () {
|
114 | return this._alignment;
|
115 | },
|
116 | |
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | set: function (value) {
|
126 | if (this._alignment === value) {
|
127 | return;
|
128 | }
|
129 | this._alignment = value;
|
130 | if (!this.parent) {
|
131 | return;
|
132 | }
|
133 | this.parent.dataset['alignment'] = value;
|
134 | this.parent.update();
|
135 | },
|
136 | enumerable: true,
|
137 | configurable: true
|
138 | });
|
139 | Object.defineProperty(SplitLayout.prototype, "spacing", {
|
140 | |
141 |
|
142 |
|
143 | get: function () {
|
144 | return this._spacing;
|
145 | },
|
146 | |
147 |
|
148 |
|
149 | set: function (value) {
|
150 | value = Private.clampSpacing(value);
|
151 | if (this._spacing === value) {
|
152 | return;
|
153 | }
|
154 | this._spacing = value;
|
155 | if (!this.parent) {
|
156 | return;
|
157 | }
|
158 | this.parent.fit();
|
159 | },
|
160 | enumerable: true,
|
161 | configurable: true
|
162 | });
|
163 | Object.defineProperty(SplitLayout.prototype, "handles", {
|
164 | |
165 |
|
166 |
|
167 | get: function () {
|
168 | return this._handles;
|
169 | },
|
170 | enumerable: true,
|
171 | configurable: true
|
172 | });
|
173 | |
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | SplitLayout.prototype.relativeSizes = function () {
|
185 | return Private.normalize(this._sizers.map(function (sizer) { return sizer.size; }));
|
186 | };
|
187 | |
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 | SplitLayout.prototype.setRelativeSizes = function (sizes) {
|
198 |
|
199 | var n = this._sizers.length;
|
200 | var temp = sizes.slice(0, n);
|
201 | while (temp.length < n) {
|
202 | temp.push(0);
|
203 | }
|
204 |
|
205 | var normed = Private.normalize(temp);
|
206 |
|
207 | for (var i = 0; i < n; ++i) {
|
208 | var sizer = this._sizers[i];
|
209 | sizer.sizeHint = normed[i];
|
210 | sizer.size = normed[i];
|
211 | }
|
212 |
|
213 | this._hasNormedSizes = true;
|
214 |
|
215 | if (this.parent) {
|
216 | this.parent.update();
|
217 | }
|
218 | };
|
219 | |
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 | SplitLayout.prototype.moveHandle = function (index, position) {
|
233 |
|
234 | var handle = this._handles[index];
|
235 | if (!handle || handle.classList.contains('p-mod-hidden')) {
|
236 | return;
|
237 | }
|
238 |
|
239 | var delta;
|
240 | if (this._orientation === 'horizontal') {
|
241 | delta = position - handle.offsetLeft;
|
242 | }
|
243 | else {
|
244 | delta = position - handle.offsetTop;
|
245 | }
|
246 |
|
247 | if (delta === 0) {
|
248 | return;
|
249 | }
|
250 |
|
251 | for (var _i = 0, _a = this._sizers; _i < _a.length; _i++) {
|
252 | var sizer = _a[_i];
|
253 | if (sizer.size > 0) {
|
254 | sizer.sizeHint = sizer.size;
|
255 | }
|
256 | }
|
257 |
|
258 | boxengine_1.BoxEngine.adjust(this._sizers, index, delta);
|
259 |
|
260 | if (this.parent) {
|
261 | this.parent.update();
|
262 | }
|
263 | };
|
264 | |
265 |
|
266 |
|
267 | SplitLayout.prototype.init = function () {
|
268 | this.parent.dataset['orientation'] = this.orientation;
|
269 | this.parent.dataset['alignment'] = this.alignment;
|
270 | _super.prototype.init.call(this);
|
271 | };
|
272 | |
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 | SplitLayout.prototype.attachWidget = function (index, widget) {
|
283 |
|
284 | var item = new layout_1.LayoutItem(widget);
|
285 | var handle = Private.createHandle(this.renderer);
|
286 | var average = Private.averageSize(this._sizers);
|
287 | var sizer = Private.createSizer(average);
|
288 |
|
289 | algorithm_1.ArrayExt.insert(this._items, index, item);
|
290 | algorithm_1.ArrayExt.insert(this._sizers, index, sizer);
|
291 | algorithm_1.ArrayExt.insert(this._handles, index, handle);
|
292 |
|
293 | if (this.parent.isAttached) {
|
294 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
|
295 | }
|
296 |
|
297 | this.parent.node.appendChild(widget.node);
|
298 | this.parent.node.appendChild(handle);
|
299 |
|
300 | if (this.parent.isAttached) {
|
301 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
|
302 | }
|
303 |
|
304 | this.parent.fit();
|
305 | };
|
306 | |
307 |
|
308 |
|
309 |
|
310 |
|
311 |
|
312 |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 | SplitLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
|
319 |
|
320 | algorithm_1.ArrayExt.move(this._items, fromIndex, toIndex);
|
321 | algorithm_1.ArrayExt.move(this._sizers, fromIndex, toIndex);
|
322 | algorithm_1.ArrayExt.move(this._handles, fromIndex, toIndex);
|
323 |
|
324 | this.parent.fit();
|
325 | };
|
326 | |
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 | SplitLayout.prototype.detachWidget = function (index, widget) {
|
337 |
|
338 | var item = algorithm_1.ArrayExt.removeAt(this._items, index);
|
339 | var handle = algorithm_1.ArrayExt.removeAt(this._handles, index);
|
340 | algorithm_1.ArrayExt.removeAt(this._sizers, index);
|
341 |
|
342 | if (this.parent.isAttached) {
|
343 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
|
344 | }
|
345 |
|
346 | this.parent.node.removeChild(widget.node);
|
347 | this.parent.node.removeChild(handle);
|
348 |
|
349 | if (this.parent.isAttached) {
|
350 | messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
|
351 | }
|
352 |
|
353 | item.dispose();
|
354 |
|
355 | this.parent.fit();
|
356 | };
|
357 | |
358 |
|
359 |
|
360 | SplitLayout.prototype.onBeforeShow = function (msg) {
|
361 | _super.prototype.onBeforeShow.call(this, msg);
|
362 | this.parent.update();
|
363 | };
|
364 | |
365 |
|
366 |
|
367 | SplitLayout.prototype.onBeforeAttach = function (msg) {
|
368 | _super.prototype.onBeforeAttach.call(this, msg);
|
369 | this.parent.fit();
|
370 | };
|
371 | |
372 |
|
373 |
|
374 | SplitLayout.prototype.onChildShown = function (msg) {
|
375 | this.parent.fit();
|
376 | };
|
377 | |
378 |
|
379 |
|
380 | SplitLayout.prototype.onChildHidden = function (msg) {
|
381 | this.parent.fit();
|
382 | };
|
383 | |
384 |
|
385 |
|
386 | SplitLayout.prototype.onResize = function (msg) {
|
387 | if (this.parent.isVisible) {
|
388 | this._update(msg.width, msg.height);
|
389 | }
|
390 | };
|
391 | |
392 |
|
393 |
|
394 | SplitLayout.prototype.onUpdateRequest = function (msg) {
|
395 | if (this.parent.isVisible) {
|
396 | this._update(-1, -1);
|
397 | }
|
398 | };
|
399 | |
400 |
|
401 |
|
402 | SplitLayout.prototype.onFitRequest = function (msg) {
|
403 | if (this.parent.isAttached) {
|
404 | this._fit();
|
405 | }
|
406 | };
|
407 | |
408 |
|
409 |
|
410 | SplitLayout.prototype._fit = function () {
|
411 |
|
412 | var nVisible = 0;
|
413 | var lastHandleIndex = -1;
|
414 | for (var i = 0, n = this._items.length; i < n; ++i) {
|
415 | if (this._items[i].isHidden) {
|
416 | this._handles[i].classList.add('p-mod-hidden');
|
417 | }
|
418 | else {
|
419 | this._handles[i].classList.remove('p-mod-hidden');
|
420 | lastHandleIndex = i;
|
421 | nVisible++;
|
422 | }
|
423 | }
|
424 |
|
425 | if (lastHandleIndex !== -1) {
|
426 | this._handles[lastHandleIndex].classList.add('p-mod-hidden');
|
427 | }
|
428 |
|
429 | this._fixed = this._spacing * Math.max(0, nVisible - 1);
|
430 |
|
431 | var horz = this._orientation === 'horizontal';
|
432 | var minW = horz ? this._fixed : 0;
|
433 | var minH = horz ? 0 : this._fixed;
|
434 |
|
435 | for (var i = 0, n = this._items.length; i < n; ++i) {
|
436 |
|
437 | var item = this._items[i];
|
438 | var sizer = this._sizers[i];
|
439 |
|
440 | if (sizer.size > 0) {
|
441 | sizer.sizeHint = sizer.size;
|
442 | }
|
443 |
|
444 | if (item.isHidden) {
|
445 | sizer.minSize = 0;
|
446 | sizer.maxSize = 0;
|
447 | continue;
|
448 | }
|
449 |
|
450 | item.fit();
|
451 |
|
452 | sizer.stretch = SplitLayout.getStretch(item.widget);
|
453 |
|
454 | if (horz) {
|
455 | sizer.minSize = item.minWidth;
|
456 | sizer.maxSize = item.maxWidth;
|
457 | minW += item.minWidth;
|
458 | minH = Math.max(minH, item.minHeight);
|
459 | }
|
460 | else {
|
461 | sizer.minSize = item.minHeight;
|
462 | sizer.maxSize = item.maxHeight;
|
463 | minH += item.minHeight;
|
464 | minW = Math.max(minW, item.minWidth);
|
465 | }
|
466 | }
|
467 |
|
468 | var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
|
469 | minW += box.horizontalSum;
|
470 | minH += box.verticalSum;
|
471 |
|
472 | var style = this.parent.node.style;
|
473 | style.minWidth = minW + "px";
|
474 | style.minHeight = minH + "px";
|
475 |
|
476 | this._dirty = true;
|
477 |
|
478 |
|
479 | if (this.parent.parent) {
|
480 | messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
|
481 | }
|
482 |
|
483 |
|
484 | if (this._dirty) {
|
485 | messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
|
486 | }
|
487 | };
|
488 | |
489 |
|
490 |
|
491 |
|
492 |
|
493 | SplitLayout.prototype._update = function (offsetWidth, offsetHeight) {
|
494 |
|
495 | this._dirty = false;
|
496 |
|
497 | var nVisible = 0;
|
498 | for (var i = 0, n = this._items.length; i < n; ++i) {
|
499 | nVisible += +!this._items[i].isHidden;
|
500 | }
|
501 |
|
502 | if (nVisible === 0) {
|
503 | return;
|
504 | }
|
505 |
|
506 | if (offsetWidth < 0) {
|
507 | offsetWidth = this.parent.node.offsetWidth;
|
508 | }
|
509 | if (offsetHeight < 0) {
|
510 | offsetHeight = this.parent.node.offsetHeight;
|
511 | }
|
512 |
|
513 | if (!this._box) {
|
514 | this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
|
515 | }
|
516 |
|
517 | var top = this._box.paddingTop;
|
518 | var left = this._box.paddingLeft;
|
519 | var width = offsetWidth - this._box.horizontalSum;
|
520 | var height = offsetHeight - this._box.verticalSum;
|
521 |
|
522 | var space;
|
523 | var horz = this._orientation === 'horizontal';
|
524 | if (horz) {
|
525 | space = Math.max(0, width - this._fixed);
|
526 | }
|
527 | else {
|
528 | space = Math.max(0, height - this._fixed);
|
529 | }
|
530 |
|
531 | if (this._hasNormedSizes) {
|
532 | for (var _i = 0, _a = this._sizers; _i < _a.length; _i++) {
|
533 | var sizer = _a[_i];
|
534 | sizer.sizeHint *= space;
|
535 | }
|
536 | this._hasNormedSizes = false;
|
537 | }
|
538 |
|
539 | var delta = boxengine_1.BoxEngine.calc(this._sizers, space);
|
540 |
|
541 | var extra = 0;
|
542 | var offset = 0;
|
543 |
|
544 | if (delta > 0) {
|
545 | switch (this._alignment) {
|
546 | case 'start':
|
547 | break;
|
548 | case 'center':
|
549 | extra = 0;
|
550 | offset = delta / 2;
|
551 | break;
|
552 | case 'end':
|
553 | extra = 0;
|
554 | offset = delta;
|
555 | break;
|
556 | case 'justify':
|
557 | extra = delta / nVisible;
|
558 | offset = 0;
|
559 | break;
|
560 | default:
|
561 | throw 'unreachable';
|
562 | }
|
563 | }
|
564 |
|
565 | for (var i = 0, n = this._items.length; i < n; ++i) {
|
566 |
|
567 | var item = this._items[i];
|
568 |
|
569 | if (item.isHidden) {
|
570 | continue;
|
571 | }
|
572 |
|
573 | var size = this._sizers[i].size;
|
574 |
|
575 | var handleStyle = this._handles[i].style;
|
576 |
|
577 | if (horz) {
|
578 | item.update(left + offset, top, size + extra, height);
|
579 | left += size + extra;
|
580 | handleStyle.top = top + "px";
|
581 | handleStyle.left = left + offset + "px";
|
582 | handleStyle.width = this._spacing + "px";
|
583 | handleStyle.height = height + "px";
|
584 | left += this._spacing;
|
585 | }
|
586 | else {
|
587 | item.update(left, top + offset, width, size + extra);
|
588 | top += size + extra;
|
589 | handleStyle.top = top + offset + "px";
|
590 | handleStyle.left = left + "px";
|
591 | handleStyle.width = width + "px";
|
592 | handleStyle.height = this._spacing + "px";
|
593 | top += this._spacing;
|
594 | }
|
595 | }
|
596 | };
|
597 | return SplitLayout;
|
598 | }(panellayout_1.PanelLayout));
|
599 | exports.SplitLayout = SplitLayout;
|
600 |
|
601 |
|
602 |
|
603 | (function (SplitLayout) {
|
604 | |
605 |
|
606 |
|
607 |
|
608 |
|
609 |
|
610 |
|
611 | function getStretch(widget) {
|
612 | return Private.stretchProperty.get(widget);
|
613 | }
|
614 | SplitLayout.getStretch = getStretch;
|
615 | |
616 |
|
617 |
|
618 |
|
619 |
|
620 |
|
621 |
|
622 | function setStretch(widget, value) {
|
623 | Private.stretchProperty.set(widget, value);
|
624 | }
|
625 | SplitLayout.setStretch = setStretch;
|
626 | })(SplitLayout = exports.SplitLayout || (exports.SplitLayout = {}));
|
627 | exports.SplitLayout = SplitLayout;
|
628 |
|
629 |
|
630 |
|
631 | var Private;
|
632 | (function (Private) {
|
633 | |
634 |
|
635 |
|
636 | Private.stretchProperty = new properties_1.AttachedProperty({
|
637 | name: 'stretch',
|
638 | create: function () { return 0; },
|
639 | coerce: function (owner, value) { return Math.max(0, Math.floor(value)); },
|
640 | changed: onChildSizingChanged
|
641 | });
|
642 | |
643 |
|
644 |
|
645 | function createSizer(size) {
|
646 | var sizer = new boxengine_1.BoxSizer();
|
647 | sizer.sizeHint = Math.floor(size);
|
648 | return sizer;
|
649 | }
|
650 | Private.createSizer = createSizer;
|
651 | |
652 |
|
653 |
|
654 | function createHandle(renderer) {
|
655 | var handle = renderer.createHandle();
|
656 | handle.style.position = 'absolute';
|
657 | return handle;
|
658 | }
|
659 | Private.createHandle = createHandle;
|
660 | |
661 |
|
662 |
|
663 | function clampSpacing(value) {
|
664 | return Math.max(0, Math.floor(value));
|
665 | }
|
666 | Private.clampSpacing = clampSpacing;
|
667 | |
668 |
|
669 |
|
670 | function averageSize(sizers) {
|
671 | return sizers.reduce(function (v, s) { return v + s.size; }, 0) / sizers.length || 0;
|
672 | }
|
673 | Private.averageSize = averageSize;
|
674 | |
675 |
|
676 |
|
677 | function normalize(values) {
|
678 | var n = values.length;
|
679 | if (n === 0) {
|
680 | return [];
|
681 | }
|
682 | var sum = values.reduce(function (a, b) { return a + Math.abs(b); }, 0);
|
683 | return sum === 0 ? values.map(function (v) { return 1 / n; }) : values.map(function (v) { return v / sum; });
|
684 | }
|
685 | Private.normalize = normalize;
|
686 | |
687 |
|
688 |
|
689 | function onChildSizingChanged(child) {
|
690 | if (child.parent && child.parent.layout instanceof SplitLayout) {
|
691 | child.parent.fit();
|
692 | }
|
693 | }
|
694 | })(Private || (Private = {}));
|