aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2011-10-20 18:06:51 -0700
committerTor Norbye <tnorbye@google.com>2011-10-26 13:29:53 -0700
commitfadd53c9ef6d046a60919e89eed1380696b67b7a (patch)
tree9d3c8156f7daab13fb86284e789d906e68e381ca /eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common
parent8027fad9680e1622d7c70be330422d6b11fc6c88 (diff)
downloadsdk-fadd53c9ef6d046a60919e89eed1380696b67b7a.tar.gz
Misc GridLayout handling fixes
This changeset fixes some miscellaneous in the GridLayout support. The gravity handling code (which creates a bitmask for gravity from XML attribute values) was pulled out of the change layout refactoring such that it can also be used by the GridLayout. This is done to figure out where cells are not bound to the top or left corners, in which case they should not be considered when computing a suitable right or bottom edge for splitting a cell. There's also fixes for a problem where certain negative constraints would be offered, there were tooltips when only one of the two dimensions produced suggestions (and you can only drop when both are valid). When removing children back to a blank layout, reset the columCount to 2. And finally there were some problems where the columnCount was larger than the number of actual used columns in the table, where dragging near top/left corner would use some of the later columns rather than the first available one. Change-Id: Ice22754fb14659812b54019452aeca6daaeede10
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/GravityHelper.java99
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java47
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridModel.java65
3 files changed, 152 insertions, 59 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/GravityHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/GravityHelper.java
new file mode 100644
index 000000000..b2f769e72
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/GravityHelper.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.common.layout;
+
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_GRAVITY;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_BOTTOM;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_CENTER;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_CENTER_HORIZONTAL;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_CENTER_VERTICAL;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_FILL;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_FILL_HORIZONTAL;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_FILL_VERTICAL;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_LEFT;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_RIGHT;
+import static com.android.ide.common.layout.LayoutConstants.GRAVITY_VALUE_TOP;
+
+import org.w3c.dom.Element;
+
+/** Helper class for looking up the gravity masks of gravity attributes */
+public class GravityHelper {
+ public static final int GRAVITY_LEFT = 1 << 0;
+ public static final int GRAVITY_RIGHT = 1 << 1;
+ public static final int GRAVITY_CENTER_HORIZ = 1 << 2;
+ public static final int GRAVITY_FILL_HORIZ = 1 << 3;
+ public static final int GRAVITY_CENTER_VERT = 1 << 4;
+ public static final int GRAVITY_FILL_VERT = 1 << 5;
+ public static final int GRAVITY_TOP = 1 << 6;
+ public static final int GRAVITY_BOTTOM = 1 << 7;
+ public static final int GRAVITY_HORIZ_MASK = GRAVITY_CENTER_HORIZ | GRAVITY_FILL_HORIZ
+ | GRAVITY_LEFT | GRAVITY_RIGHT;
+ public static final int GRAVITY_VERT_MASK = GRAVITY_CENTER_VERT | GRAVITY_FILL_VERT
+ | GRAVITY_TOP | GRAVITY_BOTTOM;
+
+ /**
+ * Returns the gravity of the given element
+ *
+ * @param element the element to look up the gravity for
+ * @return a bit mask corresponding to the selected gravities
+ */
+ public static int getGravity(Element element) {
+ String gravityString = element.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_GRAVITY);
+ return getGravity(gravityString, GRAVITY_LEFT | GRAVITY_TOP);
+ }
+
+ /**
+ * Returns the gravity bitmask for the given gravity string description
+ *
+ * @param gravityString the gravity string description
+ * @param defaultMask the default/initial bitmask to start with
+ * @return a bitmask corresponding to the gravity description
+ */
+ public static int getGravity(String gravityString, int defaultMask) {
+ int gravity = defaultMask;
+ if (gravityString != null && gravityString.length() > 0) {
+ String[] anchors = gravityString.split("\\|"); //$NON-NLS-1$
+ for (String anchor : anchors) {
+ if (GRAVITY_VALUE_CENTER.equals(anchor)) {
+ gravity = GRAVITY_CENTER_HORIZ | GRAVITY_CENTER_VERT;
+ } else if (GRAVITY_VALUE_FILL.equals(anchor)) {
+ gravity = GRAVITY_FILL_HORIZ | GRAVITY_FILL_VERT;
+ } else if (GRAVITY_VALUE_CENTER_VERTICAL.equals(anchor)) {
+ gravity = (gravity & GRAVITY_HORIZ_MASK) | GRAVITY_CENTER_VERT;
+ } else if (GRAVITY_VALUE_CENTER_HORIZONTAL.equals(anchor)) {
+ gravity = (gravity & GRAVITY_VERT_MASK) | GRAVITY_CENTER_HORIZ;
+ } else if (GRAVITY_VALUE_FILL_VERTICAL.equals(anchor)) {
+ gravity = (gravity & GRAVITY_HORIZ_MASK) | GRAVITY_FILL_VERT;
+ } else if (GRAVITY_VALUE_FILL_HORIZONTAL.equals(anchor)) {
+ gravity = (gravity & GRAVITY_VERT_MASK) | GRAVITY_FILL_HORIZ;
+ } else if (GRAVITY_VALUE_TOP.equals(anchor)) {
+ gravity = (gravity & GRAVITY_HORIZ_MASK) | GRAVITY_TOP;
+ } else if (GRAVITY_VALUE_BOTTOM.equals(anchor)) {
+ gravity = (gravity & GRAVITY_HORIZ_MASK) | GRAVITY_BOTTOM;
+ } else if (GRAVITY_VALUE_LEFT.equals(anchor)) {
+ gravity = (gravity & GRAVITY_VERT_MASK) | GRAVITY_LEFT;
+ } else if (GRAVITY_VALUE_RIGHT.equals(anchor)) {
+ gravity = (gravity & GRAVITY_VERT_MASK) | GRAVITY_RIGHT;
+ } else {
+ // "clip" not supported
+ }
+ }
+ }
+
+ return gravity;
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java
index 9f8e0b114..796252bce 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java
@@ -80,6 +80,7 @@ public class GridDropHandler {
*/
public void computeMatches(DropFeedback feedback, Point p) {
mRowMatch = mColumnMatch = null;
+ feedback.tooltip = null;
Rect bounds = mGrid.layout.getBounds();
int x1 = p.x;
@@ -113,7 +114,7 @@ public class GridDropHandler {
addCenterColumnMatch(bounds, x1, y1, x2, y2, columnMatches, max);
// Row matches:
- int row = mGrid.getClosestRow(y1);
+ int row = (mGrid.getViewCount() == 0) ? 0 : mGrid.getClosestRow(y1);
int rowY = mGrid.getRowY(row);
addTopMatch(y1, rowMatches, max, row, rowY);
addBaselineMatch(feedback.dragBaseline, y1, rowMatches, max, row, rowY);
@@ -138,13 +139,13 @@ public class GridDropHandler {
}
- if (columnMatches.size() == 0) {
+ if (columnMatches.size() == 0 && x1 >= bounds.x) {
// Split the current cell since we have no matches
// TODO: Decide whether it should be gravity left or right...
columnMatches.add(new GridMatch(SegmentType.LEFT, 0, x1, mGrid.getColumn(x1),
true /* createCell */, UNDEFINED));
}
- if (rowMatches.size() == 0) {
+ if (rowMatches.size() == 0 && y1 >= bounds.y) {
rowMatches.add(new GridMatch(SegmentType.TOP, 0, y1, mGrid.getRow(y1),
true /* createCell */, UNDEFINED));
}
@@ -165,16 +166,9 @@ public class GridDropHandler {
mRowMatch = rowMatches.get(0);
rowDescription = mRowMatch.getDisplayName(mGrid.layout);
}
- if (columnDescription != null) {
- if (rowDescription != null) {
- feedback.tooltip = columnDescription + '\n' + rowDescription;
- } else {
- feedback.tooltip = columnDescription;
- }
- } else if (rowDescription != null) {
- feedback.tooltip = rowDescription;
- } else {
- feedback.tooltip = null;
+
+ if (columnDescription != null && rowDescription != null) {
+ feedback.tooltip = columnDescription + '\n' + rowDescription;
}
feedback.invalidTarget = mColumnMatch == null || mRowMatch == null;
@@ -214,7 +208,7 @@ public class GridDropHandler {
* Adds a match to align the left edge with some other edge.
*/
private void addLeftSideMatch(int x1, List<GridMatch> columnMatches, int max) {
- int column = mGrid.getClosestColumn(x1);
+ int column = (mGrid.getViewCount() == 0) ? 0 : mGrid.getClosestColumn(x1);
int columnX = mGrid.getColumnX(column);
int distance = abs(columnX - x1);
if (distance <= max) {
@@ -229,11 +223,14 @@ public class GridDropHandler {
private void addRightSideMatch(int x2, List<GridMatch> columnMatches, int max) {
// TODO: Only match the right hand side if the drag bounds fit fully within the
// cell! Ditto for match below.
- int columnRight = mGrid.getClosestColumn(x2);
+ int columnRight = (mGrid.getViewCount() == 0) ? 0 : mGrid.getClosestColumn(x2);
int rightDistance = mGrid.getColumnDistance(columnRight, x2);
if (rightDistance < max) {
- columnMatches.add(new GridMatch(SegmentType.RIGHT, rightDistance,
- mGrid.getColumnX(columnRight), columnRight, false, UNDEFINED));
+ int columnX = mGrid.getColumnX(columnRight);
+ if (columnX > mGrid.layout.getBounds().x) {
+ columnMatches.add(new GridMatch(SegmentType.RIGHT, rightDistance, columnX,
+ columnRight, false, UNDEFINED));
+ }
}
}
@@ -270,12 +267,14 @@ public class GridDropHandler {
* Adds a match to align the bottom edge with some other edge.
*/
private void addBottomMatch(int y2, List<GridMatch> rowMatches, int max) {
- int rowBottom = mGrid.getClosestRow(y2);
+ int rowBottom = (mGrid.getViewCount() == 0) ? 0 : mGrid.getClosestRow(y2);
int distance = mGrid.getRowDistance(rowBottom, y2);
if (distance < max) {
int rowY = mGrid.getRowY(rowBottom);
- rowMatches.add(new GridMatch(SegmentType.BOTTOM, distance, rowY,
- rowBottom, false, UNDEFINED));
+ if (rowY > mGrid.layout.getBounds().y) {
+ rowMatches.add(new GridMatch(SegmentType.BOTTOM, distance, rowY,
+ rowBottom, false, UNDEFINED));
+ }
}
}
@@ -493,10 +492,10 @@ public class GridDropHandler {
//sr1.setAttribute(ANDROID_URI, ATTR_LAYOUT_ROW_WEIGHT, VALUE_1);
//sc1.setAttribute(ANDROID_URI, ATTR_LAYOUT_GRAVITY, VALUE_FILL_HORIZONTAL);
//sr1.setAttribute(ANDROID_URI, ATTR_LAYOUT_GRAVITY, VALUE_FILL_VERTICAL);
-
- mGrid.loadFromXml();
- column = mGrid.getColumn(columnX);
- row = mGrid.getRow(rowY);
+ //
+ //mGrid.loadFromXml();
+ //column = mGrid.getColumn(columnX);
+ //row = mGrid.getRow(rowY);
}
int startX, endX;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridModel.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridModel.java
index df3727cad..1e4d5cd45 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridModel.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridModel.java
@@ -15,6 +15,10 @@
*/
package com.android.ide.common.layout.grid;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_BOTTOM;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_HORIZ;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_CENTER_VERT;
+import static com.android.ide.common.layout.GravityHelper.GRAVITY_RIGHT;
import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
import static com.android.ide.common.layout.LayoutConstants.ATTR_COLUMN_COUNT;
import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
@@ -43,6 +47,7 @@ import com.android.ide.common.api.INode;
import com.android.ide.common.api.IViewMetadata;
import com.android.ide.common.api.Margins;
import com.android.ide.common.api.Rect;
+import com.android.ide.common.layout.GravityHelper;
import com.android.ide.common.layout.GridLayoutRule;
import com.android.util.Pair;
@@ -622,11 +627,13 @@ public class GridModel {
}
// The bounds should be in ascending order now
- for (int i = 1; i < actualRowCount; i++) {
- assert mTop[i + 1] >= mTop[i];
- }
- for (int i = 0; i < actualColumnCount; i++) {
- assert mLeft[i + 1] >= mLeft[i];
+ if (GridLayoutRule.sDebugGridLayout) {
+ for (int i = 1; i < actualRowCount; i++) {
+ assert mTop[i + 1] >= mTop[i];
+ }
+ for (int i = 0; i < actualColumnCount; i++) {
+ assert mLeft[i + 1] >= mLeft[i];
+ }
}
}
@@ -661,10 +668,12 @@ public class GridModel {
y2 -= insets.bottom;
}
}
- if (mMaxRight[targetColumn] < x2) {
+ if (mMaxRight[targetColumn] < x2
+ && ((view.gravity & (GRAVITY_CENTER_HORIZ | GRAVITY_RIGHT)) == 0)) {
mMaxRight[targetColumn] = x2;
}
- if (mMaxBottom[targetRow] < y2) {
+ if (mMaxBottom[targetRow] < y2
+ && ((view.gravity & (GRAVITY_CENTER_VERT | GRAVITY_BOTTOM)) == 0)) {
mMaxBottom[targetRow] = y2;
}
}
@@ -1602,8 +1611,7 @@ public class GridModel {
public int column;
public int rowSpan;
public int columnSpan;
- //public final float rowWeight;
- //public final float columnWeight;
+ public int gravity;
ViewData(INode n, int index) {
node = n;
@@ -1613,31 +1621,8 @@ public class GridModel {
columnSpan = getInt(n, ATTR_LAYOUT_COLUMN_SPAN, 1);
row = getInt(n, ATTR_LAYOUT_ROW, UNDEFINED);
rowSpan = getInt(n, ATTR_LAYOUT_ROW_SPAN, 1);
-
- // Weights are in flux
- //
- //String width = n.getStringAttr(ANDROID_URI, ATTR_LAYOUT_WIDTH);
- //float colDefaultWeight;
- //if (VALUE_MATCH_PARENT.equals(width) || VALUE_FILL_PARENT.equals(width)) {
- // colDefaultWeight = 1.0f;
- //} else {
- // colDefaultWeight = 0.0f;
- //}
- //String height = n.getStringAttr(ANDROID_URI, ATTR_LAYOUT_HEIGHT);
- //float rowDefaultWeight;
- //if (VALUE_MATCH_PARENT.equals(height) || VALUE_FILL_PARENT.equals(height)) {
- // rowDefaultWeight = 1.0f;
- //} else {
- // rowDefaultWeight = 0.0f;
- //}
- //
- //columnWeight = getFloat(n, ATTR_LAYOUT_COLUMN_WEIGHT, colDefaultWeight);
- //rowWeight = getFloat(n, ATTR_LAYOUT_ROW_WEIGHT, rowDefaultWeight);
-
- // Interval hSpan = new Interval(column, column + columnSpan);
- // this.columnGroup = new Group(hSpan, getColumnAlignment(gravity, width));
- // Interval vSpan = new Interval(row, row + rowSpan);
- // this.rowGroup = new Group(vSpan, getRowAlignment(gravity, height));
+ gravity = GravityHelper.getGravity(n.getStringAttr(ANDROID_URI, ATTR_LAYOUT_GRAVITY),
+ 0);
}
/** Applies the column and row fields into the XML model */
@@ -1783,6 +1768,7 @@ public class GridModel {
for (ViewData spacer : rowSpacers.values()) {
layout.removeChild(spacer.node);
}
+ layout.setAttribute(ANDROID_URI, ATTR_COLUMN_COUNT, Integer.toString(2));
return;
}
@@ -2059,4 +2045,13 @@ public class GridModel {
return defaultValue;
}
-} \ No newline at end of file
+
+ /**
+ * Returns the number of children views in the GridLayout
+ *
+ * @return the number of children views in the GridLayout
+ */
+ public int getViewCount() {
+ return mChildViews.size();
+ }
+}