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