OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * | |
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 | |
14 * distribution. | |
15 * | |
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. | |
27 */ | |
28 | |
29 /** | |
30 * @constructor | |
31 * @extends {WebInspector.View} | |
32 * @param {boolean} isVertical | |
33 * @param {boolean} secondIsSidebar | |
34 * @param {string=} settingName | |
35 * @param {number=} defaultSidebarWidth | |
36 * @param {number=} defaultSidebarHeight | |
37 * @param {boolean=} constraintsInDip | |
38 */ | |
39 WebInspector.SplitView = function(isVertical, secondIsSidebar, settingName, defa
ultSidebarWidth, defaultSidebarHeight, constraintsInDip) | |
40 { | |
41 WebInspector.View.call(this, true); | |
42 this.element.classList.add("split-view"); | |
43 this.registerRequiredCSS("ui/splitView.css"); | |
44 | |
45 this.contentElement.classList.add("shadow-split-view"); | |
46 this._mainElement = this.contentElement.createChild("div", "shadow-split-vie
w-contents shadow-split-view-main vbox"); | |
47 this._mainElement.createChild("content").select = ".insertion-point-main"; | |
48 this._sidebarElement = this.contentElement.createChild("div", "shadow-split-
view-contents shadow-split-view-sidebar vbox"); | |
49 this._sidebarElement.createChild("content").select = ".insertion-point-sideb
ar"; | |
50 this._resizerElement = this.contentElement.createChild("div", "shadow-split-
view-resizer"); | |
51 | |
52 this._resizerWidget = new WebInspector.SimpleResizerWidget(); | |
53 this._resizerWidget.setEnabled(true); | |
54 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz
eStart, this._onResizeStart, this); | |
55 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz
eUpdate, this._onResizeUpdate, this); | |
56 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz
eEnd, this._onResizeEnd, this); | |
57 | |
58 this._defaultSidebarWidth = defaultSidebarWidth || 200; | |
59 this._defaultSidebarHeight = defaultSidebarHeight || this._defaultSidebarWid
th; | |
60 this._constraintsInDip = !!constraintsInDip; | |
61 this._setting = settingName ? WebInspector.settings.createSetting(settingNam
e, {}) : null; | |
62 | |
63 this.setSecondIsSidebar(secondIsSidebar); | |
64 | |
65 this._innerSetVertical(isVertical); | |
66 this._showMode = WebInspector.SplitView.ShowMode.Both; | |
67 | |
68 // Should be called after isVertical has the right value. | |
69 this.installResizer(this._resizerElement); | |
70 } | |
71 | |
72 /** @typedef {{showMode: string, size: number}} */ | |
73 WebInspector.SplitView.SettingForOrientation; | |
74 | |
75 WebInspector.SplitView.ShowMode = { | |
76 Both: "Both", | |
77 OnlyMain: "OnlyMain", | |
78 OnlySidebar: "OnlySidebar" | |
79 } | |
80 | |
81 WebInspector.SplitView.Events = { | |
82 SidebarSizeChanged: "SidebarSizeChanged", | |
83 ShowModeChanged: "ShowModeChanged" | |
84 } | |
85 | |
86 WebInspector.SplitView.MinPadding = 20; | |
87 | |
88 WebInspector.SplitView.prototype = { | |
89 /** | |
90 * @return {boolean} | |
91 */ | |
92 isVertical: function() | |
93 { | |
94 return this._isVertical; | |
95 }, | |
96 | |
97 /** | |
98 * @param {boolean} isVertical | |
99 */ | |
100 setVertical: function(isVertical) | |
101 { | |
102 if (this._isVertical === isVertical) | |
103 return; | |
104 | |
105 this._innerSetVertical(isVertical); | |
106 | |
107 if (this.isShowing()) | |
108 this._updateLayout(); | |
109 }, | |
110 | |
111 /** | |
112 * @param {boolean} isVertical | |
113 */ | |
114 _innerSetVertical: function(isVertical) | |
115 { | |
116 this.contentElement.classList.toggle("vbox", !isVertical); | |
117 this.contentElement.classList.toggle("hbox", isVertical); | |
118 this._isVertical = isVertical; | |
119 | |
120 delete this._resizerElementSize; | |
121 this._sidebarSizeDIP = -1; | |
122 this._restoreSidebarSizeFromSettings(); | |
123 if (this._shouldSaveShowMode) | |
124 this._restoreAndApplyShowModeFromSettings(); | |
125 this._updateShowHideSidebarButton(); | |
126 // FIXME: reverse SplitView.isVertical meaning. | |
127 this._resizerWidget.setVertical(!isVertical); | |
128 this.invalidateConstraints(); | |
129 }, | |
130 | |
131 /** | |
132 * @param {boolean=} animate | |
133 */ | |
134 _updateLayout: function(animate) | |
135 { | |
136 delete this._totalSizeCSS; // Lazy update. | |
137 delete this._totalSizeOtherDimensionCSS; | |
138 | |
139 // Remove properties that might affect total size calculation. | |
140 this._mainElement.style.removeProperty("width"); | |
141 this._mainElement.style.removeProperty("height"); | |
142 this._sidebarElement.style.removeProperty("width"); | |
143 this._sidebarElement.style.removeProperty("height"); | |
144 | |
145 this._innerSetSidebarSizeDIP(this._preferredSidebarSizeDIP(), !!animate)
; | |
146 }, | |
147 | |
148 /** | |
149 * @param {!WebInspector.View} view | |
150 */ | |
151 setMainView: function(view) | |
152 { | |
153 if (this._mainView) | |
154 this._mainView.detach(); | |
155 this._mainView = view; | |
156 if (view) { | |
157 view.element.classList.add("insertion-point-main"); | |
158 view.element.classList.remove("insertion-point-sidebar"); | |
159 if (this._showMode === WebInspector.SplitView.ShowMode.OnlyMain || t
his._showMode === WebInspector.SplitView.ShowMode.Both) | |
160 view.show(this.element); | |
161 } | |
162 }, | |
163 | |
164 /** | |
165 * @param {!WebInspector.View} view | |
166 */ | |
167 setSidebarView: function(view) | |
168 { | |
169 if (this._sidebarView) | |
170 this._sidebarView.detach(); | |
171 this._sidebarView = view; | |
172 if (view) { | |
173 view.element.classList.add("insertion-point-sidebar"); | |
174 view.element.classList.remove("insertion-point-main"); | |
175 if (this._showMode === WebInspector.SplitView.ShowMode.OnlySidebar |
| this._showMode === WebInspector.SplitView.ShowMode.Both) | |
176 view.show(this.element); | |
177 } | |
178 }, | |
179 | |
180 /** | |
181 * @return {?WebInspector.View} | |
182 */ | |
183 mainView: function() | |
184 { | |
185 return this._mainView; | |
186 }, | |
187 | |
188 /** | |
189 * @return {?WebInspector.View} | |
190 */ | |
191 sidebarView: function() | |
192 { | |
193 return this._sidebarView; | |
194 }, | |
195 | |
196 /** | |
197 * @override | |
198 * @param {!WebInspector.View} view | |
199 */ | |
200 childWasDetached: function(view) | |
201 { | |
202 if (this._detaching) | |
203 return; | |
204 if (this._mainView === view) | |
205 delete this._mainView; | |
206 if (this._sidebarView === view) | |
207 delete this._sidebarView; | |
208 }, | |
209 | |
210 /** | |
211 * @return {boolean} | |
212 */ | |
213 isSidebarSecond: function() | |
214 { | |
215 return this._secondIsSidebar; | |
216 }, | |
217 | |
218 enableShowModeSaving: function() | |
219 { | |
220 this._shouldSaveShowMode = true; | |
221 this._restoreAndApplyShowModeFromSettings(); | |
222 }, | |
223 | |
224 /** | |
225 * @return {string} | |
226 */ | |
227 showMode: function() | |
228 { | |
229 return this._showMode; | |
230 }, | |
231 | |
232 /** | |
233 * @param {boolean} secondIsSidebar | |
234 */ | |
235 setSecondIsSidebar: function(secondIsSidebar) | |
236 { | |
237 this.contentElement.classList.toggle("shadow-split-view-first-is-sidebar
", !secondIsSidebar); | |
238 this._secondIsSidebar = secondIsSidebar; | |
239 }, | |
240 | |
241 /** | |
242 * @return {?string} | |
243 */ | |
244 sidebarSide: function() | |
245 { | |
246 if (this._showMode !== WebInspector.SplitView.ShowMode.Both) | |
247 return null; | |
248 return this._isVertical ? | |
249 (this._secondIsSidebar ? "right" : "left") : | |
250 (this._secondIsSidebar ? "bottom" : "top"); | |
251 }, | |
252 | |
253 /** | |
254 * @return {!Element} | |
255 */ | |
256 resizerElement: function() | |
257 { | |
258 return this._resizerElement; | |
259 }, | |
260 | |
261 /** | |
262 * @param {boolean=} animate | |
263 */ | |
264 hideMain: function(animate) | |
265 { | |
266 this._showOnly(this._sidebarView, this._mainView, this._sidebarElement,
this._mainElement, animate); | |
267 this._updateShowMode(WebInspector.SplitView.ShowMode.OnlySidebar); | |
268 }, | |
269 | |
270 /** | |
271 * @param {boolean=} animate | |
272 */ | |
273 hideSidebar: function(animate) | |
274 { | |
275 this._showOnly(this._mainView, this._sidebarView, this._mainElement, thi
s._sidebarElement, animate); | |
276 this._updateShowMode(WebInspector.SplitView.ShowMode.OnlyMain); | |
277 }, | |
278 | |
279 /** | |
280 * @param {!WebInspector.View} sideToShow | |
281 * @param {!WebInspector.View} sideToHide | |
282 * @param {!Element} shadowToShow | |
283 * @param {!Element} shadowToHide | |
284 * @param {boolean=} animate | |
285 */ | |
286 _showOnly: function(sideToShow, sideToHide, shadowToShow, shadowToHide, anim
ate) | |
287 { | |
288 this._cancelAnimation(); | |
289 | |
290 /** | |
291 * @this {WebInspector.SplitView} | |
292 */ | |
293 function callback() | |
294 { | |
295 if (sideToShow) { | |
296 // Make sure main is first in the children list. | |
297 if (sideToShow === this._mainView) | |
298 this._mainView.show(this.element, this._sidebarView ? this._
sidebarView.element : null); | |
299 else | |
300 this._sidebarView.show(this.element); | |
301 } | |
302 if (sideToHide) { | |
303 this._detaching = true; | |
304 sideToHide.detach(); | |
305 delete this._detaching; | |
306 } | |
307 | |
308 this._resizerElement.classList.add("hidden"); | |
309 shadowToShow.classList.remove("hidden"); | |
310 shadowToShow.classList.add("maximized"); | |
311 shadowToHide.classList.add("hidden"); | |
312 shadowToHide.classList.remove("maximized"); | |
313 this._removeAllLayoutProperties(); | |
314 this.doResize(); | |
315 } | |
316 | |
317 if (animate) | |
318 this._animate(true, callback.bind(this)); | |
319 else | |
320 callback.call(this); | |
321 | |
322 this._sidebarSizeDIP = -1; | |
323 this.setResizable(false); | |
324 }, | |
325 | |
326 _removeAllLayoutProperties: function() | |
327 { | |
328 this._sidebarElement.style.removeProperty("flexBasis"); | |
329 | |
330 this._mainElement.style.removeProperty("width"); | |
331 this._mainElement.style.removeProperty("height"); | |
332 this._sidebarElement.style.removeProperty("width"); | |
333 this._sidebarElement.style.removeProperty("height"); | |
334 | |
335 this._resizerElement.style.removeProperty("left"); | |
336 this._resizerElement.style.removeProperty("right"); | |
337 this._resizerElement.style.removeProperty("top"); | |
338 this._resizerElement.style.removeProperty("bottom"); | |
339 | |
340 this._resizerElement.style.removeProperty("margin-left"); | |
341 this._resizerElement.style.removeProperty("margin-right"); | |
342 this._resizerElement.style.removeProperty("margin-top"); | |
343 this._resizerElement.style.removeProperty("margin-bottom"); | |
344 }, | |
345 | |
346 /** | |
347 * @param {boolean=} animate | |
348 */ | |
349 showBoth: function(animate) | |
350 { | |
351 if (this._showMode === WebInspector.SplitView.ShowMode.Both) | |
352 animate = false; | |
353 | |
354 this._cancelAnimation(); | |
355 this._mainElement.classList.remove("maximized", "hidden"); | |
356 this._sidebarElement.classList.remove("maximized", "hidden"); | |
357 this._resizerElement.classList.remove("hidden"); | |
358 | |
359 // Make sure main is the first in the children list. | |
360 if (this._sidebarView) | |
361 this._sidebarView.show(this.element); | |
362 if (this._mainView) | |
363 this._mainView.show(this.element, this._sidebarView ? this._sidebarV
iew.element : null); | |
364 // Order views in DOM properly. | |
365 this.setSecondIsSidebar(this._secondIsSidebar); | |
366 | |
367 this._sidebarSizeDIP = -1; | |
368 this.setResizable(true); | |
369 this._updateShowMode(WebInspector.SplitView.ShowMode.Both); | |
370 this._updateLayout(animate); | |
371 }, | |
372 | |
373 /** | |
374 * @param {boolean} resizable | |
375 */ | |
376 setResizable: function(resizable) | |
377 { | |
378 this._resizerWidget.setEnabled(resizable); | |
379 }, | |
380 | |
381 /** | |
382 * @return {boolean} | |
383 */ | |
384 isResizable: function() | |
385 { | |
386 return this._resizerWidget.isEnabled(); | |
387 }, | |
388 | |
389 /** | |
390 * @param {number} size | |
391 */ | |
392 setSidebarSize: function(size) | |
393 { | |
394 var sizeDIP = WebInspector.zoomManager.cssToDIP(size); | |
395 this._savedSidebarSizeDIP = sizeDIP; | |
396 this._saveSetting(); | |
397 this._innerSetSidebarSizeDIP(sizeDIP, false, true); | |
398 }, | |
399 | |
400 /** | |
401 * @return {number} | |
402 */ | |
403 sidebarSize: function() | |
404 { | |
405 var sizeDIP = Math.max(0, this._sidebarSizeDIP); | |
406 return WebInspector.zoomManager.dipToCSS(sizeDIP); | |
407 }, | |
408 | |
409 /** | |
410 * Returns total size in DIP. | |
411 * @return {number} | |
412 */ | |
413 _totalSizeDIP: function() | |
414 { | |
415 if (!this._totalSizeCSS) { | |
416 this._totalSizeCSS = this._isVertical ? this.contentElement.offsetWi
dth : this.contentElement.offsetHeight; | |
417 this._totalSizeOtherDimensionCSS = this._isVertical ? this.contentEl
ement.offsetHeight : this.contentElement.offsetWidth; | |
418 } | |
419 return WebInspector.zoomManager.cssToDIP(this._totalSizeCSS); | |
420 }, | |
421 | |
422 /** | |
423 * @param {string} showMode | |
424 */ | |
425 _updateShowMode: function(showMode) | |
426 { | |
427 this._showMode = showMode; | |
428 this._saveShowModeToSettings(); | |
429 this._updateShowHideSidebarButton(); | |
430 this.dispatchEventToListeners(WebInspector.SplitView.Events.ShowModeChan
ged, showMode); | |
431 this.invalidateConstraints(); | |
432 }, | |
433 | |
434 /** | |
435 * @param {number} sizeDIP | |
436 * @param {boolean} animate | |
437 * @param {boolean=} userAction | |
438 */ | |
439 _innerSetSidebarSizeDIP: function(sizeDIP, animate, userAction) | |
440 { | |
441 if (this._showMode !== WebInspector.SplitView.ShowMode.Both || !this.isS
howing()) | |
442 return; | |
443 | |
444 sizeDIP = this._applyConstraints(sizeDIP, userAction); | |
445 if (this._sidebarSizeDIP === sizeDIP) | |
446 return; | |
447 | |
448 if (!this._resizerElementSize) | |
449 this._resizerElementSize = this._isVertical ? this._resizerElement.o
ffsetWidth : this._resizerElement.offsetHeight; | |
450 | |
451 // Invalidate layout below. | |
452 | |
453 this._removeAllLayoutProperties(); | |
454 | |
455 // this._totalSizeDIP is available below since we successfully applied c
onstraints. | |
456 var sidebarSizeValue = WebInspector.zoomManager.dipToCSS(sizeDIP) + "px"
; | |
457 var mainSizeValue = (this._totalSizeCSS - WebInspector.zoomManager.dipTo
CSS(sizeDIP)) + "px"; | |
458 this._sidebarElement.style.flexBasis = sidebarSizeValue; | |
459 | |
460 // Make both sides relayout boundaries. | |
461 if (this._isVertical) { | |
462 this._sidebarElement.style.width = sidebarSizeValue; | |
463 this._mainElement.style.width = mainSizeValue; | |
464 this._sidebarElement.style.height = this._totalSizeOtherDimensionCSS
+ "px"; | |
465 this._mainElement.style.height = this._totalSizeOtherDimensionCSS +
"px"; | |
466 } else { | |
467 this._sidebarElement.style.height = sidebarSizeValue; | |
468 this._mainElement.style.height = mainSizeValue; | |
469 this._sidebarElement.style.width = this._totalSizeOtherDimensionCSS
+ "px"; | |
470 this._mainElement.style.width = this._totalSizeOtherDimensionCSS + "
px"; | |
471 } | |
472 | |
473 // Position resizer. | |
474 if (this._isVertical) { | |
475 if (this._secondIsSidebar) { | |
476 this._resizerElement.style.right = sidebarSizeValue; | |
477 this._resizerElement.style.marginRight = -this._resizerElementSi
ze / 2 + "px"; | |
478 } else { | |
479 this._resizerElement.style.left = sidebarSizeValue; | |
480 this._resizerElement.style.marginLeft = -this._resizerElementSiz
e / 2 + "px"; | |
481 } | |
482 } else { | |
483 if (this._secondIsSidebar) { | |
484 this._resizerElement.style.bottom = sidebarSizeValue; | |
485 this._resizerElement.style.marginBottom = -this._resizerElementS
ize / 2 + "px"; | |
486 } else { | |
487 this._resizerElement.style.top = sidebarSizeValue; | |
488 this._resizerElement.style.marginTop = -this._resizerElementSize
/ 2 + "px"; | |
489 } | |
490 } | |
491 | |
492 this._sidebarSizeDIP = sizeDIP; | |
493 | |
494 // Force layout. | |
495 | |
496 if (animate) { | |
497 this._animate(false); | |
498 } else { | |
499 // No need to recalculate this._sidebarSizeDIP and this._totalSizeDI
P again. | |
500 this.doResize(); | |
501 this.dispatchEventToListeners(WebInspector.SplitView.Events.SidebarS
izeChanged, this.sidebarSize()); | |
502 } | |
503 }, | |
504 | |
505 /** | |
506 * @param {boolean} reverse | |
507 * @param {function()=} callback | |
508 */ | |
509 _animate: function(reverse, callback) | |
510 { | |
511 var animationTime = 50; | |
512 this._animationCallback = callback; | |
513 | |
514 var animatedMarginPropertyName; | |
515 if (this._isVertical) | |
516 animatedMarginPropertyName = this._secondIsSidebar ? "margin-right"
: "margin-left"; | |
517 else | |
518 animatedMarginPropertyName = this._secondIsSidebar ? "margin-bottom"
: "margin-top"; | |
519 | |
520 var marginFrom = reverse ? "0" : "-" + WebInspector.zoomManager.dipToCSS
(this._sidebarSizeDIP) + "px"; | |
521 var marginTo = reverse ? "-" + WebInspector.zoomManager.dipToCSS(this._s
idebarSizeDIP) + "px" : "0"; | |
522 | |
523 // This order of things is important. | |
524 // 1. Resize main element early and force layout. | |
525 this.contentElement.style.setProperty(animatedMarginPropertyName, margin
From); | |
526 if (!reverse) { | |
527 suppressUnused(this._mainElement.offsetWidth); | |
528 suppressUnused(this._sidebarElement.offsetWidth); | |
529 } | |
530 | |
531 // 2. Issue onresize to the sidebar element, its size won't change. | |
532 if (!reverse) | |
533 this._sidebarView.doResize(); | |
534 | |
535 // 3. Configure and run animation | |
536 this.contentElement.style.setProperty("transition", animatedMarginProper
tyName + " " + animationTime + "ms linear"); | |
537 | |
538 var boundAnimationFrame; | |
539 var startTime; | |
540 /** | |
541 * @this {WebInspector.SplitView} | |
542 */ | |
543 function animationFrame() | |
544 { | |
545 delete this._animationFrameHandle; | |
546 | |
547 if (!startTime) { | |
548 // Kick animation on first frame. | |
549 this.contentElement.style.setProperty(animatedMarginPropertyName
, marginTo); | |
550 startTime = window.performance.now(); | |
551 } else if (window.performance.now() < startTime + animationTime) { | |
552 // Process regular animation frame. | |
553 if (this._mainView) | |
554 this._mainView.doResize(); | |
555 } else { | |
556 // Complete animation. | |
557 this._cancelAnimation(); | |
558 if (this._mainView) | |
559 this._mainView.doResize(); | |
560 this.dispatchEventToListeners(WebInspector.SplitView.Events.Side
barSizeChanged, this.sidebarSize()); | |
561 return; | |
562 } | |
563 this._animationFrameHandle = this.contentElement.window().requestAni
mationFrame(boundAnimationFrame); | |
564 } | |
565 boundAnimationFrame = animationFrame.bind(this); | |
566 this._animationFrameHandle = this.contentElement.window().requestAnimati
onFrame(boundAnimationFrame); | |
567 }, | |
568 | |
569 _cancelAnimation: function() | |
570 { | |
571 this.contentElement.style.removeProperty("margin-top"); | |
572 this.contentElement.style.removeProperty("margin-right"); | |
573 this.contentElement.style.removeProperty("margin-bottom"); | |
574 this.contentElement.style.removeProperty("margin-left"); | |
575 this.contentElement.style.removeProperty("transition"); | |
576 | |
577 if (this._animationFrameHandle) { | |
578 this.contentElement.window().cancelAnimationFrame(this._animationFra
meHandle); | |
579 delete this._animationFrameHandle; | |
580 } | |
581 if (this._animationCallback) { | |
582 this._animationCallback(); | |
583 delete this._animationCallback; | |
584 } | |
585 }, | |
586 | |
587 /** | |
588 * @param {number} sidebarSize | |
589 * @param {boolean=} userAction | |
590 * @return {number} | |
591 */ | |
592 _applyConstraints: function(sidebarSize, userAction) | |
593 { | |
594 var totalSize = this._totalSizeDIP(); | |
595 var zoomFactor = this._constraintsInDip ? 1 : WebInspector.zoomManager.z
oomFactor(); | |
596 | |
597 var constraints = this._sidebarView ? this._sidebarView.constraints() :
new Constraints(); | |
598 var minSidebarSize = this.isVertical() ? constraints.minimum.width : con
straints.minimum.height; | |
599 if (!minSidebarSize) | |
600 minSidebarSize = WebInspector.SplitView.MinPadding; | |
601 minSidebarSize *= zoomFactor; | |
602 | |
603 var preferredSidebarSize = this.isVertical() ? constraints.preferred.wid
th : constraints.preferred.height; | |
604 if (!preferredSidebarSize) | |
605 preferredSidebarSize = WebInspector.SplitView.MinPadding; | |
606 preferredSidebarSize *= zoomFactor; | |
607 // Allow sidebar to be less than preferred by explicit user action. | |
608 if (sidebarSize < preferredSidebarSize) | |
609 preferredSidebarSize = Math.max(sidebarSize, minSidebarSize); | |
610 preferredSidebarSize += zoomFactor; // 1 css pixel for splitter border. | |
611 | |
612 constraints = this._mainView ? this._mainView.constraints() : new Constr
aints(); | |
613 var minMainSize = this.isVertical() ? constraints.minimum.width : constr
aints.minimum.height; | |
614 if (!minMainSize) | |
615 minMainSize = WebInspector.SplitView.MinPadding; | |
616 minMainSize *= zoomFactor; | |
617 | |
618 var preferredMainSize = this.isVertical() ? constraints.preferred.width
: constraints.preferred.height; | |
619 if (!preferredMainSize) | |
620 preferredMainSize = WebInspector.SplitView.MinPadding; | |
621 preferredMainSize *= zoomFactor; | |
622 var savedMainSize = this.isVertical() ? this._savedVerticalMainSize : th
is._savedHorizontalMainSize; | |
623 if (typeof savedMainSize !== "undefined") | |
624 preferredMainSize = Math.min(preferredMainSize, savedMainSize * zoom
Factor); | |
625 if (userAction) | |
626 preferredMainSize = minMainSize; | |
627 | |
628 // Enough space for preferred. | |
629 var totalPreferred = preferredMainSize + preferredSidebarSize; | |
630 if (totalPreferred <= totalSize) | |
631 return Number.constrain(sidebarSize, preferredSidebarSize, totalSize
- preferredMainSize); | |
632 | |
633 // Enough space for minimum. | |
634 if (minMainSize + minSidebarSize <= totalSize) { | |
635 var delta = totalPreferred - totalSize; | |
636 var sidebarDelta = delta * preferredSidebarSize / totalPreferred; | |
637 sidebarSize = preferredSidebarSize - sidebarDelta; | |
638 return Number.constrain(sidebarSize, minSidebarSize, totalSize - min
MainSize); | |
639 } | |
640 | |
641 // Not enough space even for minimum sizes. | |
642 return Math.max(0, totalSize - minMainSize); | |
643 }, | |
644 | |
645 wasShown: function() | |
646 { | |
647 this._forceUpdateLayout(); | |
648 WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Event
s.ZoomChanged, this._onZoomChanged, this); | |
649 }, | |
650 | |
651 willHide: function() | |
652 { | |
653 WebInspector.zoomManager.removeEventListener(WebInspector.ZoomManager.Ev
ents.ZoomChanged, this._onZoomChanged, this); | |
654 }, | |
655 | |
656 onResize: function() | |
657 { | |
658 this._updateLayout(); | |
659 }, | |
660 | |
661 onLayout: function() | |
662 { | |
663 this._updateLayout(); | |
664 }, | |
665 | |
666 /** | |
667 * @override | |
668 * @return {!Constraints} | |
669 */ | |
670 calculateConstraints: function() | |
671 { | |
672 if (this._showMode === WebInspector.SplitView.ShowMode.OnlyMain) | |
673 return this._mainView ? this._mainView.constraints() : new Constrain
ts(); | |
674 if (this._showMode === WebInspector.SplitView.ShowMode.OnlySidebar) | |
675 return this._sidebarView ? this._sidebarView.constraints() : new Con
straints(); | |
676 | |
677 var mainConstraints = this._mainView ? this._mainView.constraints() : ne
w Constraints(); | |
678 var sidebarConstraints = this._sidebarView ? this._sidebarView.constrain
ts() : new Constraints(); | |
679 var min = WebInspector.SplitView.MinPadding; | |
680 if (this._isVertical) { | |
681 mainConstraints = mainConstraints.widthToMax(min).addWidth(1); // 1
for splitter | |
682 sidebarConstraints = sidebarConstraints.widthToMax(min); | |
683 return mainConstraints.addWidth(sidebarConstraints).heightToMax(side
barConstraints); | |
684 } else { | |
685 mainConstraints = mainConstraints.heightToMax(min).addHeight(1); //
1 for splitter | |
686 sidebarConstraints = sidebarConstraints.heightToMax(min); | |
687 return mainConstraints.widthToMax(sidebarConstraints).addHeight(side
barConstraints); | |
688 } | |
689 }, | |
690 | |
691 /** | |
692 * @param {!WebInspector.Event} event | |
693 */ | |
694 _onResizeStart: function(event) | |
695 { | |
696 this._resizeStartSizeDIP = this._sidebarSizeDIP; | |
697 }, | |
698 | |
699 /** | |
700 * @param {!WebInspector.Event} event | |
701 */ | |
702 _onResizeUpdate: function(event) | |
703 { | |
704 var offset = event.data.currentPosition - event.data.startPosition; | |
705 var offsetDIP = WebInspector.zoomManager.cssToDIP(offset); | |
706 var newSizeDIP = this._secondIsSidebar ? this._resizeStartSizeDIP - offs
etDIP : this._resizeStartSizeDIP + offsetDIP; | |
707 var constrainedSizeDIP = this._applyConstraints(newSizeDIP, true); | |
708 this._savedSidebarSizeDIP = constrainedSizeDIP; | |
709 this._saveSetting(); | |
710 this._innerSetSidebarSizeDIP(constrainedSizeDIP, false, true); | |
711 if (this.isVertical()) | |
712 this._savedVerticalMainSize = this._totalSizeDIP() - this._sidebarSi
zeDIP; | |
713 else | |
714 this._savedHorizontalMainSize = this._totalSizeDIP() - this._sidebar
SizeDIP; | |
715 }, | |
716 | |
717 /** | |
718 * @param {!WebInspector.Event} event | |
719 */ | |
720 _onResizeEnd: function(event) | |
721 { | |
722 delete this._resizeStartSizeDIP; | |
723 }, | |
724 | |
725 hideDefaultResizer: function() | |
726 { | |
727 this.uninstallResizer(this._resizerElement); | |
728 }, | |
729 | |
730 /** | |
731 * @param {!Element} resizerElement | |
732 */ | |
733 installResizer: function(resizerElement) | |
734 { | |
735 this._resizerWidget.addElement(resizerElement); | |
736 }, | |
737 | |
738 /** | |
739 * @param {!Element} resizerElement | |
740 */ | |
741 uninstallResizer: function(resizerElement) | |
742 { | |
743 this._resizerWidget.removeElement(resizerElement); | |
744 }, | |
745 | |
746 /** | |
747 * @return {boolean} | |
748 */ | |
749 hasCustomResizer: function() | |
750 { | |
751 var elements = this._resizerWidget.elements(); | |
752 return elements.length > 1 || (elements.length == 1 && elements[0] !== t
his._resizerElement); | |
753 }, | |
754 | |
755 /** | |
756 * @param {!Element} resizer | |
757 * @param {boolean} on | |
758 */ | |
759 toggleResizer: function(resizer, on) | |
760 { | |
761 if (on) | |
762 this.installResizer(resizer); | |
763 else | |
764 this.uninstallResizer(resizer); | |
765 }, | |
766 | |
767 /** | |
768 * @return {?WebInspector.SplitView.SettingForOrientation} | |
769 */ | |
770 _settingForOrientation: function() | |
771 { | |
772 var state = this._setting ? this._setting.get() : {}; | |
773 return this._isVertical ? state.vertical : state.horizontal; | |
774 }, | |
775 | |
776 /** | |
777 * @return {number} | |
778 */ | |
779 _preferredSidebarSizeDIP: function() | |
780 { | |
781 var size = this._savedSidebarSizeDIP; | |
782 if (!size) { | |
783 size = this._isVertical ? this._defaultSidebarWidth : this._defaultS
idebarHeight; | |
784 // If we have default value in percents, calculate it on first use. | |
785 if (0 < size && size < 1) | |
786 size *= this._totalSizeDIP(); | |
787 } | |
788 return size; | |
789 }, | |
790 | |
791 _restoreSidebarSizeFromSettings: function() | |
792 { | |
793 var settingForOrientation = this._settingForOrientation(); | |
794 this._savedSidebarSizeDIP = settingForOrientation ? settingForOrientatio
n.size : 0; | |
795 }, | |
796 | |
797 _restoreAndApplyShowModeFromSettings: function() | |
798 { | |
799 var orientationState = this._settingForOrientation(); | |
800 this._savedShowMode = orientationState && orientationState.showMode ? or
ientationState.showMode : this._showMode; | |
801 this._showMode = this._savedShowMode; | |
802 | |
803 switch (this._savedShowMode) { | |
804 case WebInspector.SplitView.ShowMode.Both: | |
805 this.showBoth(); | |
806 break; | |
807 case WebInspector.SplitView.ShowMode.OnlyMain: | |
808 this.hideSidebar(); | |
809 break; | |
810 case WebInspector.SplitView.ShowMode.OnlySidebar: | |
811 this.hideMain(); | |
812 break; | |
813 } | |
814 }, | |
815 | |
816 _saveShowModeToSettings: function() | |
817 { | |
818 this._savedShowMode = this._showMode; | |
819 this._saveSetting(); | |
820 }, | |
821 | |
822 _saveSetting: function() | |
823 { | |
824 if (!this._setting) | |
825 return; | |
826 var state = this._setting.get(); | |
827 var orientationState = (this._isVertical ? state.vertical : state.horizo
ntal) || {}; | |
828 | |
829 orientationState.size = this._savedSidebarSizeDIP; | |
830 if (this._shouldSaveShowMode) | |
831 orientationState.showMode = this._savedShowMode; | |
832 | |
833 if (this._isVertical) | |
834 state.vertical = orientationState; | |
835 else | |
836 state.horizontal = orientationState; | |
837 this._setting.set(state); | |
838 }, | |
839 | |
840 _forceUpdateLayout: function() | |
841 { | |
842 // Force layout even if sidebar size does not change. | |
843 this._sidebarSizeDIP = -1; | |
844 this._updateLayout(); | |
845 }, | |
846 | |
847 /** | |
848 * @param {!WebInspector.Event} event | |
849 */ | |
850 _onZoomChanged: function(event) | |
851 { | |
852 this._forceUpdateLayout(); | |
853 }, | |
854 | |
855 /** | |
856 * @param {string} title | |
857 * @param {string=} className | |
858 * @return {!Element} | |
859 */ | |
860 displayShowHideSidebarButton: function(title, className) | |
861 { | |
862 console.assert(this.isVertical(), "Buttons for split view with horizonta
l split are not supported yet."); | |
863 | |
864 this._showHideSidebarButtonTitle = WebInspector.UIString(title); | |
865 this._showHideSidebarButton = this._mainElement.createChild("button", "s
idebar-show-hide-button " + (className || "")); | |
866 this._showHideSidebarButton.addEventListener("click", buttonClicked.bind
(this), false); | |
867 this._updateShowHideSidebarButton(); | |
868 | |
869 /** | |
870 * @param {!Event} event | |
871 * @this {WebInspector.SplitView} | |
872 */ | |
873 function buttonClicked(event) | |
874 { | |
875 if (this._showMode !== WebInspector.SplitView.ShowMode.Both) | |
876 this.showBoth(true); | |
877 else | |
878 this.hideSidebar(true); | |
879 } | |
880 | |
881 return this._showHideSidebarButton; | |
882 }, | |
883 | |
884 _updateShowHideSidebarButton: function() | |
885 { | |
886 if (!this._showHideSidebarButton) | |
887 return; | |
888 var sidebarHidden = this._showMode === WebInspector.SplitView.ShowMode.O
nlyMain; | |
889 this._showHideSidebarButton.classList.toggle("toggled-show", sidebarHidd
en); | |
890 this._showHideSidebarButton.classList.toggle("toggled-hide", !sidebarHid
den); | |
891 this._showHideSidebarButton.classList.toggle("top-sidebar-show-hide-butt
on", !this.isVertical() && !this.isSidebarSecond()); | |
892 this._showHideSidebarButton.classList.toggle("right-sidebar-show-hide-bu
tton", this.isVertical() && this.isSidebarSecond()); | |
893 this._showHideSidebarButton.classList.toggle("bottom-sidebar-show-hide-b
utton", !this.isVertical() && this.isSidebarSecond()); | |
894 this._showHideSidebarButton.classList.toggle("left-sidebar-show-hide-but
ton", this.isVertical() && !this.isSidebarSecond()); | |
895 this._showHideSidebarButton.title = sidebarHidden ? WebInspector.UIStrin
g("Show %s", this._showHideSidebarButtonTitle) : WebInspector.UIString("Hide %s"
, this._showHideSidebarButtonTitle); | |
896 }, | |
897 | |
898 __proto__: WebInspector.View.prototype | |
899 } | |
OLD | NEW |