| 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 |