Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /** | |
| 2 * @fileoverview Description of this file. | |
| 3 */ | |
|
xiyuan
2016/01/28 00:13:35
remove?
stevenjb
2016/01/28 19:58:42
Something in my editor likes to add this but I hav
| |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 4 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 5 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 6 // found in the LICENSE file. |
| 4 | 7 |
| 5 cr.exportPath('options'); | 8 cr.exportPath('options'); |
| 6 | 9 |
| 7 /** | 10 /** |
| 8 * Enumeration of display layout. These values must match the C++ values in | 11 * Enumeration of display layout. These values must match the C++ values in |
| 9 * ash::DisplayController. | 12 * ash::DisplayController. |
| 10 * @enum {number} | 13 * @enum {number} |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 // Prefer the closer one if both edges are close enough. | 101 // Prefer the closer one if both edges are close enough. |
| 99 if (startDiff < SNAP_DISTANCE_PX && startDiff < endDiff) | 102 if (startDiff < SNAP_DISTANCE_PX && startDiff < endDiff) |
| 100 return basePoint; | 103 return basePoint; |
| 101 else if (endDiff < SNAP_DISTANCE_PX) | 104 else if (endDiff < SNAP_DISTANCE_PX) |
| 102 return basePoint + baseWidth - width; | 105 return basePoint + baseWidth - width; |
| 103 | 106 |
| 104 return point; | 107 return point; |
| 105 } | 108 } |
| 106 | 109 |
| 107 /** | 110 /** |
| 108 * @param {number} visualScale | |
| 109 * @constructor | 111 * @constructor |
| 110 */ | 112 */ |
| 111 function DisplayLayoutManager(visualScale) { | 113 function DisplayLayoutManager() { |
| 112 this.visualScale_ = visualScale; | 114 this.displayLayoutMap_ = {}; |
| 115 this.displayAreaOffset_ = {x: 0, y: 0}; | |
| 113 } | 116 } |
| 114 | 117 |
| 115 // Helper class for display layout management. Implements logic for laying | 118 // Helper class for display layout management. Implements logic for laying |
| 116 // out two displays. | 119 // out two displays. |
| 117 DisplayLayoutManager.prototype = { | 120 DisplayLayoutManager.prototype = { |
| 118 /** | 121 /** |
| 119 * An object containing DisplayLayout objects for each entry in | 122 * An object containing DisplayLayout objects for each entry in |
| 120 * |displays_|. | 123 * |displays_|. |
| 121 * @type {!Object<!options.DisplayLayout>} | 124 * @type {?Object<!options.DisplayLayout>} |
| 122 * @private | 125 * @private |
| 123 */ | 126 */ |
| 124 displayLayoutMap_: {}, | 127 displayLayoutMap_: null, |
| 125 | 128 |
| 126 /** | 129 /** |
| 127 * The scale factor of the actual display size to the drawn display | 130 * The scale factor of the actual display size to the drawn display |
| 128 * rectangle size. Set to the correct value for the UI in the constructor. | 131 * rectangle size. Set in calculateDisplayArea_. |
| 129 * @type {number} | 132 * @type {number} |
| 130 * @private | 133 * @private |
| 131 */ | 134 */ |
| 132 visualScale_: 1, | 135 visualScale_: 1, |
| 133 | 136 |
| 134 /** | 137 /** |
| 138 * The offset to the center of the display area div. | |
| 139 * @type {?options.DisplayPosition} | |
| 140 * @private | |
| 141 */ | |
| 142 displayAreaOffset_: null, | |
| 143 | |
| 144 /** | |
| 135 * Adds a display to the layout map. | 145 * Adds a display to the layout map. |
| 136 * @param {options.DisplayLayout} displayLayout | 146 * @param {options.DisplayLayout} displayLayout |
| 137 */ | 147 */ |
| 138 addDisplayLayout: function(displayLayout) { | 148 addDisplayLayout: function(displayLayout) { |
| 139 this.displayLayoutMap_[displayLayout.id] = displayLayout; | 149 this.displayLayoutMap_[displayLayout.id] = displayLayout; |
| 140 }, | 150 }, |
| 141 | 151 |
| 142 /** | 152 /** |
| 143 * Returns the layout type for |id|. | 153 * Returns the display layout for |id|. |
| 144 * @param {string} id | 154 * @param {string} id |
| 145 * @return {options.DisplayLayout} | 155 * @return {options.DisplayLayout} |
| 146 */ | 156 */ |
| 147 getDisplayLayout: function(id) { return this.displayLayoutMap_[id]; }, | 157 getDisplayLayout: function(id) { return this.displayLayoutMap_[id]; }, |
| 148 | 158 |
| 149 /** | 159 /** |
| 150 * Creates a div for each entry in displayLayoutMap_. | 160 * Returns the number of display layout entries. |
| 151 * @param {!Element} parentElement The parent element to contain the divs. | 161 * @return {number} |
| 152 * @param {!options.DisplayPosition} offset The offset to the center of | |
| 153 * the display area. | |
| 154 */ | 162 */ |
| 155 createDisplayLayoutDivs: function(parentElement, offset) { | 163 getDisplayLayoutCount: function() { |
| 164 return Object.keys(/** @type {!Object} */ (this.displayLayoutMap_)) | |
| 165 .length; | |
| 166 }, | |
| 167 | |
| 168 /** | |
| 169 * Returns the display layout corresponding to |div|. | |
| 170 * @param {!HTMLElement} div | |
| 171 * @return {?options.DisplayLayout} | |
| 172 */ | |
| 173 getFocusedLayoutForDiv: function(div) { | |
| 174 for (var id in this.displayLayoutMap_) { | |
| 175 var layout = this.displayLayoutMap_[id]; | |
| 176 if (layout.div == div || | |
| 177 (div.offsetParent && layout.div == div.offsetParent)) { | |
|
xiyuan
2016/01/28 00:13:35
I wonder whether we need to recursively crawl up t
stevenjb
2016/01/28 19:58:42
Noted for the new implementation. For this one, I'
| |
| 178 return layout; | |
| 179 } | |
| 180 } | |
| 181 return null; | |
| 182 }, | |
| 183 | |
| 184 /** | |
| 185 * Sets the display area div size and creates a div for each entry in | |
| 186 * displayLayoutMap_. | |
| 187 * @param {!Element} displayAreaDiv The display area div element. | |
| 188 * @param {number} minVisualScale The minimum visualScale value. | |
| 189 * @return {number} The calculated visual scale. | |
| 190 */ | |
| 191 createDisplayArea: function(displayAreaDiv, minVisualScale) { | |
| 192 this.calculateDisplayArea_(displayAreaDiv, minVisualScale); | |
| 156 for (var id in this.displayLayoutMap_) { | 193 for (var id in this.displayLayoutMap_) { |
| 157 var layout = this.displayLayoutMap_[id]; | 194 var layout = this.displayLayoutMap_[id]; |
| 158 if (layout.div) { | 195 if (layout.div) { |
| 159 // Parent divs must be created before children, so the div for this | 196 // Parent divs must be created before children, so the div for this |
| 160 // entry may have already been created. | 197 // entry may have already been created. |
| 161 continue; | 198 continue; |
| 162 } | 199 } |
| 163 this.createDisplayLayoutDiv_(id, parentElement, offset); | 200 this.createDisplayLayoutDiv_(id, displayAreaDiv); |
| 201 } | |
| 202 return this.visualScale_; | |
| 203 }, | |
| 204 | |
| 205 /** | |
| 206 * Sets the display layout div corresponding to |id| to focused and | |
| 207 * sets all other display layouts to unfocused. | |
| 208 * @param {string} focusedId | |
| 209 */ | |
| 210 setFocusedId: function(focusedId) { | |
| 211 for (var id in this.displayLayoutMap_) { | |
| 212 var layout = this.displayLayoutMap_[id]; | |
| 213 layout.div.classList.toggle('displays-focused', layout.id == focusedId); | |
| 164 } | 214 } |
| 165 }, | 215 }, |
| 166 | 216 |
| 217 /** | |
| 218 * Sets the mouse event callbacks for each div. | |
| 219 * @param {function (Event)} onMouseDown | |
| 220 * @param {function (Event)} onTouchStart | |
| 221 */ | |
| 222 setDivCallbacks: function(onMouseDown, onTouchStart) { | |
| 223 for (var id in this.displayLayoutMap_) { | |
| 224 var layout = this.displayLayoutMap_[id]; | |
| 225 layout.div.onmousedown = onMouseDown; | |
| 226 layout.div.ontouchstart = onTouchStart; | |
| 227 } | |
| 228 }, | |
| 229 | |
| 167 /** | 230 /** |
| 168 * Update the location of display |id| to |newPosition|. | 231 * Update the location of display |id| to |newPosition|. |
| 169 * @param {string} id | 232 * @param {string} id |
| 170 * @param {options.DisplayPosition} newPosition | 233 * @param {options.DisplayPosition} newPosition |
| 171 * @private | 234 * @private |
| 172 */ | 235 */ |
| 173 updatePosition: function(id, newPosition) { | 236 updatePosition: function(id, newPosition) { |
| 174 var displayLayout = this.displayLayoutMap_[id]; | 237 var displayLayout = this.displayLayoutMap_[id]; |
| 175 var div = displayLayout.div; | 238 var div = displayLayout.div; |
| 176 var baseLayout = this.getBaseLayout_(displayLayout); | 239 var baseLayout = this.getBaseLayout_(displayLayout); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 } | 383 } |
| 321 | 384 |
| 322 // Calculate the offset of the child display. | 385 // Calculate the offset of the child display. |
| 323 this.calculateOffset_(isPrimary ? baseLayout : displayLayout); | 386 this.calculateOffset_(isPrimary ? baseLayout : displayLayout); |
| 324 | 387 |
| 325 return displayLayout.originalPosition.x != div.offsetLeft || | 388 return displayLayout.originalPosition.x != div.offsetLeft || |
| 326 displayLayout.originalPosition.y != div.offsetTop; | 389 displayLayout.originalPosition.y != div.offsetTop; |
| 327 }, | 390 }, |
| 328 | 391 |
| 329 /** | 392 /** |
| 393 * Calculates the display area offset and scale. | |
| 394 * @param {!Element} displayAreaDiv The containing display area div. | |
| 395 * @param {number} minVisualScale The minimum visualScale value. | |
| 396 */ | |
| 397 calculateDisplayArea_(displayAreaDiv, minVisualScale) { | |
| 398 var maxWidth = 0; | |
| 399 var maxHeight = 0; | |
| 400 var boundingBox = {left: 0, right: 0, top: 0, bottom: 0}; | |
| 401 | |
| 402 for (var id in this.displayLayoutMap_) { | |
| 403 var layout = this.displayLayoutMap_[id]; | |
| 404 var bounds = layout.bounds; | |
| 405 boundingBox.left = Math.min(boundingBox.left, bounds.left); | |
| 406 boundingBox.right = | |
| 407 Math.max(boundingBox.right, bounds.left + bounds.width); | |
| 408 boundingBox.top = Math.min(boundingBox.top, bounds.top); | |
| 409 boundingBox.bottom = | |
| 410 Math.max(boundingBox.bottom, bounds.top + bounds.height); | |
| 411 maxWidth = Math.max(maxWidth, bounds.width); | |
| 412 maxHeight = Math.max(maxHeight, bounds.height); | |
| 413 } | |
| 414 | |
| 415 // Make the margin around the bounding box. | |
| 416 var areaWidth = boundingBox.right - boundingBox.left + maxWidth; | |
| 417 var areaHeight = boundingBox.bottom - boundingBox.top + maxHeight; | |
| 418 | |
| 419 // Calculates the scale by the width since horizontal size is more strict. | |
| 420 // TODO(mukai): Adds the check of vertical size in case. | |
| 421 this.visualScale_ = | |
| 422 Math.min(minVisualScale, displayAreaDiv.offsetWidth / areaWidth); | |
| 423 | |
| 424 // Prepare enough area for displays_view by adding the maximum height. | |
| 425 displayAreaDiv.style.height = | |
| 426 Math.ceil(areaHeight * this.visualScale_) + 'px'; | |
| 427 | |
| 428 // Centering the bounding box of the display rectangles. | |
| 429 this.displayAreaOffset_ = { | |
| 430 x: Math.floor( | |
| 431 displayAreaDiv.offsetWidth / 2 - | |
| 432 (boundingBox.right + boundingBox.left) * this.visualScale_ / 2), | |
| 433 y: Math.floor( | |
| 434 displayAreaDiv.offsetHeight / 2 - | |
| 435 (boundingBox.bottom + boundingBox.top) * this.visualScale_ / 2) | |
| 436 }; | |
| 437 }, | |
| 438 | |
| 439 /** | |
| 330 * Creates a div element and assigns it to |displayLayout|. Returns the | 440 * Creates a div element and assigns it to |displayLayout|. Returns the |
| 331 * created div for additional decoration. | 441 * created div for additional decoration. |
| 332 * @param {string} id | 442 * @param {string} id |
| 333 * @param {!Element} parentElement The parent element to contain the div. | 443 * @param {!Element} displayAreaDiv The containing display area div. |
| 334 * @param {!options.DisplayPosition} offset The offset to the center of | |
| 335 * the display area. | |
| 336 */ | 444 */ |
| 337 createDisplayLayoutDiv_: function(id, parentElement, offset) { | 445 createDisplayLayoutDiv_: function(id, displayAreaDiv) { |
| 338 var displayLayout = this.displayLayoutMap_[id]; | 446 var displayLayout = this.displayLayoutMap_[id]; |
| 339 var parentId = displayLayout.parentId; | 447 var parentId = displayLayout.parentId; |
| 448 var offset = this.displayAreaOffset_; | |
| 340 if (parentId) { | 449 if (parentId) { |
| 341 // Ensure the parent div is created first. | 450 // Ensure the parent div is created first. |
| 342 var parentLayout = this.displayLayoutMap_[parentId]; | 451 var parentLayout = this.displayLayoutMap_[parentId]; |
| 343 if (!parentLayout.div) | 452 if (!parentLayout.div) |
| 344 this.createDisplayLayoutDiv_(parentId, parentElement, offset); | 453 this.createDisplayLayoutDiv_(parentId, displayAreaDiv); |
| 345 } | 454 } |
| 346 | 455 |
| 347 var div = /** @type {!HTMLElement} */ (document.createElement('div')); | 456 var div = /** @type {!HTMLElement} */ (document.createElement('div')); |
| 348 div.className = 'displays-display'; | 457 div.className = 'displays-display'; |
| 349 | 458 |
| 350 // div needs to be added to the DOM tree first, otherwise offsetHeight for | 459 // div needs to be added to the DOM tree first, otherwise offsetHeight for |
| 351 // nameContainer below cannot be computed. | 460 // nameContainer below cannot be computed. |
| 352 parentElement.appendChild(div); | 461 displayAreaDiv.appendChild(div); |
| 353 | 462 |
| 354 var nameContainer = document.createElement('div'); | 463 var nameContainer = document.createElement('div'); |
| 355 nameContainer.textContent = displayLayout.name; | 464 nameContainer.textContent = displayLayout.name; |
| 356 div.appendChild(nameContainer); | 465 div.appendChild(nameContainer); |
| 357 | 466 |
| 358 var bounds = displayLayout.bounds; | 467 var bounds = displayLayout.bounds; |
| 359 div.style.width = Math.floor(bounds.width * this.visualScale_) + 'px'; | 468 div.style.width = Math.floor(bounds.width * this.visualScale_) + 'px'; |
| 360 var newHeight = Math.floor(bounds.height * this.visualScale_); | 469 var newHeight = Math.floor(bounds.height * this.visualScale_); |
| 361 div.style.height = newHeight + 'px'; | 470 div.style.height = newHeight + 'px'; |
| 362 nameContainer.style.marginTop = | 471 nameContainer.style.marginTop = |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 441 return child; | 550 return child; |
| 442 } | 551 } |
| 443 assertNotReached(); | 552 assertNotReached(); |
| 444 return null; | 553 return null; |
| 445 } | 554 } |
| 446 }; | 555 }; |
| 447 | 556 |
| 448 // Export | 557 // Export |
| 449 return {DisplayLayoutManager: DisplayLayoutManager}; | 558 return {DisplayLayoutManager: DisplayLayoutManager}; |
| 450 }); | 559 }); |
| OLD | NEW |