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 |