diff options
author | Jens Ole Lauridsen <jlauridsen@google.com> | 2015-07-27 23:36:27 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-07-27 23:36:27 +0000 |
commit | 1eb956aec5f573f867ca228a8a2a1fbc0571a079 (patch) | |
tree | b405d28b3a749a7540021fd921e338ab8c42a4fb /designer | |
parent | e2ef3f08d3e38f58ecb6801ec1fe99a478e27131 (diff) | |
parent | 23be2621c31ac9390f76ffd12ff3e401397c5e77 (diff) | |
download | idea-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.java | 38 | ||||
-rw-r--r-- | designer/src/com/android/tools/idea/uibuilder/surface/DragDropInteraction.java | 63 | ||||
-rw-r--r-- | designer/src/com/android/tools/idea/uibuilder/surface/InteractionManager.java | 255 |
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 |