| 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 | 10 |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 */ | 417 */ |
| 418 primaryDisplay_: null, | 418 primaryDisplay_: null, |
| 419 | 419 |
| 420 /** | 420 /** |
| 421 * The secondary display. | 421 * The secondary display. |
| 422 * @private | 422 * @private |
| 423 */ | 423 */ |
| 424 secondaryDisplay_: null, | 424 secondaryDisplay_: null, |
| 425 | 425 |
| 426 /** | 426 /** |
| 427 * The flag to check if the current options status should be sent to the | |
| 428 * system or not (unchanged). | |
| 429 * @private | |
| 430 */ | |
| 431 dirty_: false, | |
| 432 | |
| 433 /** | |
| 434 * The container div element which contains all of the display rectangles. | 427 * The container div element which contains all of the display rectangles. |
| 435 * @private | 428 * @private |
| 436 */ | 429 */ |
| 437 displaysView_: null, | 430 displaysView_: null, |
| 438 | 431 |
| 439 /** | 432 /** |
| 440 * The scale factor of the actual display size to the drawn display | 433 * The scale factor of the actual display size to the drawn display |
| 441 * rectangle size. | 434 * rectangle size. |
| 442 * @private | 435 * @private |
| 443 */ | 436 */ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 457 initializePage: function() { | 450 initializePage: function() { |
| 458 OptionsPage.prototype.initializePage.call(this); | 451 OptionsPage.prototype.initializePage.call(this); |
| 459 | 452 |
| 460 $('display-options-toggle-mirroring').onclick = (function() { | 453 $('display-options-toggle-mirroring').onclick = (function() { |
| 461 this.mirroring_ = !this.mirroring_; | 454 this.mirroring_ = !this.mirroring_; |
| 462 chrome.send('setMirroring', [this.mirroring_]); | 455 chrome.send('setMirroring', [this.mirroring_]); |
| 463 }).bind(this); | 456 }).bind(this); |
| 464 | 457 |
| 465 var container = $('display-options-displays-view-host'); | 458 var container = $('display-options-displays-view-host'); |
| 466 container.onmousemove = this.onMouseMove_.bind(this); | 459 container.onmousemove = this.onMouseMove_.bind(this); |
| 467 container.onmouseup = this.endDragging_.bind(this); | 460 window.addEventListener('mouseup', this.endDragging_.bind(this), true); |
| 468 container.ontouchmove = this.onTouchMove_.bind(this); | 461 container.ontouchmove = this.onTouchMove_.bind(this); |
| 469 container.ontouchend = this.endDragging_.bind(this); | 462 container.ontouchend = this.endDragging_.bind(this); |
| 470 | 463 |
| 471 $('display-options-set-primary').onclick = (function() { | 464 $('display-options-set-primary').onclick = (function() { |
| 472 chrome.send('setPrimary', [this.displays_[this.focusedIndex_].id]); | 465 chrome.send('setPrimary', [this.displays_[this.focusedIndex_].id]); |
| 473 }).bind(this); | 466 }).bind(this); |
| 474 | 467 |
| 475 $('selected-display-start-calibrating-overscan').onclick = (function() { | 468 $('selected-display-start-calibrating-overscan').onclick = (function() { |
| 476 this.overscanCalibrator_ = new DisplayOverscanCalibrator( | 469 this.overscanCalibrator_ = new DisplayOverscanCalibrator( |
| 477 this.displays_[this.focusedIndex_]); | 470 this.displays_[this.focusedIndex_]); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 var secondary = this.secondaryDisplay_; | 570 var secondary = this.secondaryDisplay_; |
| 578 var offset; | 571 var offset; |
| 579 if (this.layout_ == SecondaryDisplayLayout.LEFT || | 572 if (this.layout_ == SecondaryDisplayLayout.LEFT || |
| 580 this.layout_ == SecondaryDisplayLayout.RIGHT) { | 573 this.layout_ == SecondaryDisplayLayout.RIGHT) { |
| 581 offset = secondary.div.offsetTop - primary.div.offsetTop; | 574 offset = secondary.div.offsetTop - primary.div.offsetTop; |
| 582 } else { | 575 } else { |
| 583 offset = secondary.div.offsetLeft - primary.div.offsetLeft; | 576 offset = secondary.div.offsetLeft - primary.div.offsetLeft; |
| 584 } | 577 } |
| 585 chrome.send('setDisplayLayout', | 578 chrome.send('setDisplayLayout', |
| 586 [this.layout_, offset / this.visualScale_]); | 579 [this.layout_, offset / this.visualScale_]); |
| 587 this.dirty_ = false; | |
| 588 }, | 580 }, |
| 589 | 581 |
| 590 /** | 582 /** |
| 591 * Snaps the region [point, width] to [basePoint, baseWidth] if | 583 * Snaps the region [point, width] to [basePoint, baseWidth] if |
| 592 * the [point, width] is close enough to the base's edge. | 584 * the [point, width] is close enough to the base's edge. |
| 593 * @param {number} point The starting point of the region. | 585 * @param {number} point The starting point of the region. |
| 594 * @param {number} width The width of the region. | 586 * @param {number} width The width of the region. |
| 595 * @param {number} basePoint The starting point of the base region. | 587 * @param {number} basePoint The starting point of the base region. |
| 596 * @param {number} baseWidth The width of the base region. | 588 * @param {number} baseWidth The width of the base region. |
| 597 * @return {number} The moved point. Returns point itself if it doesn't | 589 * @return {number} The moved point. Returns point itself if it doesn't |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 baseDiv.offsetTop - draggingDiv.offsetHeight + 'px'; | 732 baseDiv.offsetTop - draggingDiv.offsetHeight + 'px'; |
| 741 draggingDiv.style.left = newPosition.x + 'px'; | 733 draggingDiv.style.left = newPosition.x + 'px'; |
| 742 break; | 734 break; |
| 743 case SecondaryDisplayLayout.BOTTOM: | 735 case SecondaryDisplayLayout.BOTTOM: |
| 744 draggingDiv.style.top = | 736 draggingDiv.style.top = |
| 745 baseDiv.offsetTop + baseDiv.offsetHeight + 'px'; | 737 baseDiv.offsetTop + baseDiv.offsetHeight + 'px'; |
| 746 draggingDiv.style.left = newPosition.x + 'px'; | 738 draggingDiv.style.left = newPosition.x + 'px'; |
| 747 break; | 739 break; |
| 748 } | 740 } |
| 749 | 741 |
| 750 this.dirty_ = true; | |
| 751 return false; | 742 return false; |
| 752 }, | 743 }, |
| 753 | 744 |
| 754 /** | 745 /** |
| 755 * start dragging of a display rectangle. | 746 * start dragging of a display rectangle. |
| 756 * @param {HTMLElement} target The event target. | 747 * @param {HTMLElement} target The event target. |
| 757 * @param {Object} eventLocation The object to hold the location where | 748 * @param {Object} eventLocation The object to hold the location where |
| 758 * this event happens. | 749 * this event happens. |
| 759 * @private | 750 * @private |
| 760 */ | 751 */ |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 draggingDiv.style.top = top + 'px'; | 808 draggingDiv.style.top = top + 'px'; |
| 818 } else { | 809 } else { |
| 819 var left = Math.max(draggingDiv.offsetLeft, | 810 var left = Math.max(draggingDiv.offsetLeft, |
| 820 baseDiv.offsetLeft - draggingDiv.offsetWidth + | 811 baseDiv.offsetLeft - draggingDiv.offsetWidth + |
| 821 MIN_OFFSET_OVERLAP); | 812 MIN_OFFSET_OVERLAP); |
| 822 left = Math.min(left, | 813 left = Math.min(left, |
| 823 baseDiv.offsetLeft + baseDiv.offsetWidth - | 814 baseDiv.offsetLeft + baseDiv.offsetWidth - |
| 824 MIN_OFFSET_OVERLAP); | 815 MIN_OFFSET_OVERLAP); |
| 825 draggingDiv.style.left = left + 'px'; | 816 draggingDiv.style.left = left + 'px'; |
| 826 } | 817 } |
| 818 var originalPosition = this.dragging_.display.originalPosition; |
| 819 if (originalPosition.x != draggingDiv.offsetLeft || |
| 820 originalPosition.y != draggingDiv.offsetTop) |
| 821 this.applyResult_(); |
| 827 this.dragging_ = null; | 822 this.dragging_ = null; |
| 828 if (this.dirty_) | |
| 829 this.applyResult_(); | |
| 830 } | 823 } |
| 831 this.updateSelectedDisplayDescription_(); | 824 this.updateSelectedDisplayDescription_(); |
| 832 return false; | 825 return false; |
| 833 }, | 826 }, |
| 834 | 827 |
| 835 /** | 828 /** |
| 836 * Updates the description of the selected display section. | 829 * Updates the description of the selected display section. |
| 837 * @private | 830 * @private |
| 838 */ | 831 */ |
| 839 updateSelectedDisplayDescription_: function() { | 832 updateSelectedDisplayDescription_: function() { |
| 840 if (this.focusedIndex_ == null || | 833 if (this.focusedIndex_ == null || |
| 841 this.displays_[this.focusedIndex_] == null) { | 834 this.displays_[this.focusedIndex_] == null) { |
| 842 $('selected-display-data-container').hidden = true; | 835 $('selected-display-data-container').hidden = true; |
| 843 $('display-configuration-arrow').hidden = true; | 836 $('display-configuration-arrow').hidden = true; |
| 844 $('display-options-set-primary').disabled = true; | 837 $('display-options-set-primary').hidden = true; |
| 845 return; | 838 return; |
| 846 } | 839 } |
| 847 | 840 |
| 848 $('selected-display-data-container').hidden = false; | 841 $('selected-display-data-container').hidden = false; |
| 849 var display = this.displays_[this.focusedIndex_]; | 842 var display = this.displays_[this.focusedIndex_]; |
| 850 var nameElement = $('selected-display-name'); | 843 var nameElement = $('selected-display-name'); |
| 851 while (nameElement.childNodes.length > 0) | 844 while (nameElement.childNodes.length > 0) |
| 852 nameElement.removeChild(nameElement.firstChild); | 845 nameElement.removeChild(nameElement.firstChild); |
| 853 nameElement.appendChild(document.createTextNode(display.name)); | 846 nameElement.appendChild(document.createTextNode(display.name)); |
| 854 | 847 |
| 855 var resolutionData = display.width + 'x' + display.height; | 848 var resolutionData = display.width + 'x' + display.height; |
| 856 var resolutionElement = $('selected-display-resolution'); | 849 var resolutionElement = $('selected-display-resolution'); |
| 857 while (resolutionElement.childNodes.length > 0) | 850 while (resolutionElement.childNodes.length > 0) |
| 858 resolutionElement.removeChild(resolutionElement.firstChild); | 851 resolutionElement.removeChild(resolutionElement.firstChild); |
| 859 resolutionElement.appendChild(document.createTextNode(resolutionData)); | 852 resolutionElement.appendChild(document.createTextNode(resolutionData)); |
| 860 | 853 |
| 861 if (this.overscanCalibrator_) { | 854 if (this.overscanCalibrator_) { |
| 862 $('start-calibrating-overscan-control').hidden = true; | 855 $('start-calibrating-overscan-control').hidden = true; |
| 863 $('end-calibrating-overscan-control').hidden = false; | 856 $('end-calibrating-overscan-control').hidden = false; |
| 864 } else { | 857 } else { |
| 865 $('start-calibrating-overscan-control').hidden = false; | 858 $('start-calibrating-overscan-control').hidden = false; |
| 866 $('end-calibrating-overscan-control').hidden = true; | 859 $('end-calibrating-overscan-control').hidden = true; |
| 867 } | 860 } |
| 868 | 861 |
| 869 var arrow = $('display-configuration-arrow'); | 862 var arrow = $('display-configuration-arrow'); |
| 870 arrow.hidden = false; | 863 arrow.hidden = false; |
| 871 arrow.style.top = | 864 // Adding 1 px to the position to fit the border line and the border in |
| 872 $('display-configurations').offsetTop - arrow.offsetHeight / 2 + 'px'; | 865 // arrow precisely. |
| 866 arrow.style.top = $('display-configurations').offsetTop - |
| 867 arrow.offsetHeight / 2 + 1 + 'px'; |
| 873 arrow.style.left = display.div.offsetLeft + display.div.offsetWidth / 2 - | 868 arrow.style.left = display.div.offsetLeft + display.div.offsetWidth / 2 - |
| 874 arrow.offsetWidth / 2 + 'px'; | 869 arrow.offsetWidth / 2 + 'px'; |
| 875 | 870 |
| 876 $('display-options-set-primary').disabled = | 871 $('display-options-set-primary').hidden = |
| 877 this.displays_[this.focusedIndex_].isPrimary; | 872 this.displays_[this.focusedIndex_].isPrimary; |
| 878 }, | 873 }, |
| 879 | 874 |
| 880 /** | 875 /** |
| 881 * Clears the drawing area for display rectangles. | 876 * Clears the drawing area for display rectangles. |
| 882 * @private | 877 * @private |
| 883 */ | 878 */ |
| 884 resetDisplaysView_: function() { | 879 resetDisplaysView_: function() { |
| 885 var displaysViewHost = $('display-options-displays-view-host'); | 880 var displaysViewHost = $('display-options-displays-view-host'); |
| 886 displaysViewHost.removeChild(displaysViewHost.firstChild); | 881 displaysViewHost.removeChild(displaysViewHost.firstChild); |
| 887 this.displaysView_ = document.createElement('div'); | 882 this.displaysView_ = document.createElement('div'); |
| 888 this.displaysView_.id = 'display-options-displays-view'; | 883 this.displaysView_.id = 'display-options-displays-view'; |
| 889 displaysViewHost.appendChild(this.displaysView_); | 884 displaysViewHost.appendChild(this.displaysView_); |
| 890 }, | 885 }, |
| 891 | 886 |
| 892 /** | 887 /** |
| 893 * Resize the specified display rectangle to keep the change of | 888 * Resize the specified display rectangle to keep the change of |
| 894 * the border width. | 889 * the border width. |
| 895 * @param {Object} display The display object. | 890 * @param {Object} display The display object. |
| 896 * @param {number} index The index of the display. | 891 * @param {number} index The index of the display. |
| 897 * @private | 892 * @private |
| 898 */ | 893 */ |
| 899 resizeDisplayRectangle_: function(display, index) { | 894 resizeDisplayRectangle_: function(display, index) { |
| 900 var borderWidth = (index == this.focusedIndex_) ? | 895 var borderWidth = (index == this.focusedIndex_) ? |
| 901 FOCUSED_BORDER_WIDTH_PX : NORMAL_BORDER_WIDTH_PX; | 896 FOCUSED_BORDER_WIDTH_PX : NORMAL_BORDER_WIDTH_PX; |
| 902 display.div.style.width = | 897 display.div.style.width = |
| 903 display.width * this.visualScale_ - borderWidth * 2 + 'px'; | 898 display.width * this.visualScale_ - borderWidth * 2 + 'px'; |
| 904 display.div.style.height = | 899 var newHeight = display.height * this.visualScale_ - borderWidth * 2; |
| 905 display.height * this.visualScale_ - borderWidth * 2 + 'px'; | 900 display.div.style.height = newHeight + 'px'; |
| 901 display.nameContainer.style.marginTop = |
| 902 (newHeight - display.nameContainer.offsetHeight) / 2 + 'px'; |
| 906 if (display.isPrimary) { | 903 if (display.isPrimary) { |
| 907 var launcher = display.div.firstChild; | 904 var launcher = display.div.firstChild; |
| 908 if (launcher && launcher.id == 'display-launcher') { | 905 if (launcher && launcher.id == 'display-launcher') { |
| 909 launcher.style.width = display.div.style.width; | 906 launcher.style.width = display.div.style.width; |
| 910 } | 907 } |
| 911 } | 908 } |
| 912 }, | 909 }, |
| 913 | 910 |
| 914 /** | 911 /** |
| 915 * Lays out the display rectangles for mirroring. | 912 * Lays out the display rectangles for mirroring. |
| 916 * @private | 913 * @private |
| 917 */ | 914 */ |
| 918 layoutMirroringDisplays_: function() { | 915 layoutMirroringDisplays_: function() { |
| 919 // Offset pixels for secondary display rectangles. | 916 // Offset pixels for secondary display rectangles. The offset includes the |
| 920 /** @const */ var MIRRORING_OFFSET_PIXELS = 2; | 917 // border width. |
| 918 /** @const */ var MIRRORING_OFFSET_PIXELS = 3; |
| 921 // Always show two displays because there must be two displays when | 919 // Always show two displays because there must be two displays when |
| 922 // the display_options is enabled. Don't rely on displays_.length because | 920 // the display_options is enabled. Don't rely on displays_.length because |
| 923 // there is only one display from chrome's perspective in mirror mode. | 921 // there is only one display from chrome's perspective in mirror mode. |
| 924 /** @const */ var MIN_NUM_DISPLAYS = 2; | 922 /** @const */ var MIN_NUM_DISPLAYS = 2; |
| 925 /** @const */ var MIRRORING_VERTICAL_MARGIN = 20; | 923 /** @const */ var MIRRORING_VERTICAL_MARGIN = 20; |
| 926 | 924 |
| 927 // The width/height should be same as the first display: | 925 // The width/height should be same as the first display: |
| 928 var width = this.displays_[0].width * this.visualScale_; | 926 var width = this.displays_[0].width * this.visualScale_; |
| 929 var height = this.displays_[0].height * this.visualScale_; | 927 var height = this.displays_[0].height * this.visualScale_; |
| 930 | 928 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 if (display.isPrimary) { | 1009 if (display.isPrimary) { |
| 1012 // Put a grey rectangle to the primary display to denote launcher | 1010 // Put a grey rectangle to the primary display to denote launcher |
| 1013 // below. | 1011 // below. |
| 1014 var launcher = document.createElement('div'); | 1012 var launcher = document.createElement('div'); |
| 1015 launcher.id = 'display-launcher'; | 1013 launcher.id = 'display-launcher'; |
| 1016 div.appendChild(launcher); | 1014 div.appendChild(launcher); |
| 1017 this.primaryDisplay_ = display; | 1015 this.primaryDisplay_ = display; |
| 1018 } else { | 1016 } else { |
| 1019 this.secondaryDisplay_ = display; | 1017 this.secondaryDisplay_ = display; |
| 1020 } | 1018 } |
| 1019 var displayNameContainer = document.createElement('div'); |
| 1020 displayNameContainer.textContent = display.name; |
| 1021 div.appendChild(displayNameContainer); |
| 1022 display.nameContainer = displayNameContainer; |
| 1021 this.resizeDisplayRectangle_(display, i); | 1023 this.resizeDisplayRectangle_(display, i); |
| 1022 div.style.left = display.x * this.visualScale_ + offset.x + 'px'; | 1024 div.style.left = display.x * this.visualScale_ + offset.x + 'px'; |
| 1023 div.style.top = display.y * this.visualScale_ + offset.y + 'px'; | 1025 div.style.top = display.y * this.visualScale_ + offset.y + 'px'; |
| 1024 var displayNameContainer = document.createElement('div'); | |
| 1025 displayNameContainer.textContent = display.name; | |
| 1026 div.appendChild(displayNameContainer); | |
| 1027 | 1026 |
| 1028 div.onmousedown = this.onMouseDown_.bind(this); | 1027 div.onmousedown = this.onMouseDown_.bind(this); |
| 1029 div.ontouchstart = this.onTouchStart_.bind(this); | 1028 div.ontouchstart = this.onTouchStart_.bind(this); |
| 1030 | 1029 |
| 1031 this.displaysView_.appendChild(div); | 1030 this.displaysView_.appendChild(div); |
| 1032 | 1031 |
| 1033 // Set the margin top to place the display name at the middle of the | 1032 // Set the margin top to place the display name at the middle of the |
| 1034 // rectangle. Note that this has to be done after it's added into the | 1033 // rectangle. Note that this has to be done after it's added into the |
| 1035 // |displaysView_|. Otherwise its offsetHeight is yet 0. | 1034 // |displaysView_|. Otherwise its offsetHeight is yet 0. |
| 1036 displayNameContainer.style.marginTop = | 1035 displayNameContainer.style.marginTop = |
| 1037 (div.offsetHeight - displayNameContainer.offsetHeight) / 2 + 'px'; | 1036 (div.offsetHeight - displayNameContainer.offsetHeight) / 2 + 'px'; |
| 1037 display.originalPosition = {x: div.offsetLeft, y: div.offsetTop}; |
| 1038 } | 1038 } |
| 1039 }, | 1039 }, |
| 1040 | 1040 |
| 1041 /** | 1041 /** |
| 1042 * Called when the display arrangement has changed. | 1042 * Called when the display arrangement has changed. |
| 1043 * @param {boolean} mirroring Whether current mode is mirroring or not. | 1043 * @param {boolean} mirroring Whether current mode is mirroring or not. |
| 1044 * @param {Array} displays The list of the display information. | 1044 * @param {Array} displays The list of the display information. |
| 1045 * @param {SecondaryDisplayLayout} layout The layout strategy. | 1045 * @param {SecondaryDisplayLayout} layout The layout strategy. |
| 1046 * @param {number} offset The offset of the secondary display. | 1046 * @param {number} offset The offset of the secondary display. |
| 1047 * @private | 1047 * @private |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1084 mirroring, displays, layout, offset) { | 1084 mirroring, displays, layout, offset) { |
| 1085 DisplayOptions.getInstance().onDisplayChanged_( | 1085 DisplayOptions.getInstance().onDisplayChanged_( |
| 1086 mirroring, displays, layout, offset); | 1086 mirroring, displays, layout, offset); |
| 1087 }; | 1087 }; |
| 1088 | 1088 |
| 1089 // Export | 1089 // Export |
| 1090 return { | 1090 return { |
| 1091 DisplayOptions: DisplayOptions | 1091 DisplayOptions: DisplayOptions |
| 1092 }; | 1092 }; |
| 1093 }); | 1093 }); |
| OLD | NEW |