private void moveTo()

in designer/src/com/android/tools/idea/uibuilder/surface/interaction/DragDropInteraction.java [297:414]


  private void moveTo(@SwingCoordinate int x, @SwingCoordinate int y, @InputEventMask final int modifiers, boolean commit) {
    mySceneView = myDesignSurface.getSceneViewAtOrPrimary(x, y);
    if (mySceneView == null) {
      return;
    }
    myDoesAcceptDropAtLastPosition = true;
    myDesignSurface.getLayeredPane().scrollRectToVisible(
      new Rectangle(x - NlConstants.DEFAULT_SCREEN_OFFSET_X, y - NlConstants.DEFAULT_SCREEN_OFFSET_Y,
                    2 * NlConstants.DEFAULT_SCREEN_OFFSET_X, 2 * NlConstants.DEFAULT_SCREEN_OFFSET_Y));
    @AndroidCoordinate final int ax = Coordinates.getAndroidX(mySceneView, x);
    @AndroidCoordinate final int ay = Coordinates.getAndroidY(mySceneView, y);

    Project project = mySceneView.getSceneManager().getModel().getProject();
    ViewGroupHandler handler = findViewGroupHandlerAt(x, y);
    SceneContext sceneContext = mySceneView.getContext();
    SceneComponent viewgroup =
      mySceneView.getScene().findComponent(sceneContext,
                                           Coordinates.getAndroidXDip(mySceneView, x),
                                           Coordinates.getAndroidYDip(mySceneView, y));

    while (viewgroup != null && !NlComponentHelperKt.isOrHasSuperclass(viewgroup.getNlComponent(), SdkConstants.CLASS_VIEWGROUP)) {
      viewgroup = viewgroup.getParent();
    }

    // No need to change Handler when using CommonDragHandler.
    if (!(myDragHandler instanceof CommonDragHandler) && (handler != myCurrentHandler || myCurrentViewgroup != viewgroup)) {
      if (myCurrentViewgroup != null) {
        myCurrentViewgroup.setDrawState(SceneComponent.DrawState.NORMAL);
      }
      myCurrentViewgroup = viewgroup;
      if (myCurrentViewgroup != null) {
        myCurrentViewgroup.setDrawState(SceneComponent.DrawState.DRAG);
      }

      if (myDragHandler != null) {
        myDragHandler.cancel();
        myDragHandler = null;
        myDesignSurface.repaint();
      }

      myCurrentHandler = handler;
      if (myCurrentHandler != null) {
        assert myDragReceiver != null;

        String error = null;
        ViewHandlerManager viewHandlerManager = ViewHandlerManager.get(project);
        for (NlComponent component : myDraggedComponents) {
          boolean constraintHelper =
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_GUIDELINE.isEquals(component.getTagName()) ||
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_BARRIER.isEquals(component.getTagName()) ||
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_FLOW.isEquals(component.getTagName()) ||
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_GROUP.isEquals(component.getTagName()) ||
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_LAYER.isEquals(component.getTagName()) ||
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_IMAGE_FILTER_VIEW.isEquals(component.getTagName()) ||
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_IMAGE_FILTER_BUTTON.isEquals(component.getTagName()) ||
            AndroidXConstants.CLASS_CONSTRAINT_LAYOUT_MOCK_VIEW.isEquals(component.getTagName());
          boolean acceptableHandler =
              (myCurrentHandler instanceof ConstraintLayoutHandler) ||
              (myCurrentHandler instanceof ConstraintLayoutHandler.ConstraintLayoutSupported);
          if (constraintHelper && !acceptableHandler) {
            error = String.format(
              "<%1$s> does not accept <%2$s> as a child", myDragReceiver.getNlComponent().getTagName(), component.getTagName());
            myDoesAcceptDropAtLastPosition = false;
            break;
          }
          if (!myCurrentHandler.acceptsChild(myDragReceiver, component, ax, ay)) {
            error = String.format(
              "<%1$s> does not accept <%2$s> as a child", myDragReceiver.getNlComponent().getTagName(), component.getTagName());
            myDoesAcceptDropAtLastPosition = false;
            break;
          }
          ViewHandler viewHandler = viewHandlerManager.getHandler(component, () -> {});
          if (viewHandler != null && !viewHandler.acceptsParent(myDragReceiver.getNlComponent(), component)) {
            error = String.format(
              "<%1$s> does not accept <%2$s> as a parent", component.getTagName(), myDragReceiver.getNlComponent().getTagName());
            myDoesAcceptDropAtLastPosition = false;
            break;
          }
        }
        if (error == null) {
          ViewEditorImpl editorImpl = new ViewEditorImpl(mySceneView);
          myDragHandler = myCurrentHandler.createDragHandler(editorImpl, myDragReceiver, myDraggedComponents, myType);
          if (myDragHandler != null) {
            myDragHandler
              .start(Coordinates.getAndroidXDip(mySceneView, myStartInfo.getX()),
                     Coordinates.getAndroidYDip(mySceneView, myStartInfo.getY()),
                     myStartInfo.getModifiersEx());
          }
        }
        else {
          myCurrentHandler = null;
        }
      }
    }

    if ((myDragHandler instanceof CommonDragHandler) || (myDragHandler != null && myCurrentHandler != null)) {
      String error = myDragHandler.update(Coordinates.pxToDp(mySceneView, ax), Coordinates.pxToDp(mySceneView, ay), modifiers, sceneContext);
      final List<NlComponent> added = new ArrayList<>();
      if (commit && error == null) {
        added.addAll(myDraggedComponents);
        final NlModel model = mySceneView.getSceneManager().getModel();
        InsertType insertType = model.getTreeWriter().determineInsertType(myType, myTransferItem, false /* not for preview */, true /* generateIds */);

        // TODO: Run this *after* making a copy
        myDragHandler.commit(ax, ay, modifiers, insertType);
        model.notifyModified(ChangeType.DND_COMMIT);

        // Do not select the created component at this point see b/124231532.
        // The commit above is executed asynchronously and may not have completed yet.
        // The selection should not be moved before the components are properly created and placed under its new parent.
        // Other tools like the attributes panel may rely on the component being fully completed.

        // Move the focus to the design area in case this component is created from the palette see b/69394814
        myDesignSurface.getLayeredPane().requestFocus();
      }
      mySceneView.getSurface().repaint();
    }
  }