aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2010-09-13 15:24:34 -0700
committerAndroid Code Review <code-review@android.com>2010-09-13 15:24:34 -0700
commit4da6e2e0fc1b88380df824c6733a87082698f3e3 (patch)
treedc8ab494bc97a667835e735e3c1ada9e138f98b6 /eclipse
parent0f7811529cfb7dbe306b390daa0afcc887b00245 (diff)
parent6f82c5b682576f9ecba3e776230f7326c340cc7d (diff)
downloadsdk-4da6e2e0fc1b88380df824c6733a87082698f3e3.zip
sdk-4da6e2e0fc1b88380df824c6733a87082698f3e3.tar.gz
sdk-4da6e2e0fc1b88380df824c6733a87082698f3e3.tar.bz2
Merge "GLE2: proper feedback on invalid drop targets."
Diffstat (limited to 'eclipse')
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.RelativeLayout.groovy2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DropFeedback.java35
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasDropListener.java43
3 files changed, 65 insertions, 15 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.RelativeLayout.groovy b/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.RelativeLayout.groovy
index 6d97103..60b5998 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.RelativeLayout.groovy
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.RelativeLayout.groovy
@@ -221,6 +221,8 @@ public class AndroidWidgetRelativeLayoutRule extends BaseLayout {
feedback.requestPaint = true;
}
+ feedback.invalidTarget = (currZone == null);
+
return feedback;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DropFeedback.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DropFeedback.java
index 82a07a9..af26ebf 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DropFeedback.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DropFeedback.java
@@ -19,26 +19,53 @@ package com.android.ide.eclipse.adt.editors.layout.gscripts;
import groovy.lang.Closure;
/**
- * Returned by onDropEnter/Move and passed to over onDropXyz methods.
+ * Structure returned by onDropEnter/Move and passed to over onDropXyz methods.
*/
public class DropFeedback {
/**
* User data that the rule can use in any way it wants to carry state from one
* operation to another.
+ * <p/>
+ * Filled and owned by the groovy view rule.
*/
public Object userData;
/**
* If true the next screen update will invoke the paint closure.
+ * <p/>
+ * Filled by the groovy view rule to request a paint, and reset by the canvas
+ * after the paint occurred.
*/
public boolean requestPaint;
/**
+ * Set to false by the engine when entering a new view target.
+ * The groovy view rule should set this to true if the current view target is not
+ * a valid drop zone.
+ * <p/>
+ * When set to true, the onDropped() method will not be called if the user releases
+ * the mouse button. Depending on the platform or implementation, the mouse cursor
+ * <em>may</em> reflect that the drop operation is invalid.
+ * <p/>
+ * Rationale: an operation like onDropEnter() is called each time the mouse enters
+ * a new view target and is supposed to return null when the drop cannot happen
+ * <em>at all</em> in that target. However a layout like RelativeLayout decorates
+ * potential targets with "hot spots" that are suitable drop zones, whereas some
+ * other parts of the view are not suitable drop zones. In this case the onDropEnter()
+ * or onDropMove() operation would return a {@link DropFeedback} with
+ * <code>invalidTarget=true</code>.
+ */
+ public boolean invalidTarget;
+
+ /**
* Closure invoked by the canvas to paint the feedback.
+ * <p/>
* The closure will receive 3 arguments: <br/>
* - The {@link IGraphics} context to use for painting. Must not be cached. <br/>
* - The {@link INode} target node last used in a onDropEnter or onDropMove call. <br/>
* - The {@link DropFeedback} returned by the last onDropEnter or onDropMove call. <br/>
+ * <p/>
+ * Filled by the groovy view rule, called by the engine.
*/
public Closure paintClosure;
@@ -48,6 +75,8 @@ public class DropFeedback {
* <p/>
* When the mouse is captured, drop events will keep going to the rule that started the
* capture and the current INode proxy will not change.
+ * <p/>
+ * Filled by the groovy view rule, read by the engine.
*/
public Rect captureArea;
@@ -55,12 +84,16 @@ public class DropFeedback {
* Set to true by the drag'n'drop engine when the current drag operation is a copy.
* When false the operation is a move and <em>after</em> a successful drop the source
* elements will be deleted.
+ * <p/>
+ * Filled by the engine, read by groovy view rule.
*/
public boolean isCopy;
/**
* Set to true when the drag'n'drop starts and ends in the same canvas of the
* same Eclipse instance.
+ * <p/>
+ * Filled by the engine, read by groovy view rule.
*/
public boolean sameCanvas;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasDropListener.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasDropListener.java
index 8c4e46f..fc06381 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasDropListener.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasDropListener.java
@@ -221,6 +221,11 @@ import java.util.Arrays;
mCurrentView = mLeaveView;
}
+ if (mFeedback != null && mFeedback.invalidTarget) {
+ // The script said we can't drop here.
+ event.detail = DND.DROP_NONE;
+ }
+
if (mLeaveTargetNode == null || event.detail == DND.DROP_NONE) {
clearDropInfo();
}
@@ -292,6 +297,7 @@ import java.util.Arrays;
df.isCopy = event.detail == DND.DROP_COPY;
}
df.sameCanvas = mCanvas == mGlobalDragInfo.getSourceCanvas();
+ df.invalidTarget = false;
}
/**
@@ -300,8 +306,8 @@ import java.util.Arrays;
*/
public void paintFeedback(GCWrapper gCWrapper) {
if (mTargetNode != null && mFeedback != null && mFeedback.requestPaint) {
- mFeedback.requestPaint = false;
mCanvas.getRulesEngine().callDropFeedbackPaint(gCWrapper, mTargetNode, mFeedback);
+ mFeedback.requestPaint = false;
}
}
@@ -428,29 +434,22 @@ import java.util.Arrays;
}
}
- if (df != null && targetNode != mTargetNode) {
+ if (df == null) {
+ // Provide visual feedback that we are refusing the drop
+ event.detail = DND.DROP_NONE;
+ clearDropInfo();
+
+ } else if (targetNode != mTargetNode) {
// We found a new target node for the drag'n'drop.
// Release the previous one, if any.
callDropLeave();
- // If we previously provided visual feedback that we were refusing
- // the drop, we now need to change it to mean we're accepting it.
- if (event.detail == DND.DROP_NONE) {
- event.detail = DND.DROP_DEFAULT;
- recomputeDragType(event);
- }
-
// And assign the new one
mTargetNode = targetNode;
mFeedback = df;
// We don't need onDropMove in this case
isMove = false;
-
- } else if (df == null) {
- // Provide visual feedback that we are refusing the drop
- event.detail = DND.DROP_NONE;
- clearDropInfo();
}
}
@@ -464,14 +463,30 @@ import java.util.Arrays;
updateDropFeedback(mFeedback, event);
DropFeedback df = mCanvas.getRulesEngine().callOnDropMove(
mTargetNode, mCurrentDragElements, mFeedback, p2);
+
if (df == null) {
// The target is no longer interested in the drop move.
+ event.detail = DND.DROP_NONE;
callDropLeave();
+
} else if (df != mFeedback) {
mFeedback = df;
}
}
+ if (mFeedback != null) {
+ if (event.detail == DND.DROP_NONE && !mFeedback.invalidTarget) {
+ // If we previously provided visual feedback that we were refusing
+ // the drop, we now need to change it to mean we're accepting it.
+ event.detail = DND.DROP_DEFAULT;
+ recomputeDragType(event);
+
+ } else if (mFeedback.invalidTarget) {
+ // Provide visual feedback that we are refusing the drop
+ event.detail = DND.DROP_NONE;
+ }
+ }
+
if (needRedraw || (mFeedback != null && mFeedback.requestPaint)) {
mCanvas.redraw();
}