Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: chrome/browser/resources/options2/chromeos/display_options.js

Issue 10544171: Add OptionsUI and its handler for multiple displays. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 cr.define('options', function() {
6
James Hawkins 2012/06/18 15:13:49 Remove blank line.
Jun Mukai 2012/06/19 08:37:44 Done.
7 var OptionsPage = options.OptionsPage;
8
9 // The scale ratio of the display rectangle to its original size.
10 var VISUAL_SCALE = 1 / 10;
James Hawkins 2012/06/18 15:13:49 /** const */
Jun Mukai 2012/06/19 08:37:44 Done.
11
12 /**
13 * Enumeration of secondary display layout. THe value has to be same as the
James Hawkins 2012/06/18 15:13:49 s/THe/ The/
Jun Mukai 2012/06/19 08:37:44 Done.
14 * values in ash/monitor/monitor_controller.cc.
15 * @enum {number}
16 */
17 var SecondaryDisplayLayout = {
18 TOP: 0,
19 RIGHT: 1,
20 BOTTOM: 2,
21 LEFT: 3
22 };
23
24 /**
25 * Encapsulated handling of the 'Display' page.
26 * @constructor
27 */
28 function DisplayOptions() {
29 OptionsPage.call(this,
James Hawkins 2012/06/18 15:13:49 Collapse parameters to save lines.
Jun Mukai 2012/06/19 08:37:44 Done.
30 'display',
31 loadTimeData.getString('displayOptionsPageTabTitle'),
32 'display-options');
33 this.mirroring_ = false;
34 this.focused_index_ = null;
35 this.displays_ = [];
36 }
37
38 cr.addSingletonGetter(DisplayOptions);
39
40 DisplayOptions.prototype = {
41 __proto__: OptionsPage.prototype,
42
43 /**
44 * Initialize the page.
45 */
46 initializePage: function() {
47 var self = this;
James Hawkins 2012/06/18 15:13:49 Use bind instead of var self.
Jun Mukai 2012/06/19 08:37:44 Done.
48
49 OptionsPage.prototype.initializePage.call(this);
50
51 $('display-options-confirm').onclick = function() {
52 OptionsPage.closeOverlay();
53 };
54
55 $('display-options-toggle-mirroring').onclick = function() {
56 self.mirroring_ = !self.mirroring_;
57 chrome.send('setMirroring', [self.mirroring_]);
58 };
59
60 chrome.send('getDisplayInfo');
61 },
62
63 /**
64 * Mouse move handler for dragging display rectangle.
65 * @private
66 * @param {Event} e The mouse move event.
67 */
68 onMouseMove_: function(e) {
69 if (!this.dragging_)
70 return true;
71
72 var index = -1;
73 for (var i = 0; i < this.displays_.length; i++) {
74 if (this.displays_[i] == this.dragging_.display) {
75 index = i;
76 break;
77 }
78 }
79 if (index < 0)
80 return true;
81
82 // Note that current code of moving display-rectangles doesn't work
83 // if there are >=3 displays. This is our assumption for M21.
84 // TODO(mukai): Fix the code to allow >=3 displays.
85 var mouse_position = {
86 x: e.pageX - this.dragging_.offset.x,
87 y: e.pageY - this.dragging_.offset.y
88 };
89 var new_position = {
90 x: mouse_position.x - this.dragging_.click_location.x,
91 y: mouse_position.y - this.dragging_.click_location.y
92 };
93
94 var primary_div = this.displays_[0].div;
95 var display = this.dragging_.display;
96
97 // Separate the area into four (LEFT/RIGHT/TOP/BOTTOM) by the diagonals of
98 // the primary display, and decide which area the display should reside.
99 var diagonal_slope = primary_div.offsetHeight / primary_div.offsetWidth;
100 var top_down_intercept =
101 primary_div.offsetTop - primary_div.offsetLeft * diagonal_slope;
James Hawkins 2012/06/18 15:13:49 Indentation is off by two.
Jun Mukai 2012/06/19 08:37:44 Done.
102 var bottom_up_intercept = primary_div.offsetTop +
103 primary_div.offsetHeight + primary_div.offsetLeft * diagonal_slope;
James Hawkins 2012/06/18 15:13:49 Indentation is off by two.
Jun Mukai 2012/06/19 08:37:44 Done.
104
105 if (mouse_position.y >
106 top_down_intercept + mouse_position.x * diagonal_slope) {
107 if (mouse_position.y >
108 bottom_up_intercept - mouse_position.x * diagonal_slope)
109 this.layout_ = SecondaryDisplayLayout.BOTTOM;
110 else
111 this.layout_ = SecondaryDisplayLayout.LEFT;
112 } else {
113 if (mouse_position.y >
114 bottom_up_intercept - mouse_position.x * diagonal_slope)
115 this.layout_ = SecondaryDisplayLayout.RIGHT;
116 else
117 this.layout_ = SecondaryDisplayLayout.TOP;
118 }
119
120 if (this.layout_ == SecondaryDisplayLayout.LEFT ||
121 this.layout_ == SecondaryDisplayLayout.RIGHT) {
122 if (new_position.y > primary_div.offsetTop + primary_div.offsetHeight)
123 this.layout_ = SecondaryDisplayLayout.BOTTOM;
124 else if (new_position.y + display.div.offsetHeight <
125 primary_div.offsetTop)
126 this.layout_ = SecondaryDisplayLayout.TOP;
127 } else {
128 if (new_position.y > primary_div.offsetLeft + primary_div.offsetWidth)
129 this.layout_ = SecondaryDisplayLayout.RIGHT;
130 else if (new_position.y + display.div.offsetWidth <
131 primary_div.offstLeft)
132 this.layout_ = SecondaryDisplayLayout.LEFT;
133 }
134
135 switch (this.layout_) {
136 case SecondaryDisplayLayout.RIGHT:
James Hawkins 2012/06/18 15:13:49 Indentation is off by two.
Jun Mukai 2012/06/19 08:37:44 you mean the assignment below? fixed those lines.
137 display.div.style.left =
138 primary_div.offsetLeft + primary_div.offsetWidth + 'px';
139 display.div.style.top = new_position.y + 'px';
140 break;
141 case SecondaryDisplayLayout.LEFT:
142 display.div.style.left =
143 primary_div.offsetLeft - display.div.offsetWidth + 'px';
144 display.div.style.top = new_position.y + 'px';
145 break;
146 case SecondaryDisplayLayout.TOP:
147 display.div.style.top =
148 primary_div.offsetTop - display.div.offsetHeight + 'px';
149 display.div.style.left = new_position.x + 'px';
150 break;
151 case SecondaryDisplayLayout.BOTTOM:
152 display.div.style.top =
153 primary_div.offsetTop + primary_div.offsetHeight + 'px';
154 display.div.style.left = new_position.x + 'px';
155 break;
156 }
157
158 return false;
159 },
160
161 /**
162 * Mouse down handler for dragging display rectangle.
163 * @private
164 * @param {Event} e The mouse down event.
165 */
166 onMouseDown_: function(e) {
167 if (this.mirroring_)
168 return true;
169
170 if (e.button != 0)
171 return true;
172
173 if (e.target == this.displays_view_)
174 return true;
175
176 for (var i = 0; i < this.displays_.length; i++) {
177 var display = this.displays_[i];
178 if (display.div == e.target) {
179 // Do not drag the primary monitor.
180 if (i == 0)
181 return true;
182
183 this.focused_index_ = i;
184 this.dragging_ = {
185 display: display,
186 click_location: {x: e.offsetX, y: e.offsetY},
187 offset: {x: e.pageX - e.offsetX - display.div.offsetLeft,
188 y: e.pageY - e.offsetY - display.div.offsetTop}
189 };
190 if (display.div.className.indexOf('displays-focused') == -1)
191 display.div.className += ' displays-focused';
192 } else if (display.div.className.indexOf('displays-focused') >= 0) {
193 // We can assume that '-primary' monitor doesn't have '-focused'.
194 this.displays_[i].div.className = 'displays-display';
195 }
196 }
197 return false;
198 },
199
200 /**
201 * Mouse up handler for dragging display rectangle.
202 * @private
203 * @param {Event} e The mouse up event.
204 */
205 onMouseUp_: function(e) {
206 if (this.dragging_) {
207 this.dragging_ = null;
208 chrome.send('setDisplayLayout', [this.layout_]);
209 }
210 return false;
211 },
212
213 resetDisplaysView_: function() {
James Hawkins 2012/06/18 15:13:49 Document method.
Jun Mukai 2012/06/19 08:37:44 Done.
214 var displays_view_host = $('display-options-displays-view-host');
215 displays_view_host.removeChild(displays_view_host.firstChild);
216 this.displays_view_ = document.createElement('div');
217 this.displays_view_.id = 'display-options-displays-view';
218 this.displays_view_.onmousemove = this.onMouseMove_.bind(this);
219 this.displays_view_.onmousedown = this.onMouseDown_.bind(this);
220 this.displays_view_.onmouseup = this.onMouseUp_.bind(this);
221 displays_view_host.appendChild(this.displays_view_);
222 },
223
224 /**
225 * Layouts the display rectangles for mirroring.
226 * @private
227 */
228 layoutMirroringDisplays_: function() {
229 // The width/height should be same as the primary display:
230 var width = this.displays_[0].width * VISUAL_SCALE;
231 var height = this.displays_[0].height * VISUAL_SCALE;
232
233 this.displays_view_.style.height =
234 height + this.displays_.length * 2 + 'px';
235
236 for (var i = 0; i < this.displays_.length; i++) {
237 var div = document.createElement('div');
238 this.displays_[i].div = div;
239 div.className = 'displays-display';
240 div.style.top = i * 2 + 'px';
241 div.style.left = i * 2 + 'px';
242 div.style.width = width + 'px';
243 div.style.height = height + 'px';
244 div.style.zIndex = i;
245 if (i == this.displays_.length - 1)
246 div.className += ' displays-primary';
247 this.displays_view_.appendChild(div);
248 }
249 },
250
251 /**
252 * Layouts the display rectangles according to the current layout_.
James Hawkins 2012/06/18 15:13:49 s/Layouts/Lays out/
Jun Mukai 2012/06/19 08:37:44 Done.
253 * @private
254 */
255 layoutDisplays_: function() {
256 var total_size = {width: 0, height: 0};
257 for (var i = 0; i < this.displays_.length; i++) {
258 total_size.width += this.displays_[i].width * VISUAL_SCALE;
259 total_size.height += this.displays_[i].height * VISUAL_SCALE;
260 }
261
262 this.displays_view_.style.width = total_size.width + 'px';
263 this.displays_view_.style.height = total_size.height + 'px';
264
265 var base_point = {x: 0, y: 0};
266 if (this.layout_ == SecondaryDisplayLayout.LEFT)
267 base_point.x = total_size.width;
268 else if (this.layout_ == SecondaryDisplayLayout.TOP)
269 base_point.y = total_size.height;
270
271 for (var i = 0; i < this.displays_.length; i++) {
272 var display = this.displays_[i];
273 var div = document.createElement('div');
274 display.div = div;
275
276 div.className = 'displays-display';
277 if (i == 0)
278 div.className += ' displays-primary';
279 else if (i == this.focused_index_)
280 div.className += ' displays-focused';
281 div.style.width = display.width * VISUAL_SCALE + 'px';
282 div.style.height = display.height * VISUAL_SCALE + 'px';
283 div.style.lineHeight = div.style.height;
284 switch (this.layout_) {
285 case SecondaryDisplayLayout.RIGHT:
286 display.div.style.top = '0';
287 display.div.style.left = base_point.x + 'px';
288 base_point.x += display.width * VISUAL_SCALE;
289 break;
290 case SecondaryDisplayLayout.LEFT:
291 display.div.style.top = '0';
292 base_point.x -= display.width * VISUAL_SCALE;
293 display.div.style.left = base_point.x + 'px';
294 break;
295 case SecondaryDisplayLayout.TOP:
296 display.div.style.left = '0';
297 base_point.y -= display.height * VISUAL_SCALE;
298 display.div.style.top = base_point.y + 'px';
299 break;
300 case SecondaryDisplayLayout.BOTTOM:
301 display.div.style.left = '0';
302 display.div.style.top = base_point.y + 'px';
303 base_point.y += display.height * VISUAL_SCALE;
304 break;
305 }
306
307 this.displays_view_.appendChild(div);
308 }
309 },
310
311 /**
312 * Called when the display arrangement has changed.
313 * @private
314 * @param {boolean} mirroring Whether current mode is mirroring or not.
315 * @param {Array} displays The list of the display information.
316 * @param {SecondaryDisplayLayout} layout The layout strategy.
317 */
318 onDisplayChanged_: function(mirroring, displays, layout) {
319 this.mirroring_ = mirroring;
320 this.layout_ = layout;
321
322 $('display-options-toggle-mirroring').textContent =
323 loadTimeData.getString(
324 this.mirroring_ ? 'stop-mirroring' : 'start-mirroring');
325
326 // Focus to the first display next to the primary one when |displays| list
327 // is updated.
328 if (this.displays_.length != displays.length)
329 this.focused_index_ = 1;
330
331 this.displays_ = displays;
332
333 if (this.displays_.length <= 1)
334 return;
335
336 this.resetDisplaysView_();
337 if (this.mirroring_)
338 this.layoutMirroringDisplays_();
339 else
340 this.layoutDisplays_();
341 },
342 };
343
344 DisplayOptions.setDisplayInfo = function(mirroring, displays, layout) {
345 DisplayOptions.getInstance().onDisplayChanged_(mirroring, displays, layout);
346 };
347
348 // Export
349 return {
350 DisplayOptions: DisplayOptions
351 };
352 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698