OSDN Git Service

Fix drag and drop handler to handle reentry
authorTor Norbye <tnorbye@google.com>
Tue, 12 Oct 2010 16:41:22 +0000 (09:41 -0700)
committerTor Norbye <tnorbye@google.com>
Tue, 12 Oct 2010 16:41:22 +0000 (09:41 -0700)
If you drag from the palette over a linear layout view, you get drop
feedback. However, if you drag outside the linear layout and then back
in, you often don't get any more feedback. This happens pretty easily
with nested layouts.

The problem is that the feedback object is initialized and reset in
onDropEnter, but the actual guideline computation happens in
onDropMove (since only drop move is handed the mouse coordinates). The
bug happens because when you leave and return to the drop zone, the
feedback object is reset, and then the drop feedback is painted - all
before the onDropMove code has been called again.

The fix is simple: On drop enter, also call onDropMove immediately
such that the layout helpers are given a chance to initialize
themselves with the entry mouse position, before they are consulted
for drop feedback data.

This changeset also contains a fix for LinearLayouts: When there are
no children, place the guideline at x=0 or y=0 (depending on whether
the layout is horizontal or vertical). Without this fix, the line is
placed in the center of the view, which is misleading since that is
not where the view will be placed upon drop.

Change-Id: Ib5e17a2d9d3818677e4209126233bbde527207c8

eclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.LinearLayout.groovy
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasDropListener.java

index 51334a2..522f226 100755 (executable)
@@ -102,7 +102,7 @@ public class AndroidWidgetLinearLayoutRule extends BaseLayout {
         }
 
         int v = isVertical ? (bn.y + bn.h) : (bn.x + bn.w);
-        v = (last + v) / 2;
+        v = indexes.isEmpty() ? last + 1 : (last + v) / 2;
         indexes.add( [v, -1] );
 
         return new DropFeedback(
index fc06381..d5bfa81 100755 (executable)
@@ -407,6 +407,18 @@ import java.util.Arrays;
                     df = mCanvas.getRulesEngine().callOnDropEnter(targetNode,
                                                                   mCurrentDragElements);
 
+                    if (df != null) {
+                        // We should also dispatch an onDropMove() call to the initial enter
+                        // position, such that the view is notified of the position where
+                        // we are within the node immediately (before we for example attempt
+                        // to draw feedback). This is necessary since most views perform the
+                        // guideline computations in onDropMove (since only onDropMove is handed
+                        // the -position- of the mouse), and we want this computation to happen
+                        // before we ask the view to draw its feedback.
+                        df = mCanvas.getRulesEngine().callOnDropMove(targetNode,
+                                mCurrentDragElements, df, p);
+                    }
+
                     if (df != null &&
                             event.detail == DND.DROP_MOVE &&
                             mCanvas == mGlobalDragInfo.getSourceCanvas()) {