From b8235512174daabfc899ff71b5ffd9241556d305 Mon Sep 17 00:00:00 2001 From: Tor Norbye Date: Mon, 15 Nov 2010 15:04:31 -0800 Subject: [PATCH] Improvements to LinearLayout feedback When you have a small and empty linear layout, and you drag something larger (such as a button) into it, the drop feedback is a bit confusing: The drop feedback rectangle is larger than the linear layout, so the bounds are outside the layout. This changeset addresses this by forcing the bounds of the drop preview to be at most the dimensions of the LinearLayout itself. Second, the fix I applied last week to show the last insert position, did not work in all cases - in particular when the drag originates outside the canvas itself. To determine if we are inserting at the last position, look at the number of target node children, rather than the number of potential insert positions, since in some cases the number of insert positions will be smaller than the number of children. Finally, there was a theoretical bug that if one of the dragged elements did not non-zero bounds, then the insert position would be wrong. This is also fixed by this changeset. Change-Id: Ia30e99f7a3aa45b8091855b69aaef86ec3699405 --- .../ide/common/layout/LinearLayoutRule.java | 36 +++++++++++++++++++--- .../ide/common/layout/LinearLayoutRuleTest.java | 8 ++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LinearLayoutRule.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LinearLayoutRule.java index bc2716a21..e5334f809 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LinearLayoutRule.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LinearLayoutRule.java @@ -140,6 +140,10 @@ public class LinearLayoutRule extends BaseLayout { last = isVertical ? (bc.y + bc.h) : (bc.x + bc.w); lastDragged = isDragged; + } else { + // We still have to count this position even if it has no bounds, or + // subsequent children will be inserted at the wrong place + pos++; } } @@ -150,7 +154,8 @@ public class LinearLayoutRule extends BaseLayout { indexes.add(new MatchPos(v, pos)); } - return new DropFeedback(new LinearDropData(indexes, isVertical, selfPos), + int posCount = targetNode.getChildren().length + 1; + return new DropFeedback(new LinearDropData(indexes, posCount, isVertical, selfPos), new IFeedbackPainter() { public void paint(IGraphics gc, INode node, DropFeedback feedback) { @@ -223,7 +228,7 @@ public class LinearLayoutRule extends BaseLayout { } if (be.isValid()) { - boolean isLast = (data.getInsertPos() == data.getIndexes().size()); + boolean isLast = data.isLastPosition(); // At least the first element has a bound. Draw rectangles for // all dropped elements with valid bounds, offset at the drop @@ -241,7 +246,16 @@ public class LinearLayoutRule extends BaseLayout { gc.useStyle(DrawingStyle.DROP_PREVIEW); for (IDragElement element : elements) { - drawElement(gc, element, offsetX, offsetY); + Rect bounds = element.getBounds(); + if (bounds.isValid() && (bounds.w > b.w || bounds.h > b.h)) { + // The bounds of the child does not fully fit inside the target. + // Limit the bounds to the layout bounds. + Rect within = new Rect(b.x, b.y, + Math.min(bounds.w, b.w), Math.min(bounds.h, b.h)); + gc.drawRect(within); + } else { + drawElement(gc, element, offsetX, offsetY); + } } } } @@ -390,6 +404,9 @@ public class LinearLayoutRule extends BaseLayout { /** Insert points (pixels + index) */ private final List mIndexes; + /** Number of insert positions in the target node */ + private final int mNumPositions; + /** Current marker X position */ private Integer mCurrX; @@ -409,8 +426,10 @@ public class LinearLayoutRule extends BaseLayout { /** height of match line if it's a vertical one */ private Integer mHeight; - public LinearDropData(List indexes, boolean isVertical, int selfPos) { + public LinearDropData(List indexes, int numPositions, + boolean isVertical, int selfPos) { this.mIndexes = indexes; + this.mNumPositions = numPositions; this.mVertical = isVertical; this.mSelfPos = selfPos; } @@ -479,5 +498,14 @@ public class LinearLayoutRule extends BaseLayout { private Integer getHeight() { return mHeight; } + + /** + * Returns true if we are inserting into the last position + * + * @return true if we are inserting into the last position + */ + public boolean isLastPosition() { + return mInsertPos == mNumPositions - 1; + } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LinearLayoutRuleTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LinearLayoutRuleTest.java index c5c43fda9..979610496 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LinearLayoutRuleTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/LinearLayoutRuleTest.java @@ -75,7 +75,7 @@ public class LinearLayoutRuleTest extends AbstractLayoutRuleTest { // Insert position line "drawLine(1,0,1,480)" + (haveBounds ? // Outline of dragged node centered over position line - ", useStyle(DROP_PREVIEW), " + "drawRect(Rect[-49,0,100,80])" + ", useStyle(DROP_PREVIEW), " + "drawRect(Rect[1,0,100,80])" // Nothing when we don't have bounds : "") + "]", graphics.getDrawn().toString()); @@ -207,17 +207,17 @@ public class LinearLayoutRuleTest extends AbstractLayoutRuleTest { // Drop zones "useStyle(DROP_ZONE), drawLine(0,0,240,0), drawLine(0,90,240,90), " - + "drawLine(0,190,240,190), drawLine(0,290,240,290)", + + "drawLine(0,190,240,190), drawLine(0,290,240,290), drawLine(0,381,240,381), ", // Active nearest line "useStyle(DROP_ZONE_ACTIVE), useStyle(DROP_PREVIEW), drawLine(0,381,240,381)", // Preview of the dropped rectangle - "useStyle(DROP_PREVIEW), drawRect(Rect[0,341,105,80])"); + "useStyle(DROP_PREVIEW), drawRect(Rect[0,381,105,80])"); // Check without bounds too dragInto(true, new Rect(0, 0, 105, 80), new Point(30, 500), 4, -1, - "useStyle(DROP_PREVIEW), drawRect(Rect[0,341,105,80])"); + "useStyle(DROP_PREVIEW), drawRect(Rect[0,381,105,80])"); } public void testDragInVerticalMiddle() { -- 2.11.0