123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518 |
- /*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /**
- * @constructor
- * @extends {WebInspector.View}
- * @param {boolean} isVertical
- * @param {string=} sidebarSizeSettingName
- * @param {number=} defaultSidebarWidth
- * @param {number=} defaultSidebarHeight
- */
- WebInspector.SplitView = function(isVertical, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight)
- {
- WebInspector.View.call(this);
- this.registerRequiredCSS("splitView.css");
- this.element.className = "split-view";
- this._firstElement = this.element.createChild("div", "split-view-contents scroll-target split-view-contents-first");
- this._secondElement = this.element.createChild("div", "split-view-contents scroll-target split-view-contents-second");
- this._resizerElement = this.element.createChild("div", "split-view-resizer");
- this.installResizer(this._resizerElement);
- this._resizable = true;
- this._savedSidebarWidth = defaultSidebarWidth || 200;
- this._savedSidebarHeight = defaultSidebarHeight || this._savedSidebarWidth;
- if (0 < this._savedSidebarWidth && this._savedSidebarWidth < 1 &&
- 0 < this._savedSidebarHeight && this._savedSidebarHeight < 1)
- this._useFraction = true;
-
- this._sidebarSizeSettingName = sidebarSizeSettingName;
- this.setSecondIsSidebar(true);
- this._innerSetVertical(isVertical);
- }
- WebInspector.SplitView.prototype = {
- /**
- * @return {boolean}
- */
- isVertical: function()
- {
- return this._isVertical;
- },
- /**
- * @param {boolean} isVertical
- */
- setVertical: function(isVertical)
- {
- if (this._isVertical === isVertical)
- return;
- this._innerSetVertical(isVertical);
- if (this.isShowing())
- this._updateLayout();
- },
- /**
- * @param {boolean} isVertical
- */
- _innerSetVertical: function(isVertical)
- {
- this.element.removeStyleClass(this._isVertical ? "split-view-vertical" : "split-view-horizontal");
- this._isVertical = isVertical;
- this.element.addStyleClass(this._isVertical ? "split-view-vertical" : "split-view-horizontal");
- delete this._resizerElementSize;
- this._sidebarSize = -1;
- },
-
- _updateLayout: function()
- {
- delete this._totalSize; // Lazy update.
- this._innerSetSidebarSize(this._lastSidebarSize());
- },
- /**
- * @return {Element}
- */
- firstElement: function()
- {
- return this._firstElement;
- },
- /**
- * @return {Element}
- */
- secondElement: function()
- {
- return this._secondElement;
- },
- /**
- * @return {Element}
- */
- get mainElement()
- {
- return this.isSidebarSecond() ? this.firstElement() : this.secondElement();
- },
- /**
- * @return {Element}
- */
- get sidebarElement()
- {
- return this.isSidebarSecond() ? this.secondElement() : this.firstElement();
- },
- /**
- * @return {boolean}
- */
- isSidebarSecond: function()
- {
- return this._secondIsSidebar;
- },
- /**
- * @param {boolean} secondIsSidebar
- */
- setSecondIsSidebar: function(secondIsSidebar)
- {
- this.sidebarElement.removeStyleClass("split-view-sidebar");
- this._secondIsSidebar = secondIsSidebar;
- this.sidebarElement.addStyleClass("split-view-sidebar");
- },
- /**
- * @return {Element}
- */
- resizerElement: function()
- {
- return this._resizerElement;
- },
- showOnlyFirst: function()
- {
- this._showOnly(this._firstElement, this._secondElement);
- },
- showOnlySecond: function()
- {
- this._showOnly(this._secondElement, this._firstElement);
- },
- /**
- * @param {Element} sideA
- * @param {Element} sideB
- */
- _showOnly: function(sideA, sideB)
- {
- sideA.removeStyleClass("hidden");
- sideA.addStyleClass("maximized");
- sideB.addStyleClass("hidden");
- sideB.removeStyleClass("maximized");
- this._removeAllLayoutProperties();
- this._isShowingOne = true;
- this._sidebarSize = -1;
- this.setResizable(false);
- this.doResize();
- },
- _removeAllLayoutProperties: function()
- {
- this._firstElement.style.removeProperty("right");
- this._firstElement.style.removeProperty("bottom");
- this._firstElement.style.removeProperty("width");
- this._firstElement.style.removeProperty("height");
- this._secondElement.style.removeProperty("left");
- this._secondElement.style.removeProperty("top");
- this._secondElement.style.removeProperty("width");
- this._secondElement.style.removeProperty("height");
- this._resizerElement.style.removeProperty("left");
- this._resizerElement.style.removeProperty("right");
- this._resizerElement.style.removeProperty("top");
- this._resizerElement.style.removeProperty("bottom");
- this._resizerElement.style.removeProperty("margin-left");
- this._resizerElement.style.removeProperty("margin-right");
- this._resizerElement.style.removeProperty("margin-top");
- this._resizerElement.style.removeProperty("margin-bottom");
- },
- showBoth: function()
- {
- this._firstElement.removeStyleClass("hidden");
- this._firstElement.removeStyleClass("maximized");
- this._secondElement.removeStyleClass("hidden");
- this._secondElement.removeStyleClass("maximized");
- this._isShowingOne = false;
- this._sidebarSize = -1;
- this.setResizable(true);
- this.doResize();
- },
- /**
- * @param {boolean} resizable
- */
- setResizable: function(resizable)
- {
- this._resizable = resizable;
- this._resizerElement.enableStyleClass("hidden", !resizable);
- },
- /**
- * @param {number} size
- */
- setSidebarSize: function(size)
- {
- this._innerSetSidebarSize(size);
- this._saveSidebarSize();
- },
- /**
- * @return {number}
- */
- sidebarSize: function()
- {
- return Math.max(0, this._sidebarSize);
- },
- /**
- * @return {number}
- */
- totalSize: function()
- {
- if (!this._totalSize)
- this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight;
- return this._totalSize;
- },
- /**
- * @param {number} size
- */
- _innerSetSidebarSize: function(size)
- {
- if (this._isShowingOne) {
- this._sidebarSize = size;
- return;
- }
- size = this._applyConstraints(size);
- if (this._sidebarSize === size)
- return;
- if (size < 0) {
- // Never apply bad values, fix it upon onResize instead.
- return;
- }
- this._removeAllLayoutProperties();
- var sizeValue;
- if (this._useFraction)
- sizeValue = (size / this.totalSize()) * 100 + "%";
- else
- sizeValue = size + "px";
- if (!this._resizerElementSize)
- this._resizerElementSize = this._isVertical ? this._resizerElement.offsetWidth : this._resizerElement.offsetHeight;
- if (this._isVertical) {
- if (this._secondIsSidebar) {
- this._firstElement.style.right = sizeValue;
- this._secondElement.style.width = sizeValue;
- this._resizerElement.style.right = sizeValue;
- this._resizerElement.style.marginRight = -this._resizerElementSize / 2 + "px";
- } else {
- this._firstElement.style.width = sizeValue;
- this._secondElement.style.left = sizeValue;
- this._resizerElement.style.left = sizeValue;
- this._resizerElement.style.marginLeft = -this._resizerElementSize / 2 + "px";
- }
- } else {
- if (this._secondIsSidebar) {
- this._firstElement.style.bottom = sizeValue;
- this._secondElement.style.height = sizeValue;
- this._resizerElement.style.bottom = sizeValue;
- this._resizerElement.style.marginBottom = -this._resizerElementSize / 2 + "px";
- } else {
- this._firstElement.style.height = sizeValue;
- this._secondElement.style.top = sizeValue;
- this._resizerElement.style.top = sizeValue;
- this._resizerElement.style.marginTop = -this._resizerElementSize / 2 + "px";
- }
- }
- this._sidebarSize = size;
- // No need to recalculate this._sidebarSize and this._totalSize again.
- this._muteOnResize = true;
- this.doResize();
- delete this._muteOnResize;
- },
- /**
- * @param {number=} minWidth
- * @param {number=} minHeight
- */
- setSidebarElementConstraints: function(minWidth, minHeight)
- {
- if (typeof minWidth === "number")
- this._minimumSidebarWidth = minWidth;
- if (typeof minHeight === "number")
- this._minimumSidebarHeight = minHeight;
- },
- /**
- * @param {number=} minWidth
- * @param {number=} minHeight
- */
- setMainElementConstraints: function(minWidth, minHeight)
- {
- if (typeof minWidth === "number")
- this._minimumMainWidth = minWidth;
- if (typeof minHeight === "number")
- this._minimumMainHeight = minHeight;
- },
- /**
- * @param {number} sidebarSize
- * @return {number}
- */
- _applyConstraints: function(sidebarSize)
- {
- const minPadding = 20;
- var totalSize = this.totalSize();
- var from = (this.isVertical() ? this._minimumSidebarWidth : this._minimumSidebarHeight) || 0;
- var fromInPercents = false;
- if (from && from < 1) {
- fromInPercents = true;
- from = Math.round(totalSize * from);
- }
- from = Math.max(from, minPadding);
- var minMainSize = (this.isVertical() ? this._minimumMainWidth : this._minimumMainHeight) || 0;
- var toInPercents = false;
- if (minMainSize && minMainSize < 1) {
- toInPercents = true;
- minMainSize = Math.round(totalSize * minMainSize);
- }
- minMainSize = Math.max(minMainSize, minPadding);
- var to = totalSize - minMainSize;
- if (from <= to)
- return Number.constrain(sidebarSize, from, to);
- // Respect fixed constraints over percents. This will, for example, shrink
- // the sidebar to its minimum size when possible.
- if (!fromInPercents && !toInPercents)
- return -1;
- if (toInPercents && sidebarSize >= from && from < totalSize)
- return from;
- if (fromInPercents && sidebarSize <= to && to < totalSize)
- return to;
- return -1;
- },
- wasShown: function()
- {
- this._updateLayout();
- },
- onResize: function()
- {
- if (this._muteOnResize)
- return;
- this._updateLayout();
- },
- /**
- * @param {Event} event
- * @return {boolean}
- */
- _startResizerDragging: function(event)
- {
- if (!this._resizable)
- return false;
- this._saveSidebarSizeRecursively();
- this._dragOffset = (this._secondIsSidebar ? this.totalSize() - this._sidebarSize : this._sidebarSize) - (this._isVertical ? event.pageX : event.pageY);
- return true;
- },
- /**
- * @param {Event} event
- */
- _resizerDragging: function(event)
- {
- var newOffset = (this._isVertical ? event.pageX : event.pageY) + this._dragOffset;
- var newSize = (this._secondIsSidebar ? this.totalSize() - newOffset : newOffset);
- this.setSidebarSize(newSize);
- event.preventDefault();
- },
- /**
- * @param {Event} event
- */
- _endResizerDragging: function(event)
- {
- delete this._dragOffset;
- this._saveSidebarSizeRecursively();
- },
- _saveSidebarSizeRecursively: function()
- {
- /** @this {WebInspector.View} */
- function doSaveSidebarSizeRecursively()
- {
- if (this._saveSidebarSize)
- this._saveSidebarSize();
- this._callOnVisibleChildren(doSaveSidebarSizeRecursively);
- }
- this._saveSidebarSize();
- this._callOnVisibleChildren(doSaveSidebarSizeRecursively);
- },
- /**
- * @param {Element} resizerElement
- */
- installResizer: function(resizerElement)
- {
- resizerElement.addEventListener("mousedown", this._onDragStart.bind(this), false);
- },
- /**
- *
- * @param {Event} event
- */
- _onDragStart: function(event)
- {
- WebInspector._elementDragStart(this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), this._isVertical ? "ew-resize" : "ns-resize", event);
- },
- /**
- * @return {WebInspector.Setting}
- */
- _sizeSetting: function()
- {
- if (!this._sidebarSizeSettingName)
- return null;
- var settingName = this._sidebarSizeSettingName + (this._isVertical ? "" : "H");
- if (!WebInspector.settings[settingName])
- WebInspector.settings[settingName] = WebInspector.settings.createSetting(settingName, undefined);
- return WebInspector.settings[settingName];
- },
- /**
- * @return {number}
- */
- _lastSidebarSize: function()
- {
- var sizeSetting = this._sizeSetting();
- var size = sizeSetting ? sizeSetting.get() : 0;
- if (!size)
- size = this._isVertical ? this._savedSidebarWidth : this._savedSidebarHeight;
- if (this._useFraction)
- size *= this.totalSize();
- return size;
- },
- _saveSidebarSize: function()
- {
- var size = this._sidebarSize;
- if (size < 0)
- return;
- if (this._useFraction)
- size /= this.totalSize();
- if (this._isVertical)
- this._savedSidebarWidth = size;
- else
- this._savedSidebarHeight = size;
- var sizeSetting = this._sizeSetting();
- if (sizeSetting)
- sizeSetting.set(size);
- },
- __proto__: WebInspector.View.prototype
- }
|