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

Unified Diff: chrome/browser/resources/options/chromeos/display_layout_manager.js

Issue 1649173002: Add DisplayLayoutManagerMulti (WIP) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@issue_576375_display3e
Patch Set: Rebase Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/options/chromeos/display_layout_manager.js
diff --git a/chrome/browser/resources/options/chromeos/display_layout_manager.js b/chrome/browser/resources/options/chromeos/display_layout_manager.js
index f264393e5c7ea3fd388f3ffd6d490972524b41f6..17317ac111ba4b5c9658398ab6d35484ba3b0045 100644
--- a/chrome/browser/resources/options/chromeos/display_layout_manager.js
+++ b/chrome/browser/resources/options/chromeos/display_layout_manager.js
@@ -42,7 +42,7 @@ options.DisplayPosition;
* layoutType: options.DisplayLayoutType,
* name: string,
* offset: number,
- * originalPosition: !options.DisplayPosition,
+ * originalDivOffsets: !options.DisplayPosition,
* parentId: string
* }}
*/
@@ -57,7 +57,7 @@ cr.define('options', function() {
* @param {!options.DisplayPosition} point The point to check the position.
* @return {options.DisplayLayoutType}
*/
- function getPositionToRectangle(rect, point) {
+ function getLayoutTypeForPosition(rect, point) {
// Separates the area into four (LEFT/RIGHT/TOP/BOTTOM) by the diagonals of
// the rect, and decides which area the display should reside.
var diagonalSlope = rect.height / rect.width;
@@ -78,30 +78,22 @@ cr.define('options', function() {
}
/**
- * Snaps the region [point, width] to [basePoint, baseWidth] if
- * the [point, width] is close enough to the base's edge.
- * @param {number} point The starting point of the region.
- * @param {number} width The width of the region.
- * @param {number} basePoint The starting point of the base region.
- * @param {number} baseWidth The width of the base region.
- * @return {number} The moved point. Returns the point itself if it doesn't
- * need to snap to the edge.
- * @private
+ * @param {options.DisplayLayoutType} layoutType
+ * @return {!options.DisplayLayoutType}
*/
- function snapToEdge(point, width, basePoint, baseWidth) {
- // If the edge of the region is smaller than this, it will snap to the
- // base's edge.
- /** @const */ var SNAP_DISTANCE_PX = 16;
-
- var startDiff = Math.abs(point - basePoint);
- var endDiff = Math.abs(point + width - (basePoint + baseWidth));
- // Prefer the closer one if both edges are close enough.
- if (startDiff < SNAP_DISTANCE_PX && startDiff < endDiff)
- return basePoint;
- else if (endDiff < SNAP_DISTANCE_PX)
- return basePoint + baseWidth - width;
-
- return point;
+ function invertLayoutType(layoutType) {
+ switch (layoutType) {
+ case options.DisplayLayoutType.RIGHT:
+ return options.DisplayLayoutType.LEFT;
+ case options.DisplayLayoutType.LEFT:
+ return options.DisplayLayoutType.RIGHT;
+ case options.DisplayLayoutType.TOP:
+ return options.DisplayLayoutType.BOTTOM;
+ case options.DisplayLayoutType.BOTTOM:
+ return options.DisplayLayoutType.TOP;
+ }
+ assertNotReached();
+ return layoutType;
}
/**
@@ -139,6 +131,29 @@ cr.define('options', function() {
displayAreaOffset_: null,
/**
+ * Creates a DisplayLayout object representing the display.
+ * @param {string} id
+ * @param {string} name
+ * @param {options.DisplayBounds} bounds
+ * @param {!options.DisplayLayoutType} layoutType
+ * @param {string} parentId
+ * @return {!options.DisplayLayout}
+ * @private
+ */
+ createDisplayLayout: function(id, name, bounds, layoutType, parentId) {
+ return {
+ bounds: bounds,
+ div: null,
+ id: id,
+ layoutType: layoutType,
+ name: name,
+ offset: 0,
+ originalDivOffsets: {x: 0, y: 0},
+ parentId: parentId
+ };
+ },
+
+ /**
* Adds a display to the layout map.
* @param {options.DisplayLayout} displayLayout
*/
@@ -236,10 +251,10 @@ cr.define('options', function() {
var baseLayout = this.getBaseLayout_(displayLayout);
var baseDiv = baseLayout.div;
- newPosition.x = snapToEdge(
+ newPosition.x = this.snapToEdge_(
newPosition.x, div.offsetWidth, baseDiv.offsetLeft,
baseDiv.offsetWidth);
- newPosition.y = snapToEdge(
+ newPosition.y = this.snapToEdge_(
newPosition.y, div.offsetHeight, baseDiv.offsetTop,
baseDiv.offsetHeight);
@@ -259,86 +274,38 @@ cr.define('options', function() {
// a single parent with one child.
var isPrimary = displayLayout.parentId == '';
- // layoutType is always stored in the child layout.
- var layoutType =
- isPrimary ? baseLayout.layoutType : displayLayout.layoutType;
-
- switch (getPositionToRectangle(baseBounds, newCenter)) {
- case options.DisplayLayoutType.RIGHT:
- layoutType = isPrimary ? options.DisplayLayoutType.LEFT :
- options.DisplayLayoutType.RIGHT;
- break;
- case options.DisplayLayoutType.LEFT:
- layoutType = isPrimary ? options.DisplayLayoutType.RIGHT :
- options.DisplayLayoutType.LEFT;
- break;
- case options.DisplayLayoutType.TOP:
- layoutType = isPrimary ? options.DisplayLayoutType.BOTTOM :
- options.DisplayLayoutType.TOP;
- break;
- case options.DisplayLayoutType.BOTTOM:
- layoutType = isPrimary ? options.DisplayLayoutType.TOP :
- options.DisplayLayoutType.BOTTOM;
- break;
- }
+ var layoutType = getLayoutTypeForPosition(baseBounds, newCenter);
+ if (isPrimary)
+ layoutType = invertLayoutType(layoutType);
if (layoutType == options.DisplayLayoutType.LEFT ||
layoutType == options.DisplayLayoutType.RIGHT) {
- if (newPosition.y > baseDiv.offsetTop + baseDiv.offsetHeight)
+ if (newPosition.y > baseDiv.offsetTop + baseDiv.offsetHeight) {
layoutType = isPrimary ? options.DisplayLayoutType.TOP :
options.DisplayLayoutType.BOTTOM;
- else if (newPosition.y + div.offsetHeight < baseDiv.offsetTop)
+ } else if (newPosition.y + div.offsetHeight < baseDiv.offsetTop) {
layoutType = isPrimary ? options.DisplayLayoutType.BOTTOM :
options.DisplayLayoutType.TOP;
+ }
} else {
- if (newPosition.x > baseDiv.offsetLeft + baseDiv.offsetWidth)
+ if (newPosition.x > baseDiv.offsetLeft + baseDiv.offsetWidth) {
layoutType = isPrimary ? options.DisplayLayoutType.LEFT :
options.DisplayLayoutType.RIGHT;
- else if (newPosition.x + div.offsetWidth < baseDiv.offsetLeft)
+ } else if (newPosition.x + div.offsetWidth < baseDiv.offsetLeft) {
layoutType = isPrimary ? options.DisplayLayoutType.RIGHT :
options.DisplayLayoutType.LEFT;
+ }
}
- var layoutToBase;
- if (!isPrimary) {
- displayLayout.layoutType = layoutType;
- layoutToBase = layoutType;
- } else {
+ // layoutType is always stored in the child layout.
+ if (isPrimary)
baseLayout.layoutType = layoutType;
- switch (layoutType) {
- case options.DisplayLayoutType.RIGHT:
- layoutToBase = options.DisplayLayoutType.LEFT;
- break;
- case options.DisplayLayoutType.LEFT:
- layoutToBase = options.DisplayLayoutType.RIGHT;
- break;
- case options.DisplayLayoutType.TOP:
- layoutToBase = options.DisplayLayoutType.BOTTOM;
- break;
- case options.DisplayLayoutType.BOTTOM:
- layoutToBase = options.DisplayLayoutType.TOP;
- break;
- }
- }
+ else
+ displayLayout.layoutType = layoutType;
- switch (layoutToBase) {
- case options.DisplayLayoutType.RIGHT:
- div.style.left = baseDiv.offsetLeft + baseDiv.offsetWidth + 'px';
- div.style.top = newPosition.y + 'px';
- break;
- case options.DisplayLayoutType.LEFT:
- div.style.left = baseDiv.offsetLeft - div.offsetWidth + 'px';
- div.style.top = newPosition.y + 'px';
- break;
- case options.DisplayLayoutType.TOP:
- div.style.top = baseDiv.offsetTop - div.offsetHeight + 'px';
- div.style.left = newPosition.x + 'px';
- break;
- case options.DisplayLayoutType.BOTTOM:
- div.style.top = baseDiv.offsetTop + baseDiv.offsetHeight + 'px';
- div.style.left = newPosition.x + 'px';
- break;
- }
+ var layoutToBase = isPrimary ? invertLayoutType(layoutType) : layoutType;
+
+ this.setDivPosition_(div, newPosition, baseDiv, layoutToBase);
},
/**
@@ -348,42 +315,22 @@ cr.define('options', function() {
* @return {boolean} True if the final position differs from the original.
*/
finalizePosition: function(id) {
- // Make sure the dragging location is connected.
var displayLayout = this.displayLayoutMap_[id];
var div = displayLayout.div;
var baseLayout = this.getBaseLayout_(displayLayout);
- var baseDiv = baseLayout.div;
var isPrimary = displayLayout.parentId == '';
var layoutType =
isPrimary ? baseLayout.layoutType : displayLayout.layoutType;
- // The number of pixels to share the edges between displays.
- /** @const */ var MIN_OFFSET_OVERLAP = 5;
-
- if (layoutType == options.DisplayLayoutType.LEFT ||
- layoutType == options.DisplayLayoutType.RIGHT) {
- var top = Math.max(
- div.offsetTop,
- baseDiv.offsetTop - div.offsetHeight + MIN_OFFSET_OVERLAP);
- top = Math.min(
- top, baseDiv.offsetTop + baseDiv.offsetHeight - MIN_OFFSET_OVERLAP);
- div.style.top = top + 'px';
- } else {
- var left = Math.max(
- div.offsetLeft,
- baseDiv.offsetLeft - div.offsetWidth + MIN_OFFSET_OVERLAP);
- left = Math.min(
- left,
- baseDiv.offsetLeft + baseDiv.offsetWidth - MIN_OFFSET_OVERLAP);
- div.style.left = left + 'px';
- }
+ // Make sure the dragging location is connected.
+ this.adjustCorners_(div, baseLayout.div, layoutType);
// Calculate the offset of the child display.
this.calculateOffset_(isPrimary ? baseLayout : displayLayout);
- return displayLayout.originalPosition.x != div.offsetLeft ||
- displayLayout.originalPosition.y != div.offsetTop;
+ return displayLayout.originalDivOffsets.x != div.offsetLeft ||
+ displayLayout.originalDivOffsets.y != div.offsetTop;
},
/**
@@ -442,7 +389,6 @@ cr.define('options', function() {
createDisplayLayoutDiv_: function(id, displayAreaDiv) {
var displayLayout = this.displayLayoutMap_[id];
var parentId = displayLayout.parentId;
- var offset = this.displayAreaOffset_;
if (parentId) {
// Ensure the parent div is created first.
var parentLayout = this.displayLayoutMap_[parentId];
@@ -452,6 +398,7 @@ cr.define('options', function() {
var div = /** @type {!HTMLElement} */ (document.createElement('div'));
div.className = 'displays-display';
+ displayLayout.div = div;
// div needs to be added to the DOM tree first, otherwise offsetHeight for
// nameContainer below cannot be computed.
@@ -461,13 +408,31 @@ cr.define('options', function() {
nameContainer.textContent = displayLayout.name;
div.appendChild(nameContainer);
- 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';
+ var newHeight =
+ Math.floor(displayLayout.bounds.height * this.visualScale_);
nameContainer.style.marginTop =
(newHeight - nameContainer.offsetHeight) / 2 + 'px';
+ this.layoutDivFromBounds_(displayLayout);
+
+ displayLayout.originalDivOffsets.x = div.offsetLeft;
+ displayLayout.originalDivOffsets.y = div.offsetTop;
+
+ this.calculateOffset_(displayLayout);
+ },
+
+ /**
+ * Calculates the div layout for displayLayout.
+ * @param {options.DisplayLayout} displayLayout
+ */
+ layoutDivFromBounds_: function(displayLayout) {
+ var div = displayLayout.div;
+ var bounds = displayLayout.bounds;
+
+ div.style.width = Math.floor(bounds.width * this.visualScale_) + 'px';
+ div.style.height = Math.floor(bounds.height * this.visualScale_) + 'px';
+
+ var offset = this.displayAreaOffset_;
if (displayLayout.parentId == '') {
div.style.left =
Math.floor(bounds.left * this.visualScale_) + offset.x + 'px';
@@ -503,15 +468,10 @@ cr.define('options', function() {
}
}
- displayLayout.div = div;
- displayLayout.originalPosition.x = div.offsetLeft;
- displayLayout.originalPosition.y = div.offsetTop;
-
- this.calculateOffset_(displayLayout);
},
/**
- * Calculates the offset for display |id| relative to its parent.
+ * Calculates the offset for displayLayout relative to its parent.
* @param {options.DisplayLayout} displayLayout
*/
calculateOffset_: function(displayLayout) {
@@ -548,6 +508,101 @@ cr.define('options', function() {
}
assertNotReached();
return null;
+ },
+
+ /**
+ * Update the location |div| to the position closest to |newPosition| along
+ * the edge of |parentDiv| specified by |layoutType|.
+ * @param {?HTMLElement} div
+ * @param {options.DisplayPosition} newPosition
+ * @param {?HTMLElement} parentDiv
+ * @param {!options.DisplayLayoutType} layoutType
+ * @private
+ */
+ setDivPosition_(div, newPosition, parentDiv, layoutType) {
+ switch (layoutType) {
+ case options.DisplayLayoutType.RIGHT:
+ div.style.left = parentDiv.offsetLeft + parentDiv.offsetWidth + 'px';
+ div.style.top = newPosition.y + 'px';
+ break;
+ case options.DisplayLayoutType.LEFT:
+ div.style.left = parentDiv.offsetLeft - div.offsetWidth + 'px';
+ div.style.top = newPosition.y + 'px';
+ break;
+ case options.DisplayLayoutType.TOP:
+ div.style.top = parentDiv.offsetTop - div.offsetHeight + 'px';
+ div.style.left = newPosition.x + 'px';
+ break;
+ case options.DisplayLayoutType.BOTTOM:
+ div.style.top = parentDiv.offsetTop + parentDiv.offsetHeight + 'px';
+ div.style.left = newPosition.x + 'px';
+ break;
+ }
+ },
+
+ /**
+ * Snaps the region [point, width] to [basePoint, baseWidth] if
+ * the [point, width] is close enough to the base's edge.
+ * @param {number} point The starting point of the region.
+ * @param {number} width The width of the region.
+ * @param {number} basePoint The starting point of the base region.
+ * @param {number} baseWidth The width of the base region.
+ * @param {number} opt_snapDistance Provide to override the snap distance.
+ * 0 means snap at any distance.
+ * @return {number} The moved point. Returns the point itself if it doesn't
+ * need to snap to the edge.
+ * @private
+ */
+ snapToEdge_: function(
+ point, width, basePoint, baseWidth, opt_snapDistance) {
+ // If the edge of the region is smaller than this, it will snap to the
+ // base's edge.
+ /** @const */ var SNAP_DISTANCE_PX = 16;
+ var snapDist;
+ if (opt_snapDistance !== undefined)
+ snapDist = opt_snapDistance;
+ else
+ snapDist = SNAP_DISTANCE_PX;
+ var startDiff = Math.abs(point - basePoint);
+ var endDiff = Math.abs(point + width - (basePoint + baseWidth));
+ // Prefer the closer one if both edges are close enough.
+ if ((!snapDist || startDiff < snapDist) && startDiff < endDiff)
+ return basePoint;
+ else if (!snapDist || endDiff < SNAP_DISTANCE_PX)
+ return basePoint + baseWidth - width;
+
+ return point;
+ },
+
+ /**
+ * Ensures that there is a minimum overlap when displays meet at a corner.
+ * @param {?HTMLElement} div
+ * @param {?HTMLElement} parentDiv
+ * @param {options.DisplayLayoutType} layoutType
+ * @private
+ */
+ adjustCorners_: function(div, parentDiv, layoutType) {
+ // The number of pixels to share the edges between displays.
+ /** @const */ var MIN_OFFSET_OVERLAP = 5;
+
+ if (layoutType == options.DisplayLayoutType.LEFT ||
+ layoutType == options.DisplayLayoutType.RIGHT) {
+ var top = Math.max(
+ div.offsetTop,
+ parentDiv.offsetTop - div.offsetHeight + MIN_OFFSET_OVERLAP);
+ top = Math.min(
+ top,
+ parentDiv.offsetTop + parentDiv.offsetHeight - MIN_OFFSET_OVERLAP);
+ div.style.top = top + 'px';
+ } else {
+ var left = Math.max(
+ div.offsetLeft,
+ parentDiv.offsetLeft - div.offsetWidth + MIN_OFFSET_OVERLAP);
+ left = Math.min(
+ left,
+ parentDiv.offsetLeft + parentDiv.offsetWidth - MIN_OFFSET_OVERLAP);
+ div.style.left = left + 'px';
+ }
}
};

Powered by Google App Engine
This is Rietveld 408576698