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

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

Issue 10836046: Allow offset for secondary display position in chrome://settings/display. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('options', function() { 5 cr.define('options', function() {
6 var OptionsPage = options.OptionsPage; 6 var OptionsPage = options.OptionsPage;
7 7
8 // The scale ratio of the display rectangle to its original size. 8 // The scale ratio of the display rectangle to its original size.
9 /** @const */ var VISUAL_SCALE = 1 / 10; 9 /** @const */ var VISUAL_SCALE = 1 / 10;
10 10
11 // The number of pixels to share the edges between displays.
12 /** @const */ var MIN_OFFSET_OVERLAP = 5;
13
11 /** 14 /**
12 * Enumeration of secondary display layout. The value has to be same as the 15 * Enumeration of secondary display layout. The value has to be same as the
13 * values in ash/monitor/monitor_controller.cc. 16 * values in ash/monitor/monitor_controller.cc.
14 * @enum {number} 17 * @enum {number}
15 */ 18 */
16 var SecondaryDisplayLayout = { 19 var SecondaryDisplayLayout = {
17 TOP: 0, 20 TOP: 0,
18 RIGHT: 1, 21 RIGHT: 1,
19 BOTTOM: 2, 22 BOTTOM: 2,
20 LEFT: 3 23 LEFT: 3
21 }; 24 };
22 25
23 /** 26 /**
24 * Encapsulated handling of the 'Display' page. 27 * Encapsulated handling of the 'Display' page.
25 * @constructor 28 * @constructor
26 */ 29 */
27 function DisplayOptions() { 30 function DisplayOptions() {
28 OptionsPage.call(this, 'display', 31 OptionsPage.call(this, 'display',
29 loadTimeData.getString('displayOptionsPageTabTitle'), 32 loadTimeData.getString('displayOptionsPageTabTitle'),
30 'display-options'); 33 'display-options');
31 this.mirroring_ = false; 34 this.mirroring_ = false;
32 this.focused_index_ = null; 35 this.focusedIndex_ = null;
33 this.displays_ = []; 36 this.displays_ = [];
34 } 37 }
35 38
36 cr.addSingletonGetter(DisplayOptions); 39 cr.addSingletonGetter(DisplayOptions);
37 40
38 DisplayOptions.prototype = { 41 DisplayOptions.prototype = {
39 __proto__: OptionsPage.prototype, 42 __proto__: OptionsPage.prototype,
40 43
41 /** 44 /**
42 * Initialize the page. 45 * Initialize the page.
43 */ 46 */
44 initializePage: function() { 47 initializePage: function() {
45 OptionsPage.prototype.initializePage.call(this); 48 OptionsPage.prototype.initializePage.call(this);
46 49
47 $('display-options-toggle-mirroring').onclick = (function() { 50 $('display-options-toggle-mirroring').onclick = (function() {
48 this.mirroring_ = !this.mirroring_; 51 this.mirroring_ = !this.mirroring_;
49 chrome.send('setMirroring', [this.mirroring_]); 52 chrome.send('setMirroring', [this.mirroring_]);
50 }).bind(this); 53 }).bind(this);
51 54
52 $('display-options-apply').onclick = (function() { 55 $('display-options-apply').onclick = this.applyResult_.bind(this);
53 chrome.send('setDisplayLayout', [this.layout_]);
54 }).bind(this);
55 chrome.send('getDisplayInfo'); 56 chrome.send('getDisplayInfo');
56 }, 57 },
57 58
58 /** 59 /**
60 * Collects the current data and sends it to Chrome.
61 * @private
62 */
63 applyResult_: function() {
64 // Offset is calculated from top or left edge.
65 var primary = this.displays_[0];
66 var secondary = this.displays_[1];
67 var offset;
68 if (this.layout_ == SecondaryDisplayLayout.LEFT ||
69 this.layout_ == SecondaryDisplayLayout.RIGHT) {
70 offset = secondary.div.offsetTop - primary.div.offsetTop;
71 } else {
72 offset = secondary.div.offsetLeft - primary.div.offsetLeft;
73 }
74 chrome.send('setDisplayLayout', [this.layout_, offset / VISUAL_SCALE]);
75 },
76
77 /**
59 * Mouse move handler for dragging display rectangle. 78 * Mouse move handler for dragging display rectangle.
60 * @private 79 * @private
61 * @param {Event} e The mouse move event. 80 * @param {Event} e The mouse move event.
62 */ 81 */
63 onMouseMove_: function(e) { 82 onMouseMove_: function(e) {
64 if (!this.dragging_) 83 if (!this.dragging_)
65 return true; 84 return true;
66 85
67 var index = -1; 86 var index = -1;
68 for (var i = 0; i < this.displays_.length; i++) { 87 for (var i = 0; i < this.displays_.length; i++) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 this.updateSelectedDisplayDescription_(); 215 this.updateSelectedDisplayDescription_();
197 return false; 216 return false;
198 }, 217 },
199 218
200 /** 219 /**
201 * Mouse up handler for dragging display rectangle. 220 * Mouse up handler for dragging display rectangle.
202 * @private 221 * @private
203 * @param {Event} e The mouse up event. 222 * @param {Event} e The mouse up event.
204 */ 223 */
205 onMouseUp_: function(e) { 224 onMouseUp_: function(e) {
206 if (this.dragging_) 225 if (this.dragging_) {
226 // Make sure the dragging location is connected.
227 var primaryDiv = this.displays_[0].div;
228 var draggingDiv = this.dragging_.display.div;
229 if (this.layout_ == SecondaryDisplayLayout.LEFT ||
230 this.layout_ == SecondaryDisplayLayout.RIGHT) {
231 var top = Math.max(draggingDiv.offsetTop,
232 primaryDiv.offsetTop - draggingDiv.offsetHeight +
233 MIN_OFFSET_OVERLAP);
234 top = Math.min(top,
235 primaryDiv.offsetTop + primaryDiv.offsetHeight -
236 MIN_OFFSET_OVERLAP);
237 draggingDiv.style.top = top + 'px';
238 } else {
239 var left = Math.max(draggingDiv.offsetLeft,
240 primaryDiv.offsetLeft - draggingDiv.offsetWidth +
241 MIN_OFFSET_OVERLAP);
242 left = Math.min(left,
243 primaryDiv.offsetLeft + primaryDiv.offsetWidth -
244 MIN_OFFSET_OVERLAP);
245 draggingDiv.style.left = left + 'px';
246 }
207 this.dragging_ = null; 247 this.dragging_ = null;
248 }
208 this.updateSelectedDisplayDescription_(); 249 this.updateSelectedDisplayDescription_();
209 return false; 250 return false;
210 }, 251 },
211 252
212 /** 253 /**
213 * Updates the description of the selected display section. 254 * Updates the description of the selected display section.
214 * @private 255 * @private
215 */ 256 */
216 updateSelectedDisplayDescription_: function() { 257 updateSelectedDisplayDescription_: function() {
217 if (this.focusedIndex_ == null || 258 if (this.focusedIndex_ == null ||
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 this.displaysView_.appendChild(div); 342 this.displaysView_.appendChild(div);
302 } 343 }
303 }, 344 },
304 345
305 /** 346 /**
306 * Layouts the display rectangles according to the current layout_. 347 * Layouts the display rectangles according to the current layout_.
307 * @private 348 * @private
308 */ 349 */
309 layoutDisplays_: function() { 350 layoutDisplays_: function() {
310 var totalHeight = 0; 351 var totalHeight = 0;
352 var boundingBox = {left: 0, right: 0, top: 0, bottom: 0};
311 for (var i = 0; i < this.displays_.length; i++) { 353 for (var i = 0; i < this.displays_.length; i++) {
312 totalHeight += this.displays_[i].height * VISUAL_SCALE; 354 var display = this.displays_[i];
355 totalHeight += display.height * VISUAL_SCALE;
356 boundingBox.left = Math.min(boundingBox.left, display.x * VISUAL_SCALE);
357 boundingBox.right = Math.max(
358 boundingBox.right, (display.x + display.width) * VISUAL_SCALE);
359 boundingBox.top = Math.min(boundingBox.top, display.y * VISUAL_SCALE);
360 boundingBox.bottom = Math.max(
361 boundingBox.bottom, (display.y + display.height) * VISUAL_SCALE);
313 } 362 }
314 363
315 // Prepare enough area for thisplays_view by adding the maximum height. 364 // Prepare enough area for thisplays_view by adding the maximum height.
316 this.displaysView_.style.height = totalHeight + 'px'; 365 this.displaysView_.style.height = totalHeight + 'px';
317 366
318 var basePoint = {x: 0, y: 0}; 367 // Centering the bounding box of the display rectangles.
319 var boundingSize = {width: 0, height: 0}; 368 var offset = {x: $('display-options-displays-view').offsetWidth / 2 -
369 (boundingBox.left + boundingBox.right) / 2,
370 y: totalHeight / 2 -
371 (boundingBox.top + boundingBox.bottom) / 2};
372
373
320 for (var i = 0; i < this.displays_.length; i++) { 374 for (var i = 0; i < this.displays_.length; i++) {
321 var display = this.displays_[i]; 375 var display = this.displays_[i];
322 var div = document.createElement('div'); 376 var div = document.createElement('div');
323 display.div = div; 377 display.div = div;
324 378
325 div.className = 'displays-display'; 379 div.className = 'displays-display';
326 if (i == this.focusedIndex_) 380 if (i == this.focusedIndex_)
327 div.classList.add('displays-focused'); 381 div.classList.add('displays-focused');
328 div.style.width = display.width * VISUAL_SCALE + 'px'; 382 div.style.width = display.width * VISUAL_SCALE + 'px';
329 div.style.height = display.height * VISUAL_SCALE + 'px'; 383 div.style.height = display.height * VISUAL_SCALE + 'px';
330 div.style.lineHeight = div.style.height; 384 div.style.lineHeight = div.style.height;
331 if (i == 0) { 385 if (i == 0) {
332 // Assumes that first display is primary and put a grey rectangle to 386 // Assumes that first display is primary and put a grey rectangle to
333 // denote launcher below. 387 // denote launcher below.
334 var launcher = document.createElement('div'); 388 var launcher = document.createElement('div');
335 launcher.id = 'display-launcher'; 389 launcher.id = 'display-launcher';
336 launcher.style.width = display.div.style.width; 390 launcher.style.width = display.div.style.width;
337 div.appendChild(launcher); 391 div.appendChild(launcher);
338 } 392 }
339 switch (this.layout_) { 393 div.style.left = display.x * VISUAL_SCALE + offset.x + 'px';
340 case SecondaryDisplayLayout.RIGHT: 394 div.style.top = display.y * VISUAL_SCALE + offset.y + 'px';
341 display.div.style.top = '0';
342 display.div.style.left = basePoint.x + 'px';
343 basePoint.x += display.width * VISUAL_SCALE;
344 boundingSize.width += display.width * VISUAL_SCALE;
345 boundingSize.height = Math.max(boundingSize.height,
346 display.height * VISUAL_SCALE);
347 break;
348 case SecondaryDisplayLayout.LEFT:
349 display.div.style.top = '0';
350 basePoint.x -= display.width * VISUAL_SCALE;
351 display.div.style.left = basePoint.x + 'px';
352 boundingSize.width += display.width * VISUAL_SCALE;
353 boundingSize.height = Math.max(boundingSize.height,
354 display.height * VISUAL_SCALE);
355 break;
356 case SecondaryDisplayLayout.TOP:
357 display.div.style.left = '0';
358 basePoint.y -= display.height * VISUAL_SCALE;
359 display.div.style.top = basePoint.y + 'px';
360 boundingSize.width = Math.max(boundingSize.width,
361 display.width * VISUAL_SCALE);
362 boundingSize.height += display.height * VISUAL_SCALE;
363 break;
364 case SecondaryDisplayLayout.BOTTOM:
365 display.div.style.left = '0';
366 display.div.style.top = basePoint.y + 'px';
367 basePoint.y += display.height * VISUAL_SCALE;
368 boundingSize.width = Math.max(boundingSize.width,
369 display.width * VISUAL_SCALE);
370 boundingSize.height += display.height * VISUAL_SCALE;
371 break;
372 }
373 395
374 div.appendChild(document.createTextNode(display.name)); 396 div.appendChild(document.createTextNode(display.name));
375 397
376 this.displaysView_.appendChild(div); 398 this.displaysView_.appendChild(div);
377 } 399 }
378
379 // Centering the display rectangles.
380 var offset = {x: $('display-options-displays-view').offsetWidth / 2 -
381 boundingSize.width / 2,
382 y: totalHeight / 2 - boundingSize.height / 2};
383 if (basePoint.x < 0)
384 offset.x -= basePoint.x;
385 if (basePoint.y < 0)
386 offset.y -= basePoint.y;
387 for (var i = 0; i < this.displays_.length; i++) {
388 var div = this.displays_[i].div;
389 div.style.left = div.offsetLeft + offset.x + 'px';
390 div.style.top = div.offsetTop + offset.y + 'px';
391 }
392 }, 400 },
393 401
394 /** 402 /**
395 * Called when the display arrangement has changed. 403 * Called when the display arrangement has changed.
396 * @private 404 * @private
397 * @param {boolean} mirroring Whether current mode is mirroring or not. 405 * @param {boolean} mirroring Whether current mode is mirroring or not.
398 * @param {Array} displays The list of the display information. 406 * @param {Array} displays The list of the display information.
399 * @param {SecondaryDisplayLayout} layout The layout strategy. 407 * @param {SecondaryDisplayLayout} layout The layout strategy.
408 * @param {number} offset The offset of the secondary display.
400 */ 409 */
401 onDisplayChanged_: function(mirroring, displays, layout) { 410 onDisplayChanged_: function(mirroring, displays, layout, offset) {
402 this.mirroring_ = mirroring; 411 this.mirroring_ = mirroring;
403 this.layout_ = layout; 412 this.layout_ = layout;
413 this.offset_ = offset;
404 414
405 $('display-options-toggle-mirroring').textContent = 415 $('display-options-toggle-mirroring').textContent =
406 loadTimeData.getString( 416 loadTimeData.getString(
407 this.mirroring_ ? 'stopMirroring' : 'startMirroring'); 417 this.mirroring_ ? 'stopMirroring' : 'startMirroring');
408 418
409 // Focus to the first display next to the primary one when |displays| list 419 // Focus to the first display next to the primary one when |displays| list
410 // is updated. 420 // is updated.
411 if (this.mirroring_) 421 if (this.mirroring_)
412 this.focusedIndex_ = null; 422 this.focusedIndex_ = null;
413 else if (this.displays_.length != displays.length) 423 else if (this.displays_.length != displays.length)
414 this.focusedIndex_ = 1; 424 this.focusedIndex_ = 1;
415 425
416 this.displays_ = displays; 426 this.displays_ = displays;
417 427
418 this.resetDisplaysView_(); 428 this.resetDisplaysView_();
419 if (this.mirroring_) 429 if (this.mirroring_)
420 this.layoutMirroringDisplays_(); 430 this.layoutMirroringDisplays_();
421 else 431 else
422 this.layoutDisplays_(); 432 this.layoutDisplays_();
423 this.updateSelectedDisplayDescription_(); 433 this.updateSelectedDisplayDescription_();
424 }, 434 },
425 }; 435 };
426 436
427 DisplayOptions.setDisplayInfo = function(mirroring, displays, layout) { 437 DisplayOptions.setDisplayInfo = function(
428 DisplayOptions.getInstance().onDisplayChanged_(mirroring, displays, layout); 438 mirroring, displays, layout, offset) {
439 DisplayOptions.getInstance().onDisplayChanged_(
440 mirroring, displays, layout, offset);
429 }; 441 };
430 442
431 // Export 443 // Export
432 return { 444 return {
433 DisplayOptions: DisplayOptions 445 DisplayOptions: DisplayOptions
434 }; 446 };
435 }); 447 });
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/preferences.cc ('k') | chrome/browser/ui/webui/options2/chromeos/display_options_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698