 Chromium Code Reviews
 Chromium Code Reviews Issue 2084673003:
  MD Settings: Add display layout  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@issue_547080_display_settings6
    
  
    Issue 2084673003:
  MD Settings: Add display layout  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@issue_547080_display_settings6| OLD | NEW | 
|---|---|
| (Empty) | |
| 1 /** | |
| 2 * @fileoverview Description of this file. | |
| 
michaelpg
2016/06/22 21:57:57
remove
 
stevenjb
2016/06/22 23:38:52
Done.
 | |
| 3 */ | |
| 4 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 5 // Use of this source code is governed by a BSD-style license that can be | |
| 6 // found in the LICENSE file. | |
| 7 | |
| 8 /** | |
| 9 * @fileoverview | |
| 10 * 'display-layout' presents a visual representaiton of the layout of one or | |
| 
michaelpg
2016/06/22 21:57:58
representation
 
stevenjb
2016/06/22 23:38:52
Done.
 | |
| 11 * more displays and allows them to be arranged. | |
| 12 * | |
| 13 * @group Chrome Settings Elements | |
| 
michaelpg
2016/06/22 21:57:57
remove
 
stevenjb
2016/06/22 23:38:52
Done.
 | |
| 14 */ | |
| 15 | |
| 16 (function() { | |
| 17 | |
| 18 /** @const {number} */ var MIN_VISUAL_SCALE = .01; | |
| 19 | |
| 20 Polymer({ | |
| 21 is: 'display-layout', | |
| 22 | |
| 23 behaviors: [ | |
| 24 Polymer.IronResizableBehavior, | |
| 25 ], | |
| 26 | |
| 27 properties: { | |
| 28 /** | |
| 29 * Array of displays. | |
| 30 * @type {!Array<!chrome.system.display.DisplayUnitInfo>} | |
| 31 */ | |
| 32 displays: Array, | |
| 33 | |
| 34 /** | |
| 35 * Array of display layouts. | |
| 36 * @type {!Array<!chrome.system.display.DisplayLayout>} | |
| 37 */ | |
| 38 layouts: Array, | |
| 39 | |
| 40 /** @type {!chrome.system.display.DisplayUnitInfo|undefined} */ | |
| 41 selectedDisplay: Object, | |
| 42 | |
| 43 /** | |
| 44 * The ratio of the DisplayUnitInfo bounds to pixels (visual bounds). | |
| 45 * @type {number} | |
| 46 */ | |
| 47 visualScale: 1, | |
| 48 }, | |
| 49 | |
| 50 observers: ['displaysChanged_(displays, layouts)'], | |
| 51 | |
| 52 /** @type {!Object<chrome.system.display.DisplayUnitInfo>} */ | |
| 
michaelpg
2016/06/22 21:57:57
s/type/private here & below
 
stevenjb
2016/06/22 23:38:52
Done.
 | |
| 53 displayMap_: {}, | |
| 54 | |
| 55 /** @type {!Object<chrome.system.display.DisplayLayout>} */ | |
| 56 layoutMap_: {}, | |
| 57 | |
| 58 /** @type {!Object<chrome.system.display.Bounds>} */ | |
| 59 boundsMap_: {}, | |
| 60 | |
| 61 /** @type {!{left: number, top: number}} */ | |
| 62 visualOffset_: {left: 0, top: 0}, | |
| 63 | |
| 64 /** @override */ | |
| 65 attached: function() { | |
| 66 // TODO(stevenjb): Remove retry once fixed: | |
| 67 // https://github.com/Polymer/polymer/issues/3629 | |
| 68 var self = this; | |
| 69 var retry = 100; // ms | |
| 70 function tryCalcDisplayArea() { | |
| 71 if (!self.calculateDisplayArea_()) | |
| 72 setTimeout(tryCalcDisplayArea, retry); | |
| 73 } | |
| 74 tryCalcDisplayArea(); | |
| 75 }, | |
| 76 | |
| 77 /** @private */ | |
| 78 displaysChanged_: function(displays, layouts) { | |
| 79 this.displayMap_ = {}; | |
| 80 for (let display of this.displays) | |
| 81 this.displayMap_[display.id] = display; | |
| 82 | |
| 83 this.layoutMap_ = {}; | |
| 84 for (var layout of this.layouts) | |
| 
michaelpg
2016/06/22 21:57:57
let, for consistency?
 
stevenjb
2016/06/22 23:38:52
Done.
 | |
| 85 this.layoutMap_[layout.id] = layout; | |
| 86 | |
| 87 this.boundsMap_ = {}; | |
| 88 for (let display of this.displays) | |
| 89 this.calcDisplayBounds_(display); | |
| 90 | |
| 91 this.calculateDisplayArea_(); | |
| 92 }, | |
| 93 | |
| 94 /** | |
| 95 * Calculates the display area offset and scale. | |
| 96 * @return {boolean} Whether the calculation was successful. | |
| 97 * @private | |
| 98 */ | |
| 99 calculateDisplayArea_() { | |
| 
michaelpg
2016/06/22 21:57:58
to clarify: is the "display area" something to do
 
stevenjb
2016/06/22 23:38:52
Renamed calculateVisualScale and tried to improve
 | |
| 100 var displayAreaDiv = this.$.displayArea; | |
| 101 if (!displayAreaDiv || !displayAreaDiv.offsetWidth || !this.displays) | |
| 102 return false; | |
| 103 | |
| 104 var maxWidth = 0; | |
| 105 var maxHeight = 0; | |
| 106 var boundingBox = {left: 0, right: 0, top: 0, bottom: 0}; | |
| 
michaelpg
2016/06/22 21:57:58
The bounding box of what?
 
stevenjb
2016/06/22 23:38:52
Renamed displayInfoBoundingBox (a box bounding all
 | |
| 107 | |
| 108 for (var display of this.displays) { | |
| 109 var bounds = this.boundsMap_[display.id]; | |
| 110 boundingBox.left = Math.min(boundingBox.left, bounds.left); | |
| 
michaelpg
2016/06/22 21:57:58
this ensures boundingBox.left is always 0 or less,
 
stevenjb
2016/06/22 23:38:52
Good catch. In practice the primary display boundi
 | |
| 111 boundingBox.right = | |
| 112 Math.max(boundingBox.right, bounds.left + bounds.width); | |
| 113 boundingBox.top = Math.min(boundingBox.top, bounds.top); | |
| 114 boundingBox.bottom = | |
| 115 Math.max(boundingBox.bottom, bounds.top + bounds.height); | |
| 116 maxWidth = Math.max(maxWidth, bounds.width); | |
| 117 maxHeight = Math.max(maxHeight, bounds.height); | |
| 118 } | |
| 119 | |
| 120 // Create a margin around the bounding box equal to the size of the | |
| 121 // largest display. | |
| 122 var areaWidth = boundingBox.right - boundingBox.left + maxWidth * 2; | |
| 123 var areaHeight = boundingBox.bottom - boundingBox.top + maxHeight * 2; | |
| 124 | |
| 125 // Calculate the scale. | |
| 126 var horizontalScale = displayAreaDiv.offsetWidth / areaWidth; | |
| 127 var verticalScale = displayAreaDiv.offsetHeight / areaHeight; | |
| 128 var scale = Math.min(horizontalScale, verticalScale); | |
| 129 | |
| 130 // Calculate the offset. | |
| 131 this.visualOffset_.left = (-boundingBox.left + maxWidth) * scale; | |
| 132 this.visualOffset_.top = (-boundingBox.top + maxHeight) * scale; | |
| 133 | |
| 134 // Update the scale which will trigger calls to getDivStyle_. | |
| 135 this.visualScale = Math.max(MIN_VISUAL_SCALE, scale); | |
| 136 | |
| 137 return true; | |
| 138 }, | |
| 139 | |
| 140 /** | |
| 141 * @param {!chrome.system.display.DisplayUnitInfo} display | |
| 142 * @param {number} visualScale | |
| 143 * @return {string} The style string for the div. | |
| 144 * @private | |
| 145 */ | |
| 146 getDivStyle_: function(display, visualScale) { | |
| 147 /** @const {number} */ var BORDER = 2; | |
| 148 var bounds = this.boundsMap_[display.id]; | |
| 149 var height = Math.round(bounds.height * this.visualScale) - BORDER * 2; | |
| 150 var width = Math.round(bounds.width * this.visualScale) - BORDER * 2; | |
| 151 var left = | |
| 152 this.visualOffset_.left + Math.round(bounds.left * this.visualScale); | |
| 153 var top = | |
| 154 this.visualOffset_.top + Math.round(bounds.top * this.visualScale); | |
| 155 var style = 'height:' + height + 'px;' + 'width:' + width + 'px;' + | |
| 156 'left:' + left + 'px;' + 'top:' + top + 'px;'; | |
| 157 return style; | |
| 158 }, | |
| 159 | |
| 160 /** | |
| 161 * @param {!chrome.system.display.DisplayUnitInfo} display | |
| 162 * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay | |
| 163 * @return {boolean} | |
| 164 * @private | |
| 165 */ | |
| 166 isSelected_: function(display, selectedDisplay) { | |
| 167 return display.id == selectedDisplay.id; | |
| 168 }, | |
| 169 | |
| 170 /** | |
| 171 * @param {!{model: !{index: number}, target: !PaperButtonElement}} e | |
| 172 * @private | |
| 173 */ | |
| 174 onSelectDisplayTap_: function(e) { | |
| 175 this.fire('select-display', e.model.index); | |
| 176 }, | |
| 177 | |
| 178 /** | |
| 179 * Recursively calculate the bounds of a display relative to its parents. | |
| 180 * Caches the display bounds so that parent bounds are only calculated once. | |
| 181 * TODO(stevenjb): Move this function and the maps it requires to a separate | |
| 182 * behavior which will include snapping and collisions. | |
| 183 * @param {!chrome.system.display.DisplayUnitInfo} display | |
| 184 * @return {!chrome.system.display.Bounds} | |
| 185 * @private | |
| 186 */ | |
| 187 calcDisplayBounds_: function(display) { | |
| 188 var left, top; | |
| 189 if (display.isPrimary) { | |
| 190 left = -display.bounds.width / 2; | |
| 191 top = -display.bounds.height / 2; | |
| 192 } else { | |
| 193 var layout = this.layoutMap_[display.id]; | |
| 194 var parentDisplay = this.displayMap_[layout.parentId]; | |
| 195 var parentBounds; | |
| 196 if (parentDisplay.id in this.boundsMap_) | |
| 197 parentBounds = this.boundsMap_[parentDisplay.id]; | |
| 198 else | |
| 199 parentBounds = this.calcDisplayBounds_(parentDisplay); | |
| 200 left = parentBounds.left; | |
| 201 top = parentBounds.top; | |
| 202 switch (layout.position) { | |
| 203 case chrome.system.display.LayoutPosition.TOP: | |
| 204 top -= display.bounds.height; | |
| 205 break; | |
| 206 case chrome.system.display.LayoutPosition.RIGHT: | |
| 207 left += parentBounds.width; | |
| 208 break; | |
| 209 case chrome.system.display.LayoutPosition.BOTTOM: | |
| 210 top += parentBounds.height; | |
| 211 break; | |
| 212 case chrome.system.display.LayoutPosition.LEFT: | |
| 213 left -= display.bounds.height; | |
| 214 break; | |
| 215 } | |
| 216 } | |
| 217 var result = { | |
| 218 left: left, | |
| 219 top: top, | |
| 220 width: display.bounds.width, | |
| 221 height: display.bounds.height | |
| 222 }; | |
| 223 this.boundsMap_[display.id] = result; | |
| 224 return result; | |
| 225 } | |
| 226 }); | |
| 227 | |
| 228 })(); | |
| OLD | NEW |