| Index: chrome/browser/resources/options/chromeos/display_options.js
|
| diff --git a/chrome/browser/resources/options/chromeos/display_options.js b/chrome/browser/resources/options/chromeos/display_options.js
|
| index fb3f4ca9da01540b00324b8e6089273178464da9..17ee9a4b7890ef790b107b9be0aa07288371f5b2 100644
|
| --- a/chrome/browser/resources/options/chromeos/display_options.js
|
| +++ b/chrome/browser/resources/options/chromeos/display_options.js
|
| @@ -73,18 +73,28 @@ options.ColorProfile;
|
| * availableColorProfiles: !Array<!options.ColorProfile>,
|
| * bounds: !options.DisplayBounds,
|
| * colorProfileId: number,
|
| - * div: ?Element,
|
| * id: string,
|
| * isInternal: boolean,
|
| * isPrimary: boolean,
|
| * resolutions: !Array<!options.DisplayMode>,
|
| * name: string,
|
| - * rotation: number,
|
| - * originalPosition: ?options.DisplayPosition
|
| + * rotation: number
|
| * }}
|
| */
|
| options.DisplayInfo;
|
|
|
| +/**
|
| + * @typedef {{
|
| + * bounds: !options.DisplayBounds,
|
| + * div: ?HTMLElement,
|
| + * id: string,
|
| + * isPrimary: boolean,
|
| + * name: string,
|
| + * originalPosition: !options.DisplayPosition
|
| + * }}
|
| + */
|
| +options.DisplayLayout;
|
| +
|
| cr.define('options', function() {
|
| var Page = cr.ui.pageManager.Page;
|
| var PageManager = cr.ui.pageManager.PageManager;
|
| @@ -163,7 +173,7 @@ cr.define('options', function() {
|
| * @type {options.DisplayLayoutType}
|
| * @private
|
| */
|
| - layout_: options.DisplayLayoutType.RIGHT,
|
| + layoutType_: options.DisplayLayoutType.RIGHT,
|
|
|
| /**
|
| * The array of current output displays. It also contains the display
|
| @@ -174,34 +184,41 @@ cr.define('options', function() {
|
| displays_: [],
|
|
|
| /**
|
| - * The index of the currently focused display, or -1 for none.
|
| - * @type {number}
|
| + * An object containing DisplayLayout objects for each entry in |displays_|.
|
| + * @type {!Object<!options.DisplayLayout>}
|
| * @private
|
| */
|
| - focusedIndex_: -1,
|
| + displayLayoutMap_: {},
|
|
|
| /**
|
| - * The primary display edit info.
|
| - * @type {?options.DisplayInfo}
|
| + * The id of the currently focused display, or empty for none.
|
| + * @type {string}
|
| * @private
|
| */
|
| - primaryDisplay_: null,
|
| + focusedId_: '',
|
|
|
| /**
|
| - * The secondary display edit info.
|
| - * @type {?options.DisplayInfo}
|
| + * The primary display id.
|
| + * @type {string}
|
| * @private
|
| */
|
| - secondaryDisplay_: null,
|
| + primaryDisplayId_: '',
|
| +
|
| + /**
|
| + * The secondary display id.
|
| + * @type {string}
|
| + * @private
|
| + */
|
| + secondaryDisplayId_: '',
|
|
|
| /**
|
| * Drag info.
|
| - * @type {?{display: !options.DisplayInfo,
|
| + * @type {?{displayId: string,
|
| * originalLocation: !options.DisplayPosition,
|
| * eventLocation: !options.DisplayPosition}}
|
| * @private
|
| */
|
| - dragging_: null,
|
| + dragInfo_: null,
|
|
|
| /**
|
| * The container div element which contains all of the display rectangles.
|
| @@ -251,28 +268,25 @@ cr.define('options', function() {
|
| container.ontouchend = this.endDragging_.bind(this);
|
|
|
| $('display-options-set-primary').onclick = (function() {
|
| - chrome.send('setPrimary', [this.displays_[this.focusedIndex_].id]);
|
| + chrome.send('setPrimary', [this.focusedId_]);
|
| }).bind(this);
|
| $('display-options-resolution-selection').onchange = (function(ev) {
|
| - var display = this.displays_[this.focusedIndex_];
|
| + var display = this.getDisplayInfoFromId(this.focusedId_);
|
| var resolution = display.resolutions[ev.target.value];
|
| - chrome.send('setDisplayMode', [display.id, resolution]);
|
| + chrome.send('setDisplayMode', [this.focusedId_, resolution]);
|
| }).bind(this);
|
| $('display-options-orientation-selection').onchange = (function(ev) {
|
| - var displayIndex =
|
| - (this.focusedIndex_ == -1) ? 0 : this.focusedIndex_;
|
| var rotation = parseInt(ev.target.value, 10);
|
| - chrome.send('setRotation', [this.displays_[displayIndex].id, rotation]);
|
| + chrome.send('setRotation', [this.focusedId_, rotation]);
|
| }).bind(this);
|
| $('display-options-color-profile-selection').onchange = (function(ev) {
|
| - chrome.send('setColorProfile', [this.displays_[this.focusedIndex_].id,
|
| - ev.target.value]);
|
| + chrome.send('setColorProfile', [this.focusedId_, ev.target.value]);
|
| }).bind(this);
|
| $('selected-display-start-calibrating-overscan').onclick = (function() {
|
| // Passes the target display ID. Do not specify it through URL hash,
|
| // we do not care back/forward.
|
| var displayOverscan = options.DisplayOverscan.getInstance();
|
| - displayOverscan.setDisplayId(this.displays_[this.focusedIndex_].id);
|
| + displayOverscan.setDisplayId(this.focusedId_);
|
| PageManager.showPageByName('displayOverscan');
|
| chrome.send('coreOptionsUserMetricsAction',
|
| ['Options_DisplaySetOverscan']);
|
| @@ -394,22 +408,33 @@ cr.define('options', function() {
|
| },
|
|
|
| /**
|
| + * @param {string} id
|
| + * @return {options.DisplayInfo}
|
| + */
|
| + getDisplayInfoFromId(id) {
|
| + return this.displays_.find(function(display) {
|
| + return display.id == id;
|
| + });
|
| + },
|
| +
|
| + /**
|
| * Collects the current data and sends it to Chrome.
|
| * @private
|
| */
|
| - applyResult_: function() {
|
| + sendDragResult_: function() {
|
| // Offset is calculated from top or left edge.
|
| - var primary = this.primaryDisplay_;
|
| - var secondary = this.secondaryDisplay_;
|
| + var primary = this.displayLayoutMap_[this.primaryDisplayId_];
|
| + var secondary = this.displayLayoutMap_[this.secondaryDisplayId_];
|
| var offset;
|
| - if (this.layout_ == options.DisplayLayoutType.LEFT ||
|
| - this.layout_ == options.DisplayLayoutType.RIGHT) {
|
| + if (this.layoutType_ == options.DisplayLayoutType.LEFT ||
|
| + this.layoutType_ == options.DisplayLayoutType.RIGHT) {
|
| offset = secondary.div.offsetTop - primary.div.offsetTop;
|
| } else {
|
| offset = secondary.div.offsetLeft - primary.div.offsetLeft;
|
| }
|
| offset = Math.floor(offset / this.visualScale_);
|
| - chrome.send('setDisplayLayout', [secondary.id, this.layout_, offset]);
|
| + chrome.send(
|
| + 'setDisplayLayout', [secondary.id, this.layoutType_, offset]);
|
| },
|
|
|
| /**
|
| @@ -447,17 +472,7 @@ cr.define('options', function() {
|
| * @private
|
| */
|
| processDragging_: function(e, eventLocation) {
|
| - if (!this.dragging_)
|
| - return true;
|
| -
|
| - var index = -1;
|
| - for (var i = 0; i < this.displays_.length; i++) {
|
| - if (this.displays_[i] == this.dragging_.display) {
|
| - index = i;
|
| - break;
|
| - }
|
| - }
|
| - if (index < 0)
|
| + if (!this.dragInfo_)
|
| return true;
|
|
|
| e.preventDefault();
|
| @@ -465,82 +480,83 @@ cr.define('options', function() {
|
| // Note that current code of moving display-rectangles doesn't work
|
| // if there are >=3 displays. This is our assumption for M21.
|
| // TODO(mukai): Fix the code to allow >=3 displays.
|
| - var newPosition = {
|
| - x: this.dragging_.originalLocation.x +
|
| - (eventLocation.x - this.dragging_.eventLocation.x),
|
| - y: this.dragging_.originalLocation.y +
|
| - (eventLocation.y - this.dragging_.eventLocation.y)
|
| + var dragInfo = this.dragInfo_;
|
| + var dragLayout = this.displayLayoutMap_[dragInfo.displayId];
|
| + /** @type {options.DisplayPosition} */ var newPosition = {
|
| + x: dragInfo.originalLocation.x +
|
| + (eventLocation.x - dragInfo.eventLocation.x),
|
| + y: dragInfo.originalLocation.y +
|
| + (eventLocation.y - dragInfo.eventLocation.y)
|
| };
|
|
|
| - var baseDiv = this.dragging_.display.isPrimary ?
|
| - this.secondaryDisplay_.div : this.primaryDisplay_.div;
|
| - var draggingDiv = this.dragging_.display.div;
|
| + var baseDisplayId = dragLayout.isPrimary ? this.secondaryDisplayId_ :
|
| + this.primaryDisplayId_;
|
| + var baseDiv = this.displayLayoutMap_[baseDisplayId].div;
|
| + var draggingDiv = dragLayout.div;
|
|
|
| newPosition.x = this.snapToEdge_(newPosition.x, draggingDiv.offsetWidth,
|
| baseDiv.offsetLeft, baseDiv.offsetWidth);
|
| newPosition.y = this.snapToEdge_(newPosition.y, draggingDiv.offsetHeight,
|
| baseDiv.offsetTop, baseDiv.offsetHeight);
|
|
|
| - var newCenter = /** {!options.DisplayPosition} */({
|
| + /** @type {!options.DisplayPosition} */ var newCenter = {
|
| x: newPosition.x + draggingDiv.offsetWidth / 2,
|
| y: newPosition.y + draggingDiv.offsetHeight / 2
|
| - });
|
| + };
|
|
|
| - var baseBounds = /** {!options.DisplayBounds} */({
|
| + /** @type {!options.DisplayBounds} */ var baseBounds = {
|
| left: baseDiv.offsetLeft,
|
| top: baseDiv.offsetTop,
|
| width: baseDiv.offsetWidth,
|
| height: baseDiv.offsetHeight
|
| - });
|
| + };
|
| +
|
| + var isPrimary = dragLayout.isPrimary;
|
| + var layoutType = this.layoutType_;
|
| +
|
| switch (getPositionToRectangle(baseBounds, newCenter)) {
|
| case options.DisplayLayoutType.RIGHT:
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.LEFT :
|
| - options.DisplayLayoutType.RIGHT;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.LEFT :
|
| + options.DisplayLayoutType.RIGHT;
|
| break;
|
| case options.DisplayLayoutType.LEFT:
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.RIGHT :
|
| - options.DisplayLayoutType.LEFT;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.RIGHT :
|
| + options.DisplayLayoutType.LEFT;
|
| break;
|
| case options.DisplayLayoutType.TOP:
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.BOTTOM :
|
| - options.DisplayLayoutType.TOP;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.BOTTOM :
|
| + options.DisplayLayoutType.TOP;
|
| break;
|
| case options.DisplayLayoutType.BOTTOM:
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.TOP :
|
| - options.DisplayLayoutType.BOTTOM;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.TOP :
|
| + options.DisplayLayoutType.BOTTOM;
|
| break;
|
| }
|
|
|
| - if (this.layout_ == options.DisplayLayoutType.LEFT ||
|
| - this.layout_ == options.DisplayLayoutType.RIGHT) {
|
| + if (layoutType == options.DisplayLayoutType.LEFT ||
|
| + layoutType == options.DisplayLayoutType.RIGHT) {
|
| if (newPosition.y > baseDiv.offsetTop + baseDiv.offsetHeight)
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.TOP :
|
| - options.DisplayLayoutType.BOTTOM;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.TOP :
|
| + options.DisplayLayoutType.BOTTOM;
|
| else if (newPosition.y + draggingDiv.offsetHeight < baseDiv.offsetTop)
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.BOTTOM :
|
| - options.DisplayLayoutType.TOP;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.BOTTOM :
|
| + options.DisplayLayoutType.TOP;
|
| } else {
|
| if (newPosition.x > baseDiv.offsetLeft + baseDiv.offsetWidth)
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.LEFT :
|
| - options.DisplayLayoutType.RIGHT;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.LEFT :
|
| + options.DisplayLayoutType.RIGHT;
|
| else if (newPosition.x + draggingDiv.offsetWidth < baseDiv.offsetLeft)
|
| - this.layout_ = this.dragging_.display.isPrimary ?
|
| - options.DisplayLayoutType.RIGHT :
|
| - options.DisplayLayoutType.LEFT;
|
| + layoutType = isPrimary ? options.DisplayLayoutType.RIGHT :
|
| + options.DisplayLayoutType.LEFT;
|
| }
|
|
|
| + this.layoutType_ = layoutType;
|
| +
|
| var layoutToBase;
|
| - if (!this.dragging_.display.isPrimary) {
|
| - layoutToBase = this.layout_;
|
| + if (!isPrimary) {
|
| + layoutToBase = layoutType;
|
| } else {
|
| - switch (this.layout_) {
|
| + switch (layoutType) {
|
| case options.DisplayLayoutType.RIGHT:
|
| layoutToBase = options.DisplayLayoutType.LEFT;
|
| break;
|
| @@ -589,34 +605,38 @@ cr.define('options', function() {
|
| * @private
|
| */
|
| startDragging_: function(target, eventLocation) {
|
| - var oldFocusedIndex = this.focusedIndex_;
|
| + var oldFocusedId = this.focusedId_;
|
| + var newFocusedId;
|
| var willUpdateDisplayDescription = false;
|
| - this.focusedIndex_ = -1;
|
| for (var i = 0; i < this.displays_.length; i++) {
|
| - var display = this.displays_[i];
|
| - if (display.div == target ||
|
| - (target.offsetParent && target.offsetParent == display.div)) {
|
| - this.focusedIndex_ = i;
|
| - if (oldFocusedIndex !== null && oldFocusedIndex != i)
|
| - willUpdateDisplayDescription = true;
|
| + var displayLayout = this.displayLayoutMap_[this.displays_[i].id];
|
| + if (displayLayout.div == target ||
|
| + (target.offsetParent && target.offsetParent == displayLayout.div)) {
|
| + newFocusedId = displayLayout.id;
|
| break;
|
| }
|
| }
|
| + if (!newFocusedId)
|
| + return false;
|
| +
|
| + this.focusedId_ = newFocusedId;
|
| + willUpdateDisplayDescription = newFocusedId != oldFocusedId;
|
|
|
| for (var i = 0; i < this.displays_.length; i++) {
|
| - var display = this.displays_[i];
|
| - display.div.className = 'displays-display';
|
| - if (i != this.focusedIndex_)
|
| + var displayLayout = this.displayLayoutMap_[this.displays_[i].id];
|
| + displayLayout.div.className = 'displays-display';
|
| + if (displayLayout.id != this.focusedId_)
|
| continue;
|
|
|
| - display.div.classList.add('displays-focused');
|
| + displayLayout.div.classList.add('displays-focused');
|
| if (this.displays_.length > 1) {
|
| - this.dragging_ = {
|
| - display: display,
|
| + this.dragInfo_ = {
|
| + displayId: displayLayout.id,
|
| originalLocation: {
|
| - x: display.div.offsetLeft, y: display.div.offsetTop
|
| + x: displayLayout.div.offsetLeft,
|
| + y: displayLayout.div.offsetTop
|
| },
|
| - eventLocation: eventLocation
|
| + eventLocation: {x: eventLocation.x, y: eventLocation.y}
|
| };
|
| }
|
| }
|
| @@ -633,36 +653,39 @@ cr.define('options', function() {
|
| */
|
| endDragging_: function(e) {
|
| this.lastTouchLocation_ = null;
|
| - if (this.dragging_) {
|
| - // Make sure the dragging location is connected.
|
| - var baseDiv = this.dragging_.display.isPrimary ?
|
| - this.secondaryDisplay_.div :
|
| - this.primaryDisplay_.div;
|
| - var draggingDiv = this.dragging_.display.div;
|
| - if (this.layout_ == options.DisplayLayoutType.LEFT ||
|
| - this.layout_ == options.DisplayLayoutType.RIGHT) {
|
| - var top = Math.max(
|
| - draggingDiv.offsetTop, baseDiv.offsetTop -
|
| - draggingDiv.offsetHeight + MIN_OFFSET_OVERLAP);
|
| - top = Math.min(
|
| - top,
|
| - baseDiv.offsetTop + baseDiv.offsetHeight - MIN_OFFSET_OVERLAP);
|
| - draggingDiv.style.top = top + 'px';
|
| - } else {
|
| - var left = Math.max(
|
| - draggingDiv.offsetLeft, baseDiv.offsetLeft -
|
| - draggingDiv.offsetWidth + MIN_OFFSET_OVERLAP);
|
| - left = Math.min(
|
| - left,
|
| - baseDiv.offsetLeft + baseDiv.offsetWidth - MIN_OFFSET_OVERLAP);
|
| - draggingDiv.style.left = left + 'px';
|
| - }
|
| - var originalPosition = this.dragging_.display.originalPosition;
|
| - if (originalPosition.x != draggingDiv.offsetLeft ||
|
| - originalPosition.y != draggingDiv.offsetTop)
|
| - this.applyResult_();
|
| - this.dragging_ = null;
|
| + if (!this.dragInfo_)
|
| + return false;
|
| +
|
| + // Make sure the dragging location is connected.
|
| + var dragLayout = this.displayLayoutMap_[this.dragInfo_.displayId];
|
| + var baseDisplayId = dragLayout.isPrimary ? this.secondaryDisplayId_ :
|
| + this.primaryDisplayId_;
|
| + var baseDiv = this.displayLayoutMap_[baseDisplayId].div;
|
| + var draggingDiv = dragLayout.div;
|
| + if (this.layoutType_ == options.DisplayLayoutType.LEFT ||
|
| + this.layoutType_ == options.DisplayLayoutType.RIGHT) {
|
| + var top = Math.max(
|
| + draggingDiv.offsetTop,
|
| + baseDiv.offsetTop - draggingDiv.offsetHeight + MIN_OFFSET_OVERLAP);
|
| + top = Math.min(
|
| + top, baseDiv.offsetTop + baseDiv.offsetHeight - MIN_OFFSET_OVERLAP);
|
| + draggingDiv.style.top = top + 'px';
|
| + } else {
|
| + var left = Math.max(
|
| + draggingDiv.offsetLeft,
|
| + baseDiv.offsetLeft - draggingDiv.offsetWidth + MIN_OFFSET_OVERLAP);
|
| + left = Math.min(
|
| + left,
|
| + baseDiv.offsetLeft + baseDiv.offsetWidth - MIN_OFFSET_OVERLAP);
|
| + draggingDiv.style.left = left + 'px';
|
| + }
|
| + if (dragLayout.originalPosition.x != draggingDiv.offsetLeft ||
|
| + dragLayout.originalPosition.y != draggingDiv.offsetTop) {
|
| + this.sendDragResult_();
|
| }
|
| +
|
| + this.dragInfo_ = null;
|
| +
|
| return false;
|
| },
|
|
|
| @@ -715,14 +738,15 @@ cr.define('options', function() {
|
| * @private
|
| */
|
| updateSelectedDisplaySectionForDisplay_: function(display) {
|
| + var displayLayout = this.displayLayoutMap_[display.id];
|
| var arrow = $('display-configuration-arrow');
|
| arrow.hidden = false;
|
| // Adding 1 px to the position to fit the border line and the border in
|
| // arrow precisely.
|
| arrow.style.top = $('display-configurations').offsetTop -
|
| arrow.offsetHeight / 2 + 'px';
|
| - arrow.style.left = display.div.offsetLeft +
|
| - display.div.offsetWidth / 2 - arrow.offsetWidth / 2 + 'px';
|
| + arrow.style.left = displayLayout.div.offsetLeft +
|
| + displayLayout.div.offsetWidth / 2 - arrow.offsetWidth / 2 + 'px';
|
|
|
| $('display-options-set-primary').disabled = display.isPrimary;
|
| $('display-options-select-mirroring').disabled =
|
| @@ -804,12 +828,11 @@ cr.define('options', function() {
|
|
|
| if (this.mirroring_) {
|
| this.updateSelectedDisplaySectionMirroring_();
|
| - } else if (this.focusedIndex_ == -1 ||
|
| - this.displays_[this.focusedIndex_] == null) {
|
| + } else if (this.focusedId_ == '') {
|
| this.updateSelectedDisplaySectionNoSelected_();
|
| } else {
|
| this.updateSelectedDisplaySectionForDisplay_(
|
| - this.displays_[this.focusedIndex_]);
|
| + this.getDisplayInfoFromId(this.focusedId_));
|
| }
|
| },
|
|
|
| @@ -856,7 +879,7 @@ cr.define('options', function() {
|
| $('display-options-displays-view').offsetWidth / 2 - totalWidth / 2;
|
|
|
| for (var i = 0; i < numDisplays; i++) {
|
| - var div = document.createElement('div');
|
| + var div = /** @type {HTMLElement} */ (document.createElement('div'));
|
| div.className = 'displays-display';
|
| div.style.top = i * MIRRORING_OFFSET_PIXELS + 'px';
|
| div.style.left = i * MIRRORING_OFFSET_PIXELS + offsetX + 'px';
|
| @@ -867,60 +890,121 @@ cr.define('options', function() {
|
| if (i != numDisplays - 1)
|
| div.classList.add('display-mirrored');
|
| this.displaysView_.appendChild(div);
|
| +
|
| + // Not currently used but set for consistency / debugging.
|
| + this.displayLayoutMap_[this.displays_[i].id].div = div;
|
| }
|
| },
|
|
|
| /**
|
| + * Creates a DisplayLayout object representing the display.
|
| + * @param {!options.DisplayInfo} display
|
| + * @return {!options.DisplayLayout}
|
| + * @private
|
| + */
|
| + createDisplayLayout_: function(display) {
|
| + /** @type {options.DisplayLayout} */ var displayLayout = {
|
| + bounds: display.bounds,
|
| + div: null,
|
| + id: display.id,
|
| + isPrimary: display.isPrimary,
|
| + name: display.name,
|
| + originalPosition: {x: 0, y: 0}
|
| + };
|
| + return displayLayout;
|
| + },
|
| +
|
| + /**
|
| * Creates a div element representing the specified display.
|
| - * @param {!options.DisplayInfo} display The display object.
|
| - * @param {boolean} focused True if it's focused.
|
| + * @param {!options.DisplayLayout} displayLayout
|
| + * @param {options.DisplayLayoutType} layoutType The layout type for the
|
| + * secondary display.
|
| + * @param {!options.DisplayPosition} offset The offset to the center of the
|
| + * display area.
|
| * @private
|
| */
|
| - createDisplayRectangle_: function(display, focused) {
|
| - var div = document.createElement('div');
|
| - display.div = div;
|
| + createDisplayLayoutDiv_: function(displayLayout, layoutType, offset) {
|
| + var div = /** @type {!HTMLElement} */ (document.createElement('div'));
|
| div.className = 'displays-display';
|
| - if (focused)
|
| - div.classList.add('displays-focused');
|
| + div.classList.toggle(
|
| + 'displays-focused', displayLayout.id == this.focusedId_);
|
|
|
| // div needs to be added to the DOM tree first, otherwise offsetHeight for
|
| // nameContainer below cannot be computed.
|
| this.displaysView_.appendChild(div);
|
|
|
| var nameContainer = document.createElement('div');
|
| - nameContainer.textContent = display.name;
|
| + nameContainer.textContent = displayLayout.name;
|
| div.appendChild(nameContainer);
|
| - div.style.width =
|
| - Math.floor(display.bounds.width * this.visualScale_) + 'px';
|
| - var newHeight = Math.floor(display.bounds.height * this.visualScale_);
|
| +
|
| + var bounds = displayLayout.bounds;
|
| + div.style.width = Math.floor(bounds.width * this.visualScale_) + 'px';
|
| + var newHeight = Math.floor(bounds.height * this.visualScale_);
|
| div.style.height = newHeight + 'px';
|
| nameContainer.style.marginTop =
|
| (newHeight - nameContainer.offsetHeight) / 2 + 'px';
|
|
|
| div.onmousedown = this.onMouseDown_.bind(this);
|
| div.ontouchstart = this.onTouchStart_.bind(this);
|
| - return div;
|
| +
|
| + if (displayLayout.isPrimary) {
|
| + div.style.left =
|
| + Math.floor(bounds.left * this.visualScale_) + offset.x + 'px';
|
| + div.style.top =
|
| + Math.floor(bounds.top * this.visualScale_) + offset.y + 'px';
|
| + } else {
|
| + // Don't trust the secondary display's x or y, because it may cause a
|
| + // 1px gap due to rounding, which will create a fake update on end
|
| + // dragging. See crbug.com/386401
|
| + var primaryDiv = this.displayLayoutMap_[this.primaryDisplayId_].div;
|
| + switch (layoutType) {
|
| + case options.DisplayLayoutType.TOP:
|
| + div.style.left =
|
| + Math.floor(bounds.left * this.visualScale_) + offset.x + 'px';
|
| + div.style.top = primaryDiv.offsetTop - div.offsetHeight + 'px';
|
| + break;
|
| + case options.DisplayLayoutType.RIGHT:
|
| + div.style.left =
|
| + primaryDiv.offsetLeft + primaryDiv.offsetWidth + 'px';
|
| + div.style.top =
|
| + Math.floor(bounds.top * this.visualScale_) + offset.y + 'px';
|
| + break;
|
| + case options.DisplayLayoutType.BOTTOM:
|
| + div.style.left =
|
| + Math.floor(bounds.left * this.visualScale_) + offset.x + 'px';
|
| + div.style.top =
|
| + primaryDiv.offsetTop + primaryDiv.offsetHeight + 'px';
|
| + break;
|
| + case options.DisplayLayoutType.LEFT:
|
| + div.style.left = primaryDiv.offsetLeft - div.offsetWidth + 'px';
|
| + div.style.top =
|
| + Math.floor(bounds.top * this.visualScale_) + offset.y + 'px';
|
| + break;
|
| + }
|
| + }
|
| +
|
| + displayLayout.div = div;
|
| + displayLayout.originalPosition.x = div.offsetLeft;
|
| + displayLayout.originalPosition.y = div.offsetTop;
|
| },
|
|
|
| /**
|
| * Layouts the display rectangles according to the current layout_.
|
| + * @param {options.DisplayLayoutType} layoutType
|
| * @private
|
| */
|
| - layoutDisplays_: function() {
|
| + layoutDisplays_: function(layoutType) {
|
| var maxWidth = 0;
|
| var maxHeight = 0;
|
| var boundingBox = {left: 0, right: 0, top: 0, bottom: 0};
|
| - this.primaryDisplay_ = null;
|
| - this.secondaryDisplay_ = null;
|
| - var focusedDisplay = null;
|
| + this.primaryDisplayId_ = '';
|
| + this.secondaryDisplayId_ = '';
|
| for (var i = 0; i < this.displays_.length; i++) {
|
| var display = this.displays_[i];
|
| if (display.isPrimary)
|
| - this.primaryDisplay_ = display;
|
| - else
|
| - this.secondaryDisplay_ = display;
|
| - if (i == this.focusedIndex_)
|
| - focusedDisplay = display;
|
| + this.primaryDisplayId_ = display.id;
|
| + else if (this.secondaryDisplayId_ == '')
|
| + this.secondaryDisplayId_ = display.id;
|
|
|
| var bounds = display.bounds;
|
| boundingBox.left = Math.min(boundingBox.left, bounds.left);
|
| @@ -932,7 +1016,7 @@ cr.define('options', function() {
|
| maxWidth = Math.max(maxWidth, bounds.width);
|
| maxHeight = Math.max(maxHeight, bounds.height);
|
| }
|
| - if (!this.primaryDisplay_)
|
| + if (this.primaryDisplayId_ == '')
|
| return;
|
|
|
| // Make the margin around the bounding box.
|
| @@ -958,106 +1042,56 @@ cr.define('options', function() {
|
| (boundingBox.bottom + boundingBox.top) * this.visualScale_ / 2)
|
| };
|
|
|
| - // Layouting the display rectangles. First layout the primaryDisplay and
|
| - // then layout the secondary which is attaching to the primary.
|
| - var primaryDiv = this.createDisplayRectangle_(
|
| - this.primaryDisplay_, this.primaryDisplay_ == focusedDisplay);
|
| - primaryDiv.style.left =
|
| - Math.floor(this.primaryDisplay_.bounds.left * this.visualScale_) +
|
| - offset.x + 'px';
|
| - primaryDiv.style.top =
|
| - Math.floor(this.primaryDisplay_.bounds.top * this.visualScale_) +
|
| - offset.y + 'px';
|
| - this.primaryDisplay_.originalPosition = {
|
| - x: primaryDiv.offsetLeft,
|
| - y: primaryDiv.offsetTop
|
| - };
|
| -
|
| - if (this.secondaryDisplay_) {
|
| - var secondaryDiv = this.createDisplayRectangle_(
|
| - this.secondaryDisplay_, this.secondaryDisplay_ == focusedDisplay);
|
| - // Don't trust the secondary display's x or y, because it may cause a
|
| - // 1px gap due to rounding, which will create a fake update on end
|
| - // dragging. See crbug.com/386401
|
| - var bounds = this.secondaryDisplay_.bounds;
|
| - switch (this.layout_) {
|
| - case options.DisplayLayoutType.TOP:
|
| - secondaryDiv.style.left =
|
| - Math.floor(bounds.left * this.visualScale_) + offset.x + 'px';
|
| - secondaryDiv.style.top =
|
| - primaryDiv.offsetTop - secondaryDiv.offsetHeight + 'px';
|
| - break;
|
| - case options.DisplayLayoutType.RIGHT:
|
| - secondaryDiv.style.left =
|
| - primaryDiv.offsetLeft + primaryDiv.offsetWidth + 'px';
|
| - secondaryDiv.style.top =
|
| - Math.floor(bounds.top * this.visualScale_) + offset.y + 'px';
|
| - break;
|
| - case options.DisplayLayoutType.BOTTOM:
|
| - secondaryDiv.style.left =
|
| - Math.floor(bounds.left * this.visualScale_) + offset.x + 'px';
|
| - secondaryDiv.style.top =
|
| - primaryDiv.offsetTop + primaryDiv.offsetHeight + 'px';
|
| - break;
|
| - case options.DisplayLayoutType.LEFT:
|
| - secondaryDiv.style.left =
|
| - primaryDiv.offsetLeft - secondaryDiv.offsetWidth + 'px';
|
| - secondaryDiv.style.top =
|
| - Math.floor(bounds.top * this.visualScale_) + offset.y + 'px';
|
| - break;
|
| - }
|
| - this.secondaryDisplay_.originalPosition = {
|
| - x: secondaryDiv.offsetLeft,
|
| - y: secondaryDiv.offsetTop
|
| - };
|
| + // Layout the display rectangles. First layout the primary display and
|
| + // then layout the secondary which is attached to the primary.
|
| + for (var i = 0; i < this.displays_.length; i++) {
|
| + this.createDisplayLayoutDiv_(
|
| + this.displayLayoutMap_[this.displays_[i].id], layoutType, offset);
|
| }
|
| },
|
|
|
| /**
|
| * Called when the display arrangement has changed.
|
| * @param {options.MultiDisplayMode} mode multi display mode.
|
| - * @param {Array<options.DisplayInfo>} displays The list of the display
|
| + * @param {!Array<!options.DisplayInfo>} displays The list of the display
|
| * information.
|
| - * @param {options.DisplayLayoutType} layout The layout strategy.
|
| + * @param {options.DisplayLayoutType} layoutType The layout strategy.
|
| * @param {number} offset The offset of the secondary display.
|
| * @private
|
| */
|
| - onDisplayChanged_: function(mode, displays, layout, offset) {
|
| + onDisplayChanged_: function(mode, displays, layoutType, offset) {
|
| if (!this.visible)
|
| return;
|
|
|
| - var hasExternal = false;
|
| + this.displays_ = displays;
|
| + this.displayLayoutMap_ = {};
|
| for (var i = 0; i < displays.length; i++) {
|
| - if (!displays[i].isInternal) {
|
| - hasExternal = true;
|
| - break;
|
| - }
|
| + var display = displays[i];
|
| + this.displayLayoutMap_[display.id] = this.createDisplayLayout_(display);
|
| }
|
|
|
| - this.layout_ = layout;
|
| -
|
| var mirroring = mode == options.MultiDisplayMode.MIRRORING;
|
| var unifiedDesktopEnabled = mode == options.MultiDisplayMode.UNIFIED;
|
|
|
| - // Focus to the first display next to the primary one when |displays| list
|
| + // Focus to the first display next to the primary one when |displays_|
|
| // is updated.
|
| if (mirroring) {
|
| - this.focusedIndex_ = -1;
|
| - } else if (this.mirroring_ != mirroring ||
|
| - this.unifiedDesktopEnabled_ != unifiedDesktopEnabled ||
|
| - this.displays_.length != displays.length) {
|
| - this.focusedIndex_ = 0;
|
| + this.focusedId_ = '';
|
| + } else if (
|
| + this.focusedId_ == '' || this.mirroring_ != mirroring ||
|
| + this.unifiedDesktopEnabled_ != unifiedDesktopEnabled ||
|
| + this.displays_.length != displays.length) {
|
| + this.focusedId_ = displays.length > 0 ? displays[0].id : '';
|
| }
|
|
|
| this.mirroring_ = mirroring;
|
| this.unifiedDesktopEnabled_ = unifiedDesktopEnabled;
|
| - this.displays_ = displays;
|
|
|
| this.resetDisplaysView_();
|
| if (this.mirroring_)
|
| this.layoutMirroringDisplays_();
|
| else
|
| - this.layoutDisplays_();
|
| + this.layoutDisplays_(layoutType);
|
|
|
| $('display-options-select-mirroring').value =
|
| mirroring ? 'mirroring' : 'extended';
|
| @@ -1081,9 +1115,9 @@ cr.define('options', function() {
|
| };
|
|
|
| DisplayOptions.setDisplayInfo = function(
|
| - mode, displays, layout, offset) {
|
| + mode, displays, layoutType, offset) {
|
| DisplayOptions.getInstance().onDisplayChanged_(
|
| - mode, displays, layout, offset);
|
| + mode, displays, layoutType, offset);
|
| };
|
|
|
| // Export
|
|
|