summaryrefslogtreecommitdiff
path: root/designer
diff options
context:
space:
mode:
authorJens Ole Lauridsen <jlauridsen@google.com>2015-07-27 23:36:27 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-07-27 23:36:27 +0000
commit1eb956aec5f573f867ca228a8a2a1fbc0571a079 (patch)
treeb405d28b3a749a7540021fd921e338ab8c42a4fb /designer
parente2ef3f08d3e38f58ecb6801ec1fe99a478e27131 (diff)
parent23be2621c31ac9390f76ffd12ff3e401397c5e77 (diff)
downloadidea-1eb956aec5f573f867ca228a8a2a1fbc0571a079.tar.gz
Merge "Nele: Use NlModel.addComponents for drag/drop in InteractionManager." into studio-1.4-dev
Diffstat (limited to 'designer')
-rw-r--r--designer/src/com/android/tools/idea/uibuilder/model/NlDropEvent.java (renamed from designer/src/com/android/tools/idea/uibuilder/structure/NlDropEvent.java)54
-rw-r--r--designer/src/com/android/tools/idea/uibuilder/model/NlModel.java38
-rw-r--r--designer/src/com/android/tools/idea/uibuilder/surface/DragDropInteraction.java63
-rw-r--r--designer/src/com/android/tools/idea/uibuilder/surface/InteractionManager.java255
4 files changed, 200 insertions, 210 deletions
diff --git a/designer/src/com/android/tools/idea/uibuilder/structure/NlDropEvent.java b/designer/src/com/android/tools/idea/uibuilder/model/NlDropEvent.java
index d8d110ff1a6..23e948de03c 100644
--- a/designer/src/com/android/tools/idea/uibuilder/structure/NlDropEvent.java
+++ b/designer/src/com/android/tools/idea/uibuilder/model/NlDropEvent.java
@@ -13,24 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.tools.idea.uibuilder.structure;
+package com.android.tools.idea.uibuilder.model;
import com.android.annotations.NonNull;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
/**
* This class encapsulates either a {@see DropTargetDragEvent} or a {@see DropTargetDropEvent}
* such that we can access either instance in code common for the 2 cases.
- * This class is used in {@link NlDropListener}.
+ * <p/>
+ * Also ensure that accept is called before data is retrieved from a source that has text flavor but no designer flavor.
*/
public class NlDropEvent {
private final DropTargetDragEvent myDragEvent;
private final DropTargetDropEvent myDropEvent;
+ private boolean myStatusSpecified;
public NlDropEvent(@NonNull DropTargetDragEvent dragEvent) {
myDragEvent = dragEvent;
@@ -46,7 +49,8 @@ public class NlDropEvent {
public Point getLocation() {
if (myDragEvent != null) {
return myDragEvent.getLocation();
- } else {
+ }
+ else {
return myDropEvent.getLocation();
}
}
@@ -54,7 +58,8 @@ public class NlDropEvent {
public boolean isDataFlavorSupported(@NonNull DataFlavor flavor) {
if (myDragEvent != null) {
return myDragEvent.isDataFlavorSupported(flavor);
- } else {
+ }
+ else {
return myDropEvent.isDataFlavorSupported(flavor);
}
}
@@ -62,33 +67,54 @@ public class NlDropEvent {
public int getDropAction() {
if (myDragEvent != null) {
return myDragEvent.getDropAction();
- } else {
+ }
+ else {
return myDropEvent.getDropAction();
}
}
@NonNull
public Transferable getTransferable() {
+ if (!myStatusSpecified &&
+ !isDataFlavorSupported(ItemTransferable.DESIGNER_FLAVOR) &&
+ isDataFlavorSupported(DataFlavor.stringFlavor)) {
+ accept(DnDConstants.ACTION_COPY);
+ }
if (myDragEvent != null) {
return myDragEvent.getTransferable();
- } else {
+ }
+ else {
return myDropEvent.getTransferable();
}
}
public void accept(int dropAction) {
- if (myDragEvent != null) {
- myDragEvent.acceptDrag(dropAction);
- } else {
- myDropEvent.acceptDrop(dropAction);
+ if (!myStatusSpecified) {
+ if (myDragEvent != null) {
+ myDragEvent.acceptDrag(dropAction);
+ }
+ else {
+ myDropEvent.acceptDrop(dropAction);
+ }
+ myStatusSpecified = true;
}
}
public void reject() {
- if (myDragEvent != null) {
- myDragEvent.rejectDrag();
- } else {
- myDropEvent.rejectDrop();
+ if (!myStatusSpecified) {
+ if (myDragEvent != null) {
+ myDragEvent.rejectDrag();
+ }
+ else {
+ myDropEvent.rejectDrop();
+ }
+ myStatusSpecified = true;
+ }
+ }
+
+ public void complete() {
+ if (myDropEvent != null) {
+ myDropEvent.dropComplete(true);
}
}
}
diff --git a/designer/src/com/android/tools/idea/uibuilder/model/NlModel.java b/designer/src/com/android/tools/idea/uibuilder/model/NlModel.java
index 272444a3315..9b69d2ea620 100644
--- a/designer/src/com/android/tools/idea/uibuilder/model/NlModel.java
+++ b/designer/src/com/android/tools/idea/uibuilder/model/NlModel.java
@@ -59,9 +59,13 @@ import org.jetbrains.android.facet.AndroidFacet;
import javax.swing.Timer;
import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.dnd.InvalidDnDOperationException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.io.IOException;
import java.util.*;
import java.util.List;
@@ -71,6 +75,7 @@ import static com.android.SdkConstants.*;
* Model for an XML file
*/
public class NlModel implements Disposable, ResourceChangeListener, ModificationTracker {
+ private static final Logger LOG = Logger.getInstance(NlModel.class);
@AndroidCoordinate public static final int EMPTY_COMPONENT_SIZE = 5;
@AndroidCoordinate public static final int VISUAL_EMPTY_COMPONENT_SIZE = 14;
@@ -888,6 +893,33 @@ public class NlModel implements Disposable, ResourceChangeListener, Modification
}
@Nullable
+ public static DnDTransferItem getTransferItem(@NonNull Transferable transferable, boolean allowPlaceholder) {
+ DnDTransferItem item = null;
+ try {
+ if (transferable.isDataFlavorSupported(ItemTransferable.DESIGNER_FLAVOR)) {
+ item = (DnDTransferItem)transferable.getTransferData(ItemTransferable.DESIGNER_FLAVOR);
+ }
+ else if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
+ String xml = (String)transferable.getTransferData(DataFlavor.stringFlavor);
+ if (!StringUtil.isEmpty(xml)) {
+ item = new DnDTransferItem(new DnDTransferComponent("", xml, 200, 100));
+ }
+ }
+ } catch (InvalidDnDOperationException ex) {
+ if (!allowPlaceholder) {
+ return null;
+ }
+ String defaultXml = "<placeholder xmlns:android=\"http://schemas.android.com/apk/res/android\"/>";
+ item = new DnDTransferItem(new DnDTransferComponent("", defaultXml, 200, 100));
+ } catch (IOException ex) {
+ LOG.warn(ex);
+ } catch (UnsupportedFlavorException ex) {
+ LOG.warn(ex);
+ }
+ return item;
+ }
+
+ @Nullable
public List<NlComponent> createComponents(@NonNull ScreenView screenView,
@NonNull DnDTransferItem item,
@NonNull InsertType insertType) {
@@ -958,15 +990,15 @@ public class NlModel implements Disposable, ResourceChangeListener, Modification
}
@NonNull
- public InsertType determineInsertType(@NonNull DragType dragType, @NonNull DnDTransferItem item, boolean asPreview) {
- if (item.isFromPalette()) {
+ public InsertType determineInsertType(@NonNull DragType dragType, @Nullable DnDTransferItem item, boolean asPreview) {
+ if (item != null && item.isFromPalette()) {
return asPreview ? InsertType.CREATE_PREVIEW : InsertType.CREATE;
}
switch (dragType) {
case CREATE:
return asPreview ? InsertType.CREATE_PREVIEW : InsertType.CREATE;
case MOVE:
- return myId == item.getModelId() ? InsertType.MOVE_INTO : InsertType.COPY;
+ return item != null && myId != item.getModelId() ? InsertType.COPY : InsertType.MOVE_INTO;
case COPY:
return InsertType.COPY;
case PASTE:
diff --git a/designer/src/com/android/tools/idea/uibuilder/surface/DragDropInteraction.java b/designer/src/com/android/tools/idea/uibuilder/surface/DragDropInteraction.java
index d334e5874b1..400a8dc1520 100644
--- a/designer/src/com/android/tools/idea/uibuilder/surface/DragDropInteraction.java
+++ b/designer/src/com/android/tools/idea/uibuilder/surface/DragDropInteraction.java
@@ -80,6 +80,9 @@ public class DragDropInteraction extends Interaction {
/** The last accessed screen view. */
private ScreenView myScreenView;
+ /** The transfer item for this drag if any */
+ private DnDTransferItem myTransferItem;
+
public DragDropInteraction(@NonNull DesignSurface designSurface, @NonNull List<NlComponent> dragged) {
myDesignSurface = designSurface;
myDraggedComponents = dragged;
@@ -92,6 +95,15 @@ public class DragDropInteraction extends Interaction {
}
}
+ public void setTransferItem(@NonNull DnDTransferItem item) {
+ myTransferItem = item;
+ }
+
+ @Nullable
+ public DnDTransferItem getTransferItem() {
+ return myTransferItem;
+ }
+
@Override
public void begin(@SwingCoordinate int x, @SwingCoordinate int y, int modifiers) {
super.begin(x, y, modifiers);
@@ -164,7 +176,7 @@ public class DragDropInteraction extends Interaction {
String error = myDragHandler.update(ax, ay, modifiers);
final List<NlComponent> added = Lists.newArrayList();
if (commit && error == null) {
- NlModel model = myScreenView.getModel();
+ final NlModel model = myScreenView.getModel();
XmlFile file = model.getFile();
String label = myType.getDescription();
WriteCommandAction action = new WriteCommandAction(project, label, file) {
@@ -178,53 +190,8 @@ public class DragDropInteraction extends Interaction {
before = myDragReceiver.getChild(insertIndex);
}
- ViewHandlerManager viewHandlerManager = ViewHandlerManager.get(getProject());
-
- // Move the widget and schedule a re-render
- for (NlComponent component : myDraggedComponents) {
- if (!myCurrentHandler.acceptsChild(myDragReceiver, component)) {
- continue;
- }
- ViewHandler viewHandler = viewHandlerManager.getHandler(component);
- if (viewHandler != null && !viewHandler.acceptsParent(myDragReceiver, component)) {
- continue;
- }
-
- // Notify parent & child about the creation and allow them to customize the objects
- InsertType insertType = myType == DragType.COPY ? InsertType.MOVE_INTO :
- (component.getParent() != myDragReceiver ? InsertType.MOVE_INTO : InsertType.MOVE_WITHIN);
- myCurrentHandler.onChildInserted(myDragReceiver, component, insertType);
- if (viewHandler != null) {
- ViewEditor editor = new ViewEditorImpl(myScreenView);
- boolean ok = viewHandler.onCreate(editor, myDragReceiver, component, insertType);
- if (!ok) {
- return;
- }
- }
-
- // Also update the component hierarchy directly.
- // This will be corrected after the next rendering job too, but anticipate it
- // here such that tests etc can immediately see the result
- NlComponent parent = component.getParent();
- if (parent != null) {
- parent.removeChild(component);
- }
- myDragReceiver.addChild(component, before);
- added.add(component);
-
- // Move XML tags
- if (myDragReceiver.getTag() != component.getTag()) {
- XmlTag prev = component.getTag();
- if (before != null) {
- component.setTag((XmlTag)myDragReceiver.getTag().addBefore(component.getTag(), before.getTag()));
- } else {
- component.setTag(myDragReceiver.getTag().addSubTag(component.getTag(), false));
- }
- if (myType == DragType.MOVE) {
- prev.delete();
- }
- }
- }
+ InsertType insertType = model.determineInsertType(myType, myTransferItem, false /* not for preview */);
+ model.addComponents(myDraggedComponents, myDragReceiver, before, insertType);
}
};
action.execute();
diff --git a/designer/src/com/android/tools/idea/uibuilder/surface/InteractionManager.java b/designer/src/com/android/tools/idea/uibuilder/surface/InteractionManager.java
index 5316f7ac2dc..980f505b90f 100644
--- a/designer/src/com/android/tools/idea/uibuilder/surface/InteractionManager.java
+++ b/designer/src/com/android/tools/idea/uibuilder/surface/InteractionManager.java
@@ -20,34 +20,18 @@ import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
import com.android.tools.idea.uibuilder.api.DragType;
import com.android.tools.idea.uibuilder.api.InsertType;
-import com.android.tools.idea.uibuilder.api.ViewEditor;
-import com.android.tools.idea.uibuilder.api.ViewHandler;
-import com.android.tools.idea.uibuilder.handlers.ViewEditorImpl;
-import com.android.tools.idea.uibuilder.handlers.ViewHandlerManager;
import com.android.tools.idea.uibuilder.model.*;
import com.google.common.collect.Lists;
-import com.intellij.openapi.application.Result;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.xml.XmlAttribute;
-import com.intellij.psi.xml.XmlFile;
-import com.intellij.psi.xml.XmlTag;
import com.intellij.util.PsiNavigateUtil;
import javax.swing.*;
import java.awt.*;
-import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.*;
import java.awt.event.*;
-import java.io.IOException;
import java.util.Collections;
import java.util.List;
-import static com.android.SdkConstants.XMLNS_PREFIX;
import static com.android.tools.idea.uibuilder.model.SelectionHandle.PIXEL_MARGIN;
import static com.android.tools.idea.uibuilder.model.SelectionHandle.PIXEL_RADIUS;
@@ -58,8 +42,6 @@ import static com.android.tools.idea.uibuilder.model.SelectionHandle.PIXEL_RADIU
* interactions and in order to update the interactions along the way.
*/
public class InteractionManager {
- private static final Logger LOG = Logger.getInstance(InteractionManager.class);
-
/** The canvas which owns this {@linkplain InteractionManager}. */
@NonNull
private final DesignSurface mySurface;
@@ -548,65 +530,72 @@ public class InteractionManager {
// ---- Implements DropTargetListener ----
@Override
- public void dragEnter(DropTargetDragEvent event) {
+ public void dragEnter(DropTargetDragEvent dragEvent) {
if (myCurrentInteraction == null) {
+ NlDropEvent event = new NlDropEvent(dragEvent);
Point location = event.getLocation();
myLastMouseX = location.x;
myLastMouseY = location.y;
- for (DataFlavor flavor : event.getCurrentDataFlavors()) {
- if (flavor.equals(ItemTransferable.DESIGNER_FLAVOR) ||
- flavor.getMimeType().startsWith("text/plain;") || flavor.getMimeType().equals("text/plain")) {
- event.acceptDrag(DnDConstants.ACTION_COPY);
- ScreenView screenView = mySurface.getScreenView(myLastMouseX, myLastMouseY);
- if (screenView == null) {
- continue;
- }
- final NlModel model = screenView.getModel();
- try {
- DnDTransferItem item = getTransferItem(event.getTransferable(), true /* allow placeholders */);
- DragType dragType = event.getDropAction() == DnDConstants.ACTION_COPY ? DragType.COPY : DragType.MOVE;
- InsertType insertType = model.determineInsertType(dragType, item, true /* preview */);
- List<NlComponent> dragged = model.createComponents(screenView, item, insertType);
- if (dragged == null) {
- continue;
- }
- int yOffset = 0;
- for (NlComponent component : dragged) {
- // todo: place the components like they were originally placed?
- component.x = Coordinates.getAndroidX(screenView, myLastMouseX) - component.w / 2;
- component.y = Coordinates.getAndroidY(screenView, myLastMouseY) - component.h / 2 + yOffset;
- yOffset += component.h;
- }
- DragDropInteraction interaction = new DragDropInteraction(mySurface, dragged);
- interaction.setType(DragType.COPY);
- startInteraction(myLastMouseX, myLastMouseY, interaction, 0);
- break;
- }
- catch (Exception ignore) {
- LOG.debug(ignore);
- }
- }
+ ScreenView screenView = mySurface.getScreenView(myLastMouseX, myLastMouseY);
+ if (screenView == null) {
+ event.reject();
+ return;
+ }
+ NlModel model = screenView.getModel();
+ DnDTransferItem item = NlModel.getTransferItem(event.getTransferable(), true /* allow placeholders */);
+ if (item == null) {
+ event.reject();
+ return;
}
+ DragType dragType = event.getDropAction() == DnDConstants.ACTION_COPY ? DragType.COPY : DragType.MOVE;
+ InsertType insertType = model.determineInsertType(dragType, item, true /* preview */);
+ List<NlComponent> dragged = model.createComponents(screenView, item, insertType);
+ if (dragged == null) {
+ event.reject();
+ return;
+ }
+ int yOffset = 0;
+ for (NlComponent component : dragged) {
+ // todo: keep original relative position?
+ component.x = Coordinates.getAndroidX(screenView, myLastMouseX) - component.w / 2;
+ component.y = Coordinates.getAndroidY(screenView, myLastMouseY) - component.h / 2 + yOffset;
+ yOffset += component.h;
+ }
+ DragDropInteraction interaction = new DragDropInteraction(mySurface, dragged);
+ interaction.setType(dragType);
+ interaction.setTransferItem(item);
+ startInteraction(myLastMouseX, myLastMouseY, interaction, 0);
+
+ // This determines the icon presented to the user while dragging.
+ // If we are dragging a component from the palette then use the icon for a copy, otherwise show the icon
+ // that reflects the users choice i.e. controlled by the modifier key.
+ event.accept(insertType.isCreate() ? DnDConstants.ACTION_COPY : event.getDropAction());
}
}
@Override
- public void dragOver(DropTargetDragEvent event) {
+ public void dragOver(DropTargetDragEvent dragEvent) {
+ NlDropEvent event = new NlDropEvent(dragEvent);
Point location = event.getLocation();
myLastMouseX = location.x;
myLastMouseY = location.y;
- if (myCurrentInteraction instanceof DragDropInteraction) {
- myCurrentInteraction.update(myLastMouseX, myLastMouseY, myLastStateMask);
- }
-
- for (DataFlavor flavor : event.getCurrentDataFlavors()) {
- if (flavor.equals(ItemTransferable.DESIGNER_FLAVOR) || String.class == flavor.getRepresentationClass()) {
- event.acceptDrag(DnDConstants.ACTION_COPY);
- return;
- }
+ ScreenView screenView = mySurface.getScreenView(myLastMouseX, myLastMouseY);
+ if (screenView != null && myCurrentInteraction instanceof DragDropInteraction) {
+ DragDropInteraction interaction = (DragDropInteraction)myCurrentInteraction;
+ interaction.update(myLastMouseX, myLastMouseY, myLastStateMask);
+ DragType dragType = event.getDropAction() == DnDConstants.ACTION_COPY ? DragType.COPY : DragType.MOVE;
+ interaction.setType(dragType);
+ NlModel model = screenView.getModel();
+ InsertType insertType = model.determineInsertType(dragType, interaction.getTransferItem(), true /* preview */);
+
+ // This determines the icon presented to the user while dragging.
+ // If we are dragging a component from the palette then use the icon for a copy, otherwise show the icon
+ // that reflects the users choice i.e. controlled by the modifier key.
+ event.accept(insertType.isCreate() ? DnDConstants.ACTION_COPY : event.getDropAction());
+ } else {
+ event.reject();
}
- event.rejectDrag();
}
@Override
@@ -616,106 +605,82 @@ public class InteractionManager {
@Override
public void dragExit(DropTargetEvent event) {
if (myCurrentInteraction instanceof DragDropInteraction) {
- finishInteraction(myLastMouseX, myLastMouseY, myLastStateMask, true);
+ finishInteraction(myLastMouseX, myLastMouseY, myLastStateMask, true /* cancel interaction */);
}
}
@Override
- public void drop(final DropTargetDropEvent event) {
+ public void drop(final DropTargetDropEvent dropEvent) {
+ NlDropEvent event = new NlDropEvent(dropEvent);
Point location = event.getLocation();
myLastMouseX = location.x;
myLastMouseY = location.y;
+ InsertType insertType = performDrop(event.getDropAction(), event.getTransferable());
+ if (insertType != null) {
+ // This determines how the DnD source acts to a completed drop.
+ event.accept(insertType == InsertType.COPY ? event.getDropAction() : DnDConstants.ACTION_COPY);
+ event.complete();
+ } else {
+ event.reject();
+ }
+ }
- final ScreenView screenView = mySurface.getScreenView(location.x, location.y);
- if (screenView == null) {
- event.rejectDrop();
- return;
+ @Nullable
+ private InsertType performDrop(int dropAction, @Nullable Transferable transferable) {
+ if (!(myCurrentInteraction instanceof DragDropInteraction)) {
+ return null;
}
+ InsertType insertType = updateDropInteraction(dropAction, transferable);
+ finishInteraction(myLastMouseX, myLastMouseY, myLastStateMask, (insertType == null));
+ return insertType;
+ }
- try {
- event.acceptDrop(DnDConstants.ACTION_MOVE);
- final NlModel model = screenView.getModel();
- final Project project = model.getFacet().getModule().getProject();
- final XmlFile file = model.getFile();
- WriteCommandAction<Void> action = new WriteCommandAction<Void>(project, "Drop", file) {
- @Override
- protected void run(@NonNull Result<Void> result) throws Throwable {
- if (myCurrentInteraction instanceof DragDropInteraction) {
- DragDropInteraction dragDrop = (DragDropInteraction)myCurrentInteraction;
- List<NlComponent> draggedComponents = dragDrop.getDraggedComponents();
- NlComponent component = draggedComponents.size() == 1 ? draggedComponents.get(0) : null;
- boolean dropCancelled = true;
- if (component != null) {
- if (component.getTag().getName().equals("placeholder")) {
- // If we were unable to read the transfer data on dragEnter, fix it here:
- final DnDTransferItem item = getTransferItem(event.getTransferable(), false /* do not allow placeholders */);
- DragType dragType = event.getDropAction() == DnDConstants.ACTION_COPY ? DragType.COPY : DragType.MOVE;
- InsertType insertType = model.determineInsertType(dragType, item, true /* preview */);
- draggedComponents = model.createComponents(screenView, item, insertType);
- component = draggedComponents != null && draggedComponents.size() == 1 ? draggedComponents.get(0) : null;
- }
- }
- if (component != null) {
- if (component.needsDefaultId()) {
- component.assignId();
- }
- ViewHandlerManager viewHandlerManager = ViewHandlerManager.get(getProject());
- ViewHandler viewHandler = viewHandlerManager.getHandler(component);
- if (viewHandler != null && dragDrop.getDragReceiver() != null) {
- ViewEditor editor = new ViewEditorImpl(screenView);
- dropCancelled = !viewHandler.onCreate(editor, dragDrop.getDragReceiver(), component, InsertType.CREATE);
- } else {
- dropCancelled = false;
- }
- }
- finishInteraction(myLastMouseX, myLastMouseY, myLastStateMask, dropCancelled);
- if (component != null && component.getTag().isValid() && component.getTag().getParent() instanceof XmlTag) {
- // Remove any xmlns: attributes once the element is added into the document
- for (XmlAttribute attribute : component.getTag().getAttributes()) {
- if (attribute.getName().startsWith(XMLNS_PREFIX)) {
- attribute.delete();
- }
- }
- }
- }
- }
- };
- action.execute();
- event.getDropTargetContext().dropComplete(true); // or just event.dropComplete() ?
- model.notifyModified();
+ @Nullable
+ private InsertType updateDropInteraction(int dropAction, @Nullable Transferable transferable) {
+ if (transferable == null) {
+ return null;
}
- catch (Exception ignore) {
- LOG.debug(ignore);
- event.rejectDrop();
+ DnDTransferItem item = NlModel.getTransferItem(transferable, false /* no placeholders */);
+ if (item == null) {
+ return null;
+ }
+ ScreenView screenView = mySurface.getScreenView(myLastMouseX, myLastMouseY);
+ if (screenView == null) {
+ return null;
}
- }
- }
- @NonNull
- private static DnDTransferItem getTransferItem(@NonNull Transferable transferable, boolean allowPlaceholder)
- throws IOException, UnsupportedFlavorException {
- DnDTransferItem item = null;
- try {
- if (transferable.isDataFlavorSupported(ItemTransferable.DESIGNER_FLAVOR)) {
- item = (DnDTransferItem)transferable.getTransferData(ItemTransferable.DESIGNER_FLAVOR);
+ NlModel model = screenView.getModel();
+ DragType dragType = dropAction == DnDConstants.ACTION_COPY ? DragType.COPY : DragType.MOVE;
+ InsertType insertType = model.determineInsertType(dragType, item, false /* not for preview */);
+
+ DragDropInteraction interaction = (DragDropInteraction)myCurrentInteraction;
+ assert interaction != null;
+ interaction.setType(dragType);
+ interaction.setTransferItem(item);
+
+ List<NlComponent> dragged = interaction.getDraggedComponents();
+ List<NlComponent> components;
+ if (insertType.isMove()) {
+ components = model.getSelectionModel().getSelection();
}
- else if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
- String xml = (String)transferable.getTransferData(DataFlavor.stringFlavor);
- if (!StringUtil.isEmpty(xml)) {
- item = new DnDTransferItem(new DnDTransferComponent("", xml, 200, 100));
+ else {
+ components = model.createComponents(screenView, item, insertType);
+ if (components == null) {
+ return null; // User cancelled
}
}
- } catch (InvalidDnDOperationException ex) {
- if (!allowPlaceholder) {
- throw ex;
+ if (dragged.size() != components.size()) {
+ throw new AssertionError(
+ String.format("Problem with drop: dragged.size(%1$d) != components.size(%1$d)", dragged.size(), components.size()));
}
- String defaultXml = "<placeholder xmlns:android=\"http://schemas.android.com/apk/res/android\"/>";
- item = new DnDTransferItem(new DnDTransferComponent("", defaultXml, 200, 100));
- }
- if (item == null) {
- throw new UnsupportedFlavorException(null);
+ for (int index = 0; index < dragged.size(); index++) {
+ components.get(index).x = dragged.get(index).x;
+ components.get(index).y = dragged.get(index).y;
+ }
+ dragged.clear();
+ dragged.addAll(components);
+ return insertType;
}
- return item;
}
@VisibleForTesting