diff options
author | Tor Norbye <tnorbye@google.com> | 2011-07-29 12:16:49 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2011-07-29 12:16:49 -0700 |
commit | 1706a4a2a0727473c96d0f08e53d60400fed824a (patch) | |
tree | e80a00cc4007c96d11619c89faddfcd191267e21 | |
parent | 4b1ba10feb7d7922a39602d25c9d90086d5eae3e (diff) | |
parent | cb7c663420f00194d14c511d4e5a14e3622200a9 (diff) | |
download | sdk-1706a4a2a0727473c96d0f08e53d60400fed824a.zip sdk-1706a4a2a0727473c96d0f08e53d60400fed824a.tar.gz sdk-1706a4a2a0727473c96d0f08e53d60400fed824a.tar.bz2 |
Merge "Add tooltip drag feedback for relative layout"
5 files changed, 110 insertions, 20 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/DropFeedback.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/DropFeedback.java index 551cb3c..4be9c9e 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/DropFeedback.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/api/DropFeedback.java @@ -148,6 +148,16 @@ public class DropFeedback { public String tooltip; /** + * Horizontal alignment for the tooltip, or null if no preference + */ + public SegmentType tooltipX; + + /** + * Vertical alignment for the tooltip, or null if no preference + */ + public SegmentType tooltipY; + + /** * A mask of the currently held keyboard modifier keys - some combination of * {@link #MODIFIER1}, {@link #MODIFIER2}, {@link #MODIFIER3}, or none. */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java index 8299be3..7a6b07f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/relative/GuidelinePainter.java @@ -30,6 +30,7 @@ import com.android.ide.common.api.IGraphics; import com.android.ide.common.api.INode; import com.android.ide.common.api.Point; import com.android.ide.common.api.Rect; +import com.android.ide.common.api.SegmentType; import com.android.ide.common.layout.relative.DependencyGraph.Constraint; import java.util.ArrayList; @@ -103,18 +104,30 @@ public final class GuidelinePainter implements IFeedbackPainter { state.mBottomMargin, ATTR_LAYOUT_MARGIN_BOTTOM); if (strings.size() > 0) { - gc.useStyle(DrawingStyle.HELP); - Rect b = state.layout.getBounds(); - int x, y; - if (b.w > b.h) { - x = b.x + 3; - y = b.y2() + 6; - } else { - x = b.x2() + 6; - y = b.y + 3; + // Update the drag tooltip + StringBuilder sb = new StringBuilder(200); + for (String s : strings) { + if (sb.length() > 0) { + sb.append('\n'); + } + sb.append(s); } - - gc.drawBoxedStrings(x, y, strings); + feedback.tooltip = sb.toString(); + + // Set the tooltip orientation to ensure that it does not interfere with + // the constraint arrows + if (state.mCurrentLeftMatch != null) { + feedback.tooltipX = SegmentType.RIGHT; + } else if (state.mCurrentRightMatch != null) { + feedback.tooltipX = SegmentType.LEFT; + } + if (state.mCurrentTopMatch != null) { + feedback.tooltipY = SegmentType.BOTTOM; + } else if (state.mCurrentBottomMatch != null) { + feedback.tooltipY = SegmentType.TOP; + } + } else { + feedback.tooltip = null; } if (state.mHorizontalCycle != null) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureManager.java index 8c4bf15..151a240 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureManager.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureManager.java @@ -19,6 +19,7 @@ package com.android.ide.eclipse.adt.internal.editors.layout.gle2; import com.android.ide.common.api.DropFeedback; import com.android.ide.common.api.IViewRule; import com.android.ide.common.api.Rect; +import com.android.ide.common.api.SegmentType; import com.android.ide.eclipse.adt.internal.editors.layout.gre.NodeProxy; import com.android.sdklib.SdkConstants; import com.android.util.Pair; @@ -398,11 +399,19 @@ public class GestureManager { // Tooltip if (feedback != null && feedback.tooltip != null) { + Pair<Boolean,Boolean> position = mCurrentGesture.getTooltipPosition(); + boolean below = position.getFirst(); + if (feedback.tooltipY != null) { + below = feedback.tooltipY == SegmentType.BOTTOM; + } + boolean toRightOf = position.getSecond(); + if (feedback.tooltipX != null) { + toRightOf = feedback.tooltipX == SegmentType.RIGHT; + } if (mTooltip == null) { - Pair<Boolean,Boolean> position = mCurrentGesture.getTooltipPosition(); - mTooltip = new GestureToolTip(mCanvas, position.getFirst(), position.getSecond()); + mTooltip = new GestureToolTip(mCanvas, below, toRightOf); } - mTooltip.update(feedback.tooltip); + mTooltip.update(feedback.tooltip, below, toRightOf); } else if (mTooltip != null) { mTooltip.dispose(); mTooltip = null; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureToolTip.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureToolTip.java index 7d71ec7..b75f4d1 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureToolTip.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureToolTip.java @@ -34,6 +34,9 @@ import org.eclipse.swt.widgets.Shell; * have setter methods to update the text or position without recreating the tip. */ public class GestureToolTip { + /** Minimum number of milliseconds to wait between alignment changes */ + private static final int TIMEOUT_MS = 750; + /** * The alpha to use for the tooltip window (which sadly will apply to the tooltip text * as well.) @@ -58,12 +61,24 @@ public class GestureToolTip { /** The font shown in the label; held here such that it can be disposed of after use */ private Font mFont; - /** Should the tooltip be displayed below the cursor? */ + /** Is the tooltip positioned below the given anchor? */ private boolean mBelow; - /** Should the tooltip be displayed to the right of the cursor? */ + /** Is the tooltip positioned to the right of the given anchor? */ private boolean mToRightOf; + /** Is an alignment change pending? */ + private boolean mTimerPending; + + /** The new value for {@link #mBelow} when the timer expires */ + private boolean mPendingBelow; + + /** The new value for {@link #mToRightOf} when the timer expires */ + private boolean mPendingRight; + + /** The time stamp (from {@link System#currentTimeMillis()} of the last alignment change */ + private long mLastAlignmentTime; + /** * Creates a new tooltip over the given parent with the given relative position. * @@ -75,6 +90,7 @@ public class GestureToolTip { public GestureToolTip(Composite parent, boolean below, boolean toRightOf) { mBelow = below; mToRightOf = toRightOf; + mLastAlignmentTime = System.currentTimeMillis(); mShell = new Shell(parent.getShell(), SWT.ON_TOP | SWT.TOOL | SWT.NO_FOCUS); mShell.setLayout(new FillLayout()); @@ -94,15 +110,29 @@ public class GestureToolTip { mLabel.setFont(mFont); mShell.setVisible(false); - } /** - * Show the tooltip at the given position and with the given text + * Show the tooltip at the given position and with the given text. Note that the + * position may not be applied immediately; to prevent flicker alignment changes + * are queued up with a timer (unless it's been a while since the last change, in + * which case the update is applied immediately.) * * @param text the new text to be displayed + * @param below if true, display the tooltip below the mouse cursor otherwise above + * @param toRightOf if true, display the tooltip to the right of the mouse cursor, + * otherwise to the left */ - public void update(String text) { + public void update(final String text, boolean below, boolean toRightOf) { + // If the alignment has not changed recently, just apply the change immediately + // instead of within a delay + if (!mTimerPending && (below != mBelow || toRightOf != mToRightOf) + && (System.currentTimeMillis() - mLastAlignmentTime >= TIMEOUT_MS)) { + mBelow = below; + mToRightOf = toRightOf; + mLastAlignmentTime = System.currentTimeMillis(); + } + Point location = mShell.getDisplay().getCursorLocation(); mLabel.setText(text); @@ -124,6 +154,9 @@ public class GestureToolTip { mShell.pack(changed); Point size = mShell.getSize(); + // Position the tooltip to the left or right, and above or below, according + // to the saved state of these flags, not the current parameters. We don't want + // to flicker, instead we react on a timer to changes in alignment below. if (mBelow) { location.y += OFFSET_Y; } else { @@ -143,6 +176,32 @@ public class GestureToolTip { if (!mShell.isVisible()) { mShell.setVisible(true); } + + // Has the orientation changed? + mPendingBelow = below; + mPendingRight = toRightOf; + if (below != mBelow || toRightOf != mToRightOf) { + // Yes, so schedule a timer (unless one is already scheduled) + if (!mTimerPending) { + mTimerPending = true; + final Runnable timer = new Runnable() { + public void run() { + mTimerPending = false; + // Check whether the alignment is still different than the target + // (since we may change back and forth repeatedly during the timeout) + if (mBelow != mPendingBelow || mToRightOf != mPendingRight) { + mBelow = mPendingBelow; + mToRightOf = mPendingRight; + mLastAlignmentTime = System.currentTimeMillis(); + if (mShell != null && mShell.isVisible()) { + update(text, mBelow, mToRightOf); + } + } + } + }; + mShell.getDisplay().timerExec(TIMEOUT_MS, timer); + } + } } /** Hide the tooltip and dispose of any associated resources */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java index 45e0234..43bb3ff 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/MoveGesture.java @@ -639,7 +639,6 @@ public class MoveGesture extends DropGesture { updateDropFeedback(df, event); df = mCanvas.getRulesEngine().callOnDropMove(targetNode, mCurrentDragElements, df, new Point(p.x, p.y)); - mCanvas.getGestureManager().updateMessage(df); } if (df != null && |