@Override public boolean onEnd( final Draggable draggable, final Actor actor, final float stageX, final float stageY) { if (actor == null || actor.getStage() == null) { return CANCEL; } final Actor overActor = actor.getStage().hit(stageX, stageY, true); if (overActor == null || overActor == actor) { return CANCEL; } else if (overActor.isAscendantOf(actor)) { final DragPane dragPane = getDragPane(actor); if (dragPane != null && dragPane.isFloating()) { DRAG_POSITION.set(stageX, stageY); return addToFloatingGroup(draggable, actor, dragPane); } return CANCEL; } DRAG_POSITION.set(stageX, stageY); if (overActor instanceof DragPane) { return addDirectlyToPane(draggable, actor, (DragPane) overActor); } final DragPane dragPane = getDragPane(overActor); if (accept(actor, dragPane)) { return addActor(draggable, actor, overActor, dragPane); } return CANCEL; }
/** * @param draggable is attached to the actor. * @param actor dragged actor. * @param dragPane is directly under the dragged actor. If accepts the actor, it should be added * to its content. * @return true if actor was accepted. */ protected boolean addDirectlyToPane( final Draggable draggable, final Actor actor, final DragPane dragPane) { if (accept(actor, dragPane)) { if (dragPane.isFloating()) { return addToFloatingGroup(draggable, actor, dragPane); } // Dragged directly to a pane. Assuming no padding, adding last: dragPane.addActor(actor); return APPROVE; } return CANCEL; }
/** * @param actor is being dragged. * @param dragPane is under the actor. Stores a {@link GridGroup} or unknown group. * @param directPaneChild actor under the cursor. * @return true if actor was accepted by the group. */ protected boolean addToOtherGroup( final Actor actor, final DragPane dragPane, final Actor directPaneChild) { final Array<Actor> children = dragPane.getChildren(); final int indexOfDirectChild = children.indexOf(directPaneChild, true); final int indexOfDraggedActor = children.indexOf(actor, true); if (indexOfDraggedActor >= 0) { // Dragging own actor. if (indexOfDraggedActor > indexOfDirectChild) { // Dropped after current position. dragPane.addActorBefore(directPaneChild, actor); } else { // Dropped before current position. dragPane.addActorAfter(directPaneChild, actor); } } else if (indexOfDirectChild == children.size - 1) { // Dragged into last element. if (DRAG_POSITION.y < directPaneChild.getHeight() / 2f || DRAG_POSITION.x > directPaneChild.getWidth() / 2f) { // Adding last: // last: dragPane.addActor(actor); } else { dragPane.addActorBefore(directPaneChild, actor); } } else if (indexOfDirectChild == 0) { // Dragged into first element. if (DRAG_POSITION.y < directPaneChild.getHeight() / 2f || DRAG_POSITION.x > directPaneChild.getWidth() / 2f) { dragPane.addActorAfter(directPaneChild, actor); } else { // Adding first: dragPane.addActorBefore(directPaneChild, actor); } } else { // Replacing hovered actor: dragPane.addActorBefore(directPaneChild, actor); } return APPROVE; }
/** * @param draggable is attached to the actor. * @param actor is being dragged. * @param overActor is directly under the dragged actor. * @param dragPane contains the actor under dragged widget. * @return true if actor is accepted and added to the group. */ protected boolean addActor( final Draggable draggable, final Actor actor, final Actor overActor, final DragPane dragPane) { final Actor directPaneChild = getActorInDragPane(overActor, dragPane); directPaneChild.stageToLocalCoordinates(DRAG_POSITION); if (dragPane.isVertical() || dragPane.isVerticalFlow()) { return addToVerticalGroup(actor, dragPane, directPaneChild); } else if (dragPane.isHorizontal() || dragPane.isHorizontalFlow()) { return addToHorizontalGroup(actor, dragPane, directPaneChild); } else if (dragPane.isFloating()) { return addToFloatingGroup(draggable, actor, dragPane); } // This is the default behavior for grid and unknown groups: return addToOtherGroup(actor, dragPane, directPaneChild); }
/** * @param actor if in the drag pane, but does not have to be added directly. * @param dragPane contains the actor. * @return passed actor or the parent of the actor added directly to the pane. */ protected Actor getActorInDragPane(Actor actor, final DragPane dragPane) { while (actor != dragPane && actor != null) { if (dragPane.contains(actor)) { return actor; } // Actor might not be added directly to the drag pane. Trying out the parent: actor = actor.getParent(); } return null; }
/** * @param actor is being dragged. * @param dragPane is under the actor. Stores a {@link VerticalGroup}. * @param directPaneChild actor under the cursor. * @return true if actor was accepted by the group. */ protected boolean addToVerticalGroup( final Actor actor, final DragPane dragPane, final Actor directPaneChild) { final Array<Actor> children = dragPane.getChildren(); final int indexOfDraggedActor = children.indexOf(actor, true); if (indexOfDraggedActor >= 0) { final int indexOfDirectChild = children.indexOf(directPaneChild, true); if (indexOfDirectChild > indexOfDraggedActor) { dragPane.addActorAfter(directPaneChild, actor); } else { dragPane.addActorBefore(directPaneChild, actor); } } else if (DRAG_POSITION.y < directPaneChild.getHeight() / 2f) { // Y inverted. dragPane.addActorAfter(directPaneChild, actor); } else { dragPane.addActorBefore(directPaneChild, actor); } return APPROVE; }
/** * @param draggable attached to dragged actor. * @param actor is being dragged. * @param dragPane is under the actor. Stores a {@link FloatingGroup}. * @return true if actor was accepted by the group. */ protected boolean addToFloatingGroup( final Draggable draggable, final Actor actor, final DragPane dragPane) { final FloatingGroup group = dragPane.getFloatingGroup(); dragPane.stageToLocalCoordinates(DRAG_POSITION); float x = DRAG_POSITION.x + draggable.getOffsetX(); if (x < 0f || x + actor.getWidth() > dragPane.getWidth()) { // Normalizing value if set to keep within parent's bounds: if (draggable.isKeptWithinParent()) { x = x < 0f ? 0f : dragPane.getWidth() - actor.getWidth() - 1f; } else { return CANCEL; } } float y = DRAG_POSITION.y + draggable.getOffsetY(); if (y < 0f || y + actor.getHeight() > dragPane.getHeight()) { if (draggable.isKeptWithinParent()) { y = y < 0f ? 0f : dragPane.getHeight() - actor.getHeight() - 1f; } else { return CANCEL; } } actor.remove(); actor.setPosition(x, y); group.addActor(actor); return APPROVE; }
@Override public boolean accept(final DragPane dragPane, final Actor actor) { return dragPane.contains(actor) || dragPane.getChildren().size < max; }
@Override public boolean accept(final DragPane dragPane, final Actor actor) { return dragPane.contains(actor); }
@Override public boolean accept(final DragPane dragPane, final Actor actor) { return dragPane.contains(actor); // dragPane must be the direct parent of actor. }
/** * @param actor has just been dragged. * @param dragPane is under the dragged actor (if exists). Can be null. * @return true if the actor can be added to the dragPane. */ protected boolean accept(final Actor actor, final DragPane dragPane) { return dragPane != null && dragPane.accept(actor) && policy.accept(dragPane, actor); }