aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LinearLayoutRule.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GestureManager.java10
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GlobalCanvasDragInfo.java14
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionItem.java32
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionManager.java16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleElement.java39
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestDragElement.java6
-rw-r--r--rule_api/src/com/android/ide/common/api/IDragElement.java8
-rw-r--r--rule_api/src/com/android/ide/common/api/IViewRule.java16
9 files changed, 126 insertions, 18 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 04373e1..a1571e2 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
@@ -304,8 +304,9 @@ public class LinearLayoutRule extends BaseLayoutRule {
for (IDragElement element : elements) {
// This tries to determine if an INode corresponds to an
// IDragElement, by comparing their bounds.
- if (bc.equals(element.getBounds())) {
+ if (element.isSame(it)) {
isDragged = true;
+ break;
}
}
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 d8a45b6..e2c1d5e 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
@@ -717,6 +717,7 @@ public class GestureManager {
// operation.
List<SelectionItem> selections = selectionManager.getSelections();
mDragSelection.clear();
+ SelectionItem primary = null;
if (!selections.isEmpty()) {
// Is the cursor on top of a selected element?
@@ -724,6 +725,7 @@ public class GestureManager {
for (SelectionItem cs : selections) {
if (!cs.isRoot() && cs.getRect().contains(p.x, p.y)) {
+ primary = cs;
insideSelection = true;
break;
}
@@ -732,7 +734,7 @@ public class GestureManager {
if (!insideSelection) {
CanvasViewInfo vi = mCanvas.getViewHierarchy().findViewInfoAt(p);
if (vi != null && !vi.isRoot() && !vi.isHidden()) {
- selectionManager.selectSingle(vi);
+ primary = selectionManager.selectSingle(vi);
insideSelection = true;
}
}
@@ -753,6 +755,8 @@ public class GestureManager {
for (SelectionItem cs : selections) {
if (!cs.isRoot() && !cs.isHidden()) {
mDragSelection.add(cs);
+ } else if (cs == primary) {
+ primary = null;
}
}
}
@@ -763,7 +767,7 @@ public class GestureManager {
if (mDragSelection.isEmpty()) {
CanvasViewInfo vi = mCanvas.getViewHierarchy().findViewInfoAt(p);
if (vi != null && !vi.isRoot() && !vi.isHidden()) {
- selectionManager.selectSingle(vi);
+ primary = selectionManager.selectSingle(vi);
mDragSelection.addAll(selections);
}
}
@@ -773,7 +777,7 @@ public class GestureManager {
e.doit = !mDragSelection.isEmpty();
int imageCount = mDragSelection.size();
if (e.doit) {
- mDragElements = SelectionItem.getAsElements(mDragSelection);
+ mDragElements = SelectionItem.getAsElements(mDragSelection, primary);
GlobalCanvasDragInfo.getInstance().startDrag(mDragElements,
mDragSelection.toArray(new SelectionItem[imageCount]),
mCanvas, new Runnable() {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GlobalCanvasDragInfo.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GlobalCanvasDragInfo.java
index 06986cd..b918b00 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GlobalCanvasDragInfo.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GlobalCanvasDragInfo.java
@@ -16,6 +16,8 @@
package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.ide.common.api.IViewRule;
import com.android.ide.common.api.Rect;
@@ -63,6 +65,10 @@ final class GlobalCanvasDragInfo {
* Registers the XML elements being dragged.
*
* @param elements The elements being dragged
+ * @param primary the "primary" element among the elements; when there is a
+ * single item dragged this will be the same, but in
+ * multi-selection it will be the element under the mouse as the
+ * selection was initiated
* @param selection The selection (which can be null, for example when the
* user drags from the palette)
* @param sourceCanvas An object representing the source we are dragging
@@ -71,8 +77,11 @@ final class GlobalCanvasDragInfo {
* source. It should only be invoked if the drag operation is a
* move, not a copy.
*/
- public void startDrag(SimpleElement[] elements, SelectionItem[] selection,
- Object sourceCanvas, Runnable removeSourceHandler) {
+ public void startDrag(
+ @NonNull SimpleElement[] elements,
+ @Nullable SelectionItem[] selection,
+ @Nullable Object sourceCanvas,
+ @Nullable Runnable removeSourceHandler) {
mCurrentElements = elements;
mCurrentSelection = selection;
mSourceCanvas = sourceCanvas;
@@ -93,6 +102,7 @@ final class GlobalCanvasDragInfo {
}
/** Returns the elements being dragged. */
+ @NonNull
public SimpleElement[] getCurrentElements() {
return mCurrentElements;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionItem.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionItem.java
index 5d49426..d104e37 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionItem.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionItem.java
@@ -169,13 +169,39 @@ class SelectionItem {
* @return An array of wrapper elements. Never null.
*/
@NonNull
- static SimpleElement[] getAsElements(List<SelectionItem> items) {
- ArrayList<SimpleElement> elements = new ArrayList<SimpleElement>();
+ static SimpleElement[] getAsElements(@NonNull List<SelectionItem> items) {
+ return getAsElements(items, null);
+ }
+
+ /**
+ * Returns elements representing the given selection of canvas items.
+ *
+ * @param items Items to wrap in elements
+ * @param primary The primary selected item which should be listed first
+ * @return An array of wrapper elements. Never null.
+ */
+ @NonNull
+ static SimpleElement[] getAsElements(
+ @NonNull List<SelectionItem> items,
+ @Nullable SelectionItem primary) {
+ List<SimpleElement> elements = new ArrayList<SimpleElement>();
+
+ if (primary != null) {
+ CanvasViewInfo vi = primary.getViewInfo();
+ SimpleElement e = vi.toSimpleElement();
+ e.setSelectionItem(primary);
+ elements.add(e);
+ }
for (SelectionItem cs : items) {
- CanvasViewInfo vi = cs.getViewInfo();
+ if (cs == primary) {
+ // Already handled
+ continue;
+ }
+ CanvasViewInfo vi = cs.getViewInfo();
SimpleElement e = vi.toSimpleElement();
+ e.setSelectionItem(cs);
elements.add(e);
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionManager.java
index 1450768..dc8a383 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionManager.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SelectionManager.java
@@ -21,6 +21,7 @@ import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.Selection
import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.SelectionHandle.PIXEL_RADIUS;
import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.ide.common.api.INode;
import com.android.ide.common.layout.GridLayoutRule;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
@@ -429,11 +430,15 @@ public class SelectionManager implements ISelectionProvider {
/**
* Removes all the currently selected item and only select the given item.
- * Issues a {@link #redraw()} if the selection changes.
+ * Issues a redraw() if the selection changes.
*
* @param vi The new selected item if non-null. Selection becomes empty if null.
+ * @return the item selected, or null if the selection was cleared (e.g. vi was null)
*/
- /* package */ void selectSingle(CanvasViewInfo vi) {
+ @Nullable
+ SelectionItem selectSingle(CanvasViewInfo vi) {
+ SelectionItem item = null;
+
// reset alternate selection if any
mAltSelection = null;
@@ -449,13 +454,14 @@ public class SelectionManager implements ISelectionProvider {
if (!mSelections.isEmpty()) {
if (mSelections.size() == 1 && mSelections.getFirst().getViewInfo() == vi) {
// CanvasSelection remains the same, don't touch it.
- return;
+ return mSelections.getFirst();
}
mSelections.clear();
}
if (vi != null) {
- mSelections.add(createSelection(vi));
+ item = createSelection(vi);
+ mSelections.add(item);
if (vi.isInvisible()) {
redoLayout = true;
}
@@ -467,6 +473,8 @@ public class SelectionManager implements ISelectionProvider {
}
redraw();
+
+ return item;
}
/** Returns true if the view hierarchy is showing exploded items. */
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleElement.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleElement.java
index 4feff25..9acc8c2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleElement.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SimpleElement.java
@@ -19,6 +19,7 @@ package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.IDragElement;
+import com.android.ide.common.api.INode;
import com.android.ide.common.api.Rect;
import java.util.ArrayList;
@@ -47,6 +48,7 @@ public class SimpleElement implements IDragElement {
private IDragAttribute[] mCachedAttributes = null;
private IDragElement[] mCachedElements = null;
+ private SelectionItem mSelectionItem;
/**
* Creates a new {@link SimpleElement} with the specified element name.
@@ -141,6 +143,43 @@ public class SimpleElement implements IDragElement {
mElements.add(e);
}
+ @Override
+ public boolean isSame(@NonNull INode node) {
+ if (mSelectionItem != null) {
+ return node == mSelectionItem.getNode();
+ } else {
+ return node.getBounds().equals(mBounds);
+ }
+ }
+
+ void setSelectionItem(@Nullable SelectionItem selectionItem) {
+ mSelectionItem = selectionItem;
+ }
+
+ @Nullable
+ SelectionItem getSelectionItem() {
+ return mSelectionItem;
+ }
+
+ @Nullable
+ static SimpleElement findPrimary(SimpleElement[] elements, SelectionItem primary) {
+ if (elements == null || elements.length == 0) {
+ return null;
+ }
+
+ if (elements.length == 1 || primary == null) {
+ return elements[0];
+ }
+
+ for (SimpleElement element : elements) {
+ if (element.getSelectionItem() == primary) {
+ return element;
+ }
+ }
+
+ return elements[0];
+ }
+
// reader and writer methods
@Override
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestDragElement.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestDragElement.java
index eb0a432..5b55532 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestDragElement.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/TestDragElement.java
@@ -21,6 +21,7 @@ import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.api.IDragElement;
+import com.android.ide.common.api.INode;
import com.android.ide.common.api.Rect;
import java.util.ArrayList;
@@ -150,5 +151,8 @@ public class TestDragElement implements IDragElement {
+ mRect + "]";
}
-
+ @Override
+ public boolean isSame(INode node) {
+ return node.getBounds().equals(getBounds());
+ }
}
diff --git a/rule_api/src/com/android/ide/common/api/IDragElement.java b/rule_api/src/com/android/ide/common/api/IDragElement.java
index 885ba35..50a5014 100644
--- a/rule_api/src/com/android/ide/common/api/IDragElement.java
+++ b/rule_api/src/com/android/ide/common/api/IDragElement.java
@@ -86,6 +86,14 @@ public interface IDragElement {
public abstract IDragElement[] getInnerElements();
/**
+ * Returns true if the given {@link INode} represents this drag element
+ *
+ * @param node the node to be checked
+ * @return true if the given node represents this drag element
+ */
+ public abstract boolean isSame(@NonNull INode node);
+
+ /**
* An XML attribute in the {@link IDragElement}.
* <p/>
* The attribute is always represented by a namespace URI, a name and a value.
diff --git a/rule_api/src/com/android/ide/common/api/IViewRule.java b/rule_api/src/com/android/ide/common/api/IViewRule.java
index bcf4e89..c115795 100644
--- a/rule_api/src/com/android/ide/common/api/IViewRule.java
+++ b/rule_api/src/com/android/ide/common/api/IViewRule.java
@@ -161,7 +161,9 @@ public interface IViewRule {
* @param targetView the corresponding View object for the target layout, or
* null if not known
* @param elements an array of {@link IDragElement} element descriptors for
- * the dragged views
+ * the dragged views. When there are more than one element, the
+ * first element will always be the "primary" element (e.g. the
+ * one that the mouse is actively dragging.)
* @return a {@link DropFeedback} object with drop state (which will be
* supplied to a follow-up {@link #onDropMove} call), or null if the
* drop should be ignored
@@ -178,7 +180,9 @@ public interface IViewRule {
* @param targetNode the {@link INode} for the target layout receiving a
* drop event
* @param elements an array of {@link IDragElement} element descriptors for
- * the dragged views
+ * the dragged views. When there are more than one element, the
+ * first element will always be the "primary" element (e.g. the
+ * one that the mouse is actively dragging.)
* @param feedback the {@link DropFeedback} object created by
* {@link #onDropEnter(INode, Object, IDragElement[])}
* @param where the current mouse drag position
@@ -211,7 +215,9 @@ public interface IViewRule {
* @param targetNode the {@link INode} for the target layout receiving a
* drop event
* @param elements an array of {@link IDragElement} element descriptors for
- * the dragged views
+ * the dragged views. When there are more than one element, the
+ * first element will always be the "primary" element (e.g. the
+ * one that the mouse is actively dragging.)
* @param feedback the {@link DropFeedback} object created by
* {@link #onDropEnter(INode, Object, IDragElement[])}
*/
@@ -230,7 +236,9 @@ public interface IViewRule {
* @param targetNode the {@link INode} for the target layout receiving a
* drop event
* @param elements an array of {@link IDragElement} element descriptors for
- * the dragged views
+ * the dragged views. When there are more than one element, the
+ * first element will always be the "primary" element (e.g. the
+ * one that the mouse is actively dragging.)
* @param feedback the {@link DropFeedback} object created by
* {@link #onDropEnter(INode, Object, IDragElement[])}
* @param where the mouse drop position