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 |