2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * @extends {WebInspector.View}
32 * @param {string=} sidebarPosition
33 * @param {string=} sidebarWidthSettingName
34 * @param {number=} defaultSidebarWidth
36 WebInspector.SplitView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth)
38 WebInspector.View.call(this);
39 this.registerRequiredCSS("splitView.css");
41 this.element.className = "split-view";
43 this._leftElement = document.createElement("div");
44 this._leftElement.className = "split-view-contents";
45 this.element.appendChild(this._leftElement);
47 this._rightElement = document.createElement("div");
48 this._rightElement.className = "split-view-contents";
49 this.element.appendChild(this._rightElement);
51 this.sidebarResizerElement = document.createElement("div");
52 this.sidebarResizerElement.className = "split-view-resizer";
53 this.installResizer(this.sidebarResizerElement);
54 this._resizable = true;
55 this.element.appendChild(this.sidebarResizerElement);
57 defaultSidebarWidth = defaultSidebarWidth || 200;
58 this._savedSidebarWidth = defaultSidebarWidth;
60 this._sidebarWidthSettingName = sidebarWidthSettingName;
61 if (this._sidebarWidthSettingName)
62 WebInspector.settings[this._sidebarWidthSettingName] = WebInspector.settings.createSetting(this._sidebarWidthSettingName, undefined);
64 this._minimalSidebarWidth = Preferences.minSidebarWidth;
65 this._minimalMainWidth = 0;
66 this._minimalSidebarWidthPercent = 0;
67 this._minimalMainWidthPercent = 50;
69 this._mainElementHidden = false;
70 this._sidebarElementHidden = false;
72 this._innerSetSidebarPosition(sidebarPosition || WebInspector.SplitView.SidebarPosition.Left);
75 WebInspector.SplitView.EventTypes = {
82 WebInspector.SplitView.SidebarPosition = {
87 WebInspector.SplitView.prototype = {
93 return this._sidebarPosition === WebInspector.SplitView.SidebarPosition.Left;
101 return this.hasLeftSidebar ? this._rightElement : this._leftElement;
109 return this.hasLeftSidebar ? this._leftElement : this._rightElement;
117 return this._resizable && !this._mainElementHidden && !this._sidebarElementHidden
123 set resizable(resizable)
125 if (this._resizable === resizable)
127 this._resizable = resizable;
128 this._updateResizer(resizable);
131 _updateResizer: function()
134 this.sidebarResizerElement.removeStyleClass("hidden");
136 this.sidebarResizerElement.addStyleClass("hidden");
142 set sidebarPosition(sidebarPosition)
144 if (this._sidebarPosition === sidebarPosition)
146 this._innerSetSidebarPosition(sidebarPosition);
147 this._restoreSidebarWidth();
151 * @param {string} sidebarPosition
153 _innerSetSidebarPosition: function(sidebarPosition)
155 this._sidebarPosition = sidebarPosition;
157 this._leftElement.style.left = 0;
158 this._rightElement.style.right = 0;
159 if (this.hasLeftSidebar) {
160 this._leftElement.addStyleClass("split-view-sidebar-left");
161 this._rightElement.removeStyleClass("split-view-sidebar-right");
162 this._leftElement.style.removeProperty("right");
163 this._rightElement.style.removeProperty("width");
164 this.sidebarResizerElement.style.removeProperty("right");
166 this._rightElement.addStyleClass("split-view-sidebar-right");
167 this._leftElement.removeStyleClass("split-view-sidebar-left");
168 this._leftElement.style.removeProperty("width");
169 this._rightElement.style.removeProperty("left");
170 this.sidebarResizerElement.style.removeProperty("left");
175 * @param {number} width
177 set minimalSidebarWidth(width)
179 this._minimalSidebarWidth = width;
183 * @param {number} width
185 set minimalMainWidth(width)
187 this._minimalMainWidth = width;
191 * @param {number} widthPercent
193 set minimalSidebarWidthPercent(widthPercent)
195 this._minimalSidebarWidthPercent = widthPercent;
199 * @param {number} widthPercent
201 set minimalMainWidthPercent(widthPercent)
203 this._minimalMainWidthPercent = widthPercent;
207 * @param {number} width
209 setMainWidth: function(width)
211 this.setSidebarWidth(this._totalWidth - width);
215 * @param {number} width
217 setSidebarWidth: function(width)
219 if (this._sidebarWidth === width)
222 this._innerSetSidebarWidth(width);
223 this.saveSidebarWidth();
227 * @param {number} width
229 _innerSetSidebarWidth: function(width)
231 if (this.hasLeftSidebar)
232 this._innerSetLeftSidebarWidth(width);
234 this._innerSetRightSidebarWidth(width);
235 this._sidebarWidth = width;
237 this.dispatchEventToListeners(WebInspector.SplitView.EventTypes.Resized, this._sidebarWidth);
241 * @param {number} width
243 _innerSetLeftSidebarWidth: function(width)
245 this._leftElement.style.width = width + "px";
246 this._rightElement.style.left = width + "px";
247 this.sidebarResizerElement.style.left = (width - 3) + "px";
251 * @param {number} width
253 _innerSetRightSidebarWidth: function(width)
255 this._rightElement.style.width = width + "px";
256 this._leftElement.style.right = width + "px";
257 this.sidebarResizerElement.style.right = (width - 3) + "px";
261 * @param {number} width
263 _setSidebarWidthEnsuringConstraints: function(width)
265 var minWidth = Math.max(this._minimalSidebarWidth, this._totalWidth * this._minimalSidebarWidthPercent);
266 var maxWidth = Math.min(this._totalWidth - this._minimalMainWidth, this._totalWidth * (100 - this._minimalMainWidthPercent) / 100 );
267 width = Number.constrain(width, minWidth, maxWidth);
269 this.setSidebarWidth(width);
272 hideMainElement: function()
274 if (this._mainElementHidden)
277 if (this._sidebarElementHidden)
278 this.showSidebarElement();
280 this.mainElement.addStyleClass("hidden");
281 this.sidebarElement.addStyleClass("maximized");
282 this._mainElementHidden = true;
283 this._updateResizer();
284 this._restoreSidebarWidth();
287 showMainElement: function()
289 if (!this._mainElementHidden)
292 this.mainElement.removeStyleClass("hidden");
293 this.sidebarElement.removeStyleClass("maximized");
294 this._mainElementHidden = false;
295 this._updateResizer();
296 this._restoreSidebarWidth();
299 hideSidebarElement: function()
301 if (this._sidebarElementHidden)
304 if (this._mainElementHidden)
305 this.showMainElement();
307 this.sidebarElement.addStyleClass("hidden");
308 this._sidebarElementHidden = true;
309 this._updateResizer();
310 this._restoreSidebarWidth();
313 showSidebarElement: function()
315 if (!this._sidebarElementHidden)
318 this.sidebarElement.removeStyleClass("hidden");
319 this._sidebarElementHidden = false;
320 this._updateResizer();
321 this._restoreSidebarWidth();
326 this._totalWidth = this.element.offsetWidth;
327 this._restoreSidebarWidth();
332 this._totalWidth = this.element.offsetWidth;
336 * @param {Event} event
338 _startResizerDragging: function(event)
340 if (!this._resizable)
343 var leftWidth = this.hasLeftSidebar ? this._sidebarWidth : this._totalWidth - this._sidebarWidth;
344 this._dragOffset = leftWidth - event.pageX;
346 WebInspector.elementDragStart(this.sidebarResizerElement, this._resizerDragging.bind(this), this._endResizerDragging.bind(this), event, "ew-resize");
350 * @param {Event} event
352 _resizerDragging: function(event)
354 var leftWidth = event.pageX + this._dragOffset
355 var rightWidth = this._totalWidth - leftWidth;
356 var sidebarWidth = this.hasLeftSidebar ? leftWidth : rightWidth;
358 this._setSidebarWidthEnsuringConstraints(sidebarWidth);
359 event.preventDefault();
363 * @param {Event} event
365 _endResizerDragging: function(event)
367 delete this._dragOffset;
368 WebInspector.elementDragEnd(event);
372 * @param {Element} resizerElement
374 installResizer: function(resizerElement)
376 resizerElement.addEventListener("mousedown", this._startResizerDragging.bind(this), false);
382 preferredSidebarWidth: function()
384 if (!this._sidebarWidthSettingName)
385 return this._savedSidebarWidth;
387 return WebInspector.settings[this._sidebarWidthSettingName].get() || this._savedSidebarWidth;
390 _restoreSidebarWidth: function()
392 if (this._mainElementHidden) {
393 this._innerSetSidebarWidth(this._totalWidth);
397 if (this._sidebarElementHidden) {
398 this._innerSetSidebarWidth(0);
402 // Ensure restore satisfies constraints.
403 this._setSidebarWidthEnsuringConstraints(this.preferredSidebarWidth());
406 saveSidebarWidth: function()
408 this._savedSidebarWidth = this._sidebarWidth;
409 if (!this._sidebarWidthSettingName)
412 WebInspector.settings[this._sidebarWidthSettingName].set(this._sidebarWidth);
416 * @return {Array.<Element>}
418 elementsToRestoreScrollPositionsFor: function()
420 return [ this.mainElement, this.sidebarElement ];
424 WebInspector.SplitView.prototype.__proto__ = WebInspector.View.prototype;