Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect anchor settings when resizing entity #2551

Merged
merged 1 commit into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ This file is part of Universal Gcode Sender (UGS).
*/
package com.willwinder.ugs.nbp.designer.actions;

import com.willwinder.ugs.nbp.designer.entities.Anchor;
import com.willwinder.ugs.nbp.designer.entities.Entity;
import com.willwinder.ugs.nbp.designer.entities.EntityGroup;
import com.willwinder.ugs.nbp.designer.entities.controls.Location;
import com.willwinder.ugs.nbp.designer.entities.controls.ResizeUtils;
import com.willwinder.ugs.nbp.designer.model.Size;

Expand All @@ -34,30 +34,38 @@ This file is part of Universal Gcode Sender (UGS).
* @author Joacim Breiler
*/
public class ResizeAction implements UndoableAction {
private final Location location;
private final Anchor anchor;
private final List<Entity> entities;
private final Size originalSize;
private final Size newSize;

public ResizeAction(List<Entity> entities, Location location, Size originalSize, Size newSize) {
/**
* Resizes the entities from an anchor position
*
* @param entities a list of entities that is being resized
* @param anchor the corner that is being anchored
* @param originalSize the original size
* @param newSize the new size
*/
public ResizeAction(List<Entity> entities, Anchor anchor, Size originalSize, Size newSize) {
this.entities = new ArrayList<>(entities);
this.location = location;
this.originalSize = originalSize;
this.newSize = newSize;
this.anchor = anchor;
}

@Override
public void redo() {
EntityGroup entityGroup = new EntityGroup();
entityGroup.addAll(entities);
ResizeUtils.performScaling(entityGroup, location, originalSize, newSize);
ResizeUtils.performScaling(entityGroup, anchor, originalSize, newSize);
}

@Override
public void undo() {
EntityGroup entityGroup = new EntityGroup();
entityGroup.addAll(entities);
ResizeUtils.performScaling(entityGroup, location, newSize, originalSize);
ResizeUtils.performScaling(entityGroup, anchor, newSize, originalSize);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ public Size getSize() {

@Override
public void setSize(Size size) {
setSize(Anchor.BOTTOM_LEFT, size);
}

@Override
public void setSize(Anchor anchor, Size size) {
Point2D position = getPosition(anchor);
if (size.getWidth() <= 0) {
size = new Size(0.0001, size.getHeight());
}
Expand All @@ -97,6 +103,7 @@ public void setSize(Size size) {

Size currentSize = getSize();
scale(size.getWidth() / currentSize.getWidth(), size.getHeight() / currentSize.getHeight());
setPosition(anchor, position);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

public enum Anchor {
TOP_LEFT,
TOP_CENTER,
TOP_RIGHT,
CENTER,
BOTTOM_LEFT,
BOTTOM_CENTER,
LEFT_CENTER,
RIGHT_CENTER,
BOTTOM_RIGHT
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ public interface Entity {
*/
void setSize(Size size);

/**
* Changes the size of the entity from the given anchor.
*
* @param anchor the anchor to keep
* @param size the new size
*/
void setSize(Anchor anchor, Size size);

/**
* Gets the bounds of the entity with the position and size in real space
*
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.ugs.nbp.designer.Utils;
import com.willwinder.ugs.nbp.designer.actions.ResizeAction;
import com.willwinder.ugs.nbp.designer.actions.UndoManager;
import com.willwinder.ugs.nbp.designer.entities.Anchor;
import com.willwinder.ugs.nbp.designer.entities.Entity;
import com.willwinder.ugs.nbp.designer.entities.EntityEvent;
import com.willwinder.ugs.nbp.designer.entities.EventType;
Expand Down Expand Up @@ -51,40 +52,41 @@ public class ResizeControl extends AbstractControl {
public static final int SIZE = 8;
public static final int MARGIN = 6;
public static final double ARC_SIZE = 1d;
private final Location location;

private final RoundRectangle2D.Double shape;
private final Controller controller;
private final Anchor anchor;
private AffineTransform transform = new AffineTransform();
private Point2D.Double startOffset = new Point2D.Double();
private boolean isHovered;
private Size originalSize;
private Point2D originalPosition;

public ResizeControl(Controller controller, Location location) {
public ResizeControl(Controller controller, Anchor anchor) {
super(controller.getSelectionManager());
this.controller = controller;
this.location = location;
this.shape = new RoundRectangle2D.Double(0, 0, SIZE, SIZE, ARC_SIZE, ARC_SIZE);
this.anchor = anchor;
}

@Override
public Optional<Cursor> getHoverCursor() {
Cursor cursor = null;
if (location == Location.TOP_LEFT) {
if (anchor == Anchor.BOTTOM_RIGHT) {
cursor = new Cursor(Cursor.NW_RESIZE_CURSOR);
} else if (location == Location.TOP_RIGHT) {
} else if (anchor == Anchor.BOTTOM_LEFT) {
cursor = new Cursor(Cursor.NE_RESIZE_CURSOR);
} else if (location == Location.BOTTOM_LEFT) {
} else if (anchor == Anchor.TOP_RIGHT) {
cursor = new Cursor(Cursor.SW_RESIZE_CURSOR);
} else if (location == Location.BOTTOM_RIGHT) {
} else if (anchor == Anchor.TOP_LEFT) {
cursor = new Cursor(Cursor.SE_RESIZE_CURSOR);
} else if (location == Location.BOTTOM) {
} else if (anchor == Anchor.TOP_CENTER) {
cursor = new Cursor(Cursor.S_RESIZE_CURSOR);
} else if (location == Location.TOP) {
} else if (anchor == Anchor.BOTTOM_CENTER) {
cursor = new Cursor(Cursor.N_RESIZE_CURSOR);
} else if (location == Location.LEFT) {
} else if (anchor == Anchor.RIGHT_CENTER) {
cursor = new Cursor(Cursor.W_RESIZE_CURSOR);
} else if (location == Location.RIGHT) {
} else if (anchor == Anchor.LEFT_CENTER) {
cursor = new Cursor(Cursor.E_RESIZE_CURSOR);
}
return Optional.ofNullable(cursor);
Expand Down Expand Up @@ -138,11 +140,11 @@ public void onEvent(EntityEvent entityEvent) {
} else if (mouseShapeEvent.getType() == EventType.MOUSE_DRAGGED) {
Size size = getSelectionManager().getSize();
Size newSize = calculateNewSize(size, mousePosition);
ResizeUtils.performScaling(getSelectionManager(), location, size, newSize);
ResizeUtils.performScaling(getSelectionManager(), anchor, size, newSize);
} else if (mouseShapeEvent.getType() == EventType.MOUSE_RELEASED) {
getSelectionManager().setPosition(originalPosition);
Size newSize = calculateNewSize(originalSize, mousePosition);
addUndoAction(getSelectionManager(), location, originalSize, newSize);
addUndoAction(getSelectionManager(), anchor, originalSize, newSize);
} else if (mouseShapeEvent.getType() == EventType.MOUSE_IN) {
isHovered = true;
} else if (mouseShapeEvent.getType() == EventType.MOUSE_OUT) {
Expand All @@ -151,7 +153,7 @@ public void onEvent(EntityEvent entityEvent) {
}
}

private void addUndoAction(Entity target, Location location, Size originalSize, Size newSize) {
private void addUndoAction(Entity target, Anchor anchor, Size originalSize, Size newSize) {
UndoManager undoManager = ControllerFactory.getUndoManager();
if (undoManager != null) {
List<Entity> entityList = new ArrayList<>();
Expand All @@ -160,7 +162,7 @@ private void addUndoAction(Entity target, Location location, Size originalSize,
} else {
entityList.add(target);
}
ResizeAction resizeAction = new ResizeAction(entityList, location, originalSize, newSize);
ResizeAction resizeAction = new ResizeAction(entityList, anchor, originalSize, newSize);
resizeAction.redo();
undoManager.addAction(resizeAction);
}
Expand All @@ -179,21 +181,21 @@ private void updatePosition(Drawing drawing) {
Rectangle2D bounds = getSelectionManager().getRelativeShape().getBounds2D();
t.translate(bounds.getX(), bounds.getY());

if (location == Location.BOTTOM_RIGHT) {
if (anchor == Anchor.TOP_LEFT) {
t.translate(bounds.getWidth() + margin, -margin);
} else if (location == Location.TOP_LEFT) {
} else if (anchor == Anchor.BOTTOM_RIGHT) {
t.translate(-margin, bounds.getHeight() + margin);
} else if (location == Location.TOP_RIGHT) {
} else if (anchor == Anchor.BOTTOM_LEFT) {
t.translate(bounds.getWidth() + margin, bounds.getHeight() + margin);
} else if (location == Location.BOTTOM_LEFT) {
} else if (anchor == Anchor.TOP_RIGHT) {
t.translate(-margin, -margin);
} else if (location == Location.TOP) {
} else if (anchor == Anchor.BOTTOM_CENTER) {
t.translate(bounds.getWidth() / 2d, bounds.getHeight() + margin);
} else if (location == Location.BOTTOM) {
} else if (anchor == Anchor.TOP_CENTER) {
t.translate(bounds.getWidth() / 2d, -margin);
} else if (location == Location.LEFT) {
} else if (anchor == Anchor.RIGHT_CENTER) {
t.translate(-margin, bounds.getHeight() / 2d);
} else if (location == Location.RIGHT) {
} else if (anchor == Anchor.LEFT_CENTER) {
t.translate(bounds.getWidth() + margin, bounds.getHeight() / 2d);
}

Expand All @@ -218,21 +220,21 @@ private Size calculateNewSize(Size size, Point2D mousePosition) {

private Point2D getScaleFactor(double deltaX, double deltaY) {
Point2D scaleFactor = new Point2D.Double(0, 0);
if (location == Location.BOTTOM_LEFT) {
if (anchor == Anchor.TOP_RIGHT) {
scaleFactor.setLocation(1d - deltaX, 1d - deltaX);
} else if (location == Location.TOP_RIGHT) {
} else if (anchor == Anchor.BOTTOM_LEFT) {
scaleFactor.setLocation(1d + deltaX, 1d + deltaX);
} else if (location == Location.BOTTOM_RIGHT) {
} else if (anchor == Anchor.TOP_LEFT) {
scaleFactor.setLocation(1d + deltaX, 1d + deltaX);
} else if (location == Location.TOP_LEFT) {
} else if (anchor == Anchor.BOTTOM_RIGHT) {
scaleFactor.setLocation(1d - deltaX, 1d - deltaX);
} else if (location == Location.LEFT) {
} else if (anchor == Anchor.RIGHT_CENTER) {
scaleFactor.setLocation(1d - deltaX, 1d);
} else if (location == Location.BOTTOM) {
} else if (anchor == Anchor.TOP_CENTER) {
scaleFactor.setLocation(1d, 1d - deltaY);
} else if (location == Location.TOP) {
} else if (anchor == Anchor.BOTTOM_CENTER) {
scaleFactor.setLocation(1d, 1d + deltaY);
} else if (location == Location.RIGHT) {
} else if (anchor == Anchor.LEFT_CENTER) {
scaleFactor.setLocation(1d + deltaX, 1d);
}
return scaleFactor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This file is part of Universal Gcode Sender (UGS).
*/
package com.willwinder.ugs.nbp.designer.entities.controls;

import com.willwinder.ugs.nbp.designer.entities.Anchor;
import com.willwinder.ugs.nbp.designer.entities.Entity;
import com.willwinder.ugs.nbp.designer.model.Size;

Expand All @@ -28,30 +29,35 @@ public class ResizeUtils {
private ResizeUtils() {
}

public static Point2D getDeltaMovement(Location location, Size size, Size newSize) {
public static Point2D getDeltaMovement(Anchor anchor, Size size, Size newSize) {
Size deltaSize = new Size(size.getWidth() - newSize.getWidth(), size.getHeight() - newSize.getHeight());
Point2D movement = new Point2D.Double(0, 0);
if (location == Location.BOTTOM_LEFT) {
if (anchor == Anchor.TOP_RIGHT) {
movement.setLocation(deltaSize.getWidth(), deltaSize.getHeight());
} else if (location == Location.BOTTOM_RIGHT) {
} else if (anchor == Anchor.TOP_LEFT) {
movement.setLocation(0, deltaSize.getHeight());
} else if (location == Location.TOP_LEFT) {
} else if (anchor == Anchor.BOTTOM_RIGHT) {
movement.setLocation(deltaSize.getWidth(), 0);
} else if (location == Location.LEFT) {
movement.setLocation(deltaSize.getWidth(), 0);
} else if (location == Location.BOTTOM) {
movement.setLocation(0, deltaSize.getHeight());
} else if (anchor == Anchor.RIGHT_CENTER) {
movement.setLocation(deltaSize.getWidth(), deltaSize.getHeight() / 2);
} else if (anchor == Anchor.TOP_CENTER) {
movement.setLocation(deltaSize.getWidth() / 2, deltaSize.getHeight());
} else if (anchor == Anchor.CENTER) {
movement.setLocation(deltaSize.getWidth() / 2, deltaSize.getHeight() / 2);
} else if (anchor == Anchor.BOTTOM_CENTER) {
movement.setLocation(deltaSize.getWidth() / 2, 0);
} else if (anchor == Anchor.LEFT_CENTER) {
movement.setLocation(0, deltaSize.getHeight() / 2);
}
return movement;
}

public static void performScaling(Entity target, Location location, Size originalSize, Size newSize) {
public static void performScaling(Entity target, Anchor anchor, Size originalSize, Size newSize) {
// Do not scale if the entity will become too small after operation
if (newSize.getWidth() <= 0 || newSize.getHeight() <= 0) {
return;
}

target.move(getDeltaMovement(location, originalSize, newSize));
target.move(getDeltaMovement(anchor, originalSize, newSize));
target.setSize(newSize);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This file is part of Universal Gcode Sender (UGS).

import com.google.common.collect.Sets;
import com.willwinder.ugs.nbp.designer.Throttler;
import com.willwinder.ugs.nbp.designer.entities.Anchor;
import com.willwinder.ugs.nbp.designer.entities.Entity;
import com.willwinder.ugs.nbp.designer.entities.EntityGroup;
import com.willwinder.ugs.nbp.designer.entities.controls.Control;
Expand All @@ -30,7 +31,6 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.ugs.nbp.designer.entities.controls.EditTextControl;
import com.willwinder.ugs.nbp.designer.entities.controls.GridControl;
import com.willwinder.ugs.nbp.designer.entities.controls.HighlightModelControl;
import com.willwinder.ugs.nbp.designer.entities.controls.Location;
import com.willwinder.ugs.nbp.designer.entities.controls.MoveControl;
import com.willwinder.ugs.nbp.designer.entities.controls.ResizeControl;
import com.willwinder.ugs.nbp.designer.entities.controls.RotationControl;
Expand Down Expand Up @@ -86,14 +86,14 @@ public Drawing(Controller controller) {

controlsRoot = new EntityGroup();
globalRoot.addChild(controlsRoot);
controlsRoot.addChild(new ResizeControl(controller, Location.TOP));
controlsRoot.addChild(new ResizeControl(controller, Location.LEFT));
controlsRoot.addChild(new ResizeControl(controller, Location.RIGHT));
controlsRoot.addChild(new ResizeControl(controller, Location.BOTTOM));
controlsRoot.addChild(new ResizeControl(controller, Location.BOTTOM_LEFT));
controlsRoot.addChild(new ResizeControl(controller, Location.BOTTOM_RIGHT));
controlsRoot.addChild(new ResizeControl(controller, Location.TOP_LEFT));
controlsRoot.addChild(new ResizeControl(controller, Location.TOP_RIGHT));
controlsRoot.addChild(new ResizeControl(controller, Anchor.TOP_CENTER));
controlsRoot.addChild(new ResizeControl(controller, Anchor.LEFT_CENTER));
controlsRoot.addChild(new ResizeControl(controller, Anchor.RIGHT_CENTER));
controlsRoot.addChild(new ResizeControl(controller, Anchor.BOTTOM_CENTER));
controlsRoot.addChild(new ResizeControl(controller, Anchor.BOTTOM_LEFT));
controlsRoot.addChild(new ResizeControl(controller, Anchor.BOTTOM_RIGHT));
controlsRoot.addChild(new ResizeControl(controller, Anchor.TOP_LEFT));
controlsRoot.addChild(new ResizeControl(controller, Anchor.TOP_RIGHT));
controlsRoot.addChild(new HighlightModelControl(controller.getSelectionManager()));
controlsRoot.addChild(new MoveControl(controller));
controlsRoot.addChild(new RotationControl(controller));
Expand Down
Loading
Loading