diff options
author | Raphael Moll <ralf@android.com> | 2010-09-13 15:24:34 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2010-09-13 15:24:34 -0700 |
commit | 4da6e2e0fc1b88380df824c6733a87082698f3e3 (patch) | |
tree | dc8ab494bc97a667835e735e3c1ada9e138f98b6 /eclipse/plugins | |
parent | 0f7811529cfb7dbe306b390daa0afcc887b00245 (diff) | |
parent | 6f82c5b682576f9ecba3e776230f7326c340cc7d (diff) | |
download | sdk-4da6e2e0fc1b88380df824c6733a87082698f3e3.zip sdk-4da6e2e0fc1b88380df824c6733a87082698f3e3.tar.gz sdk-4da6e2e0fc1b88380df824c6733a87082698f3e3.tar.bz2 |
Merge "GLE2: proper feedback on invalid drop targets."
Diffstat (limited to 'eclipse/plugins')
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(); } |