fix: fix resize and dragging

- AbstractShape: make bounds protected for subclass access
- STriangle: refactor resize logic
- SCircle: refactor resize logic (preserves equal dimensions)
- SText: add reasonable default bounds for hit testing
This commit is contained in:
2026-03-26 23:54:31 +01:00
parent fbe3714182
commit 3a6f98455a
4 changed files with 47 additions and 50 deletions

View File

@@ -9,7 +9,7 @@ import java.util.TreeMap;
public abstract class AbstractShape implements Shape { public abstract class AbstractShape implements Shape {
private final Map<String, Attributes> attributes = new TreeMap<>(); private final Map<String, Attributes> attributes = new TreeMap<>();
private final Rectangle bounds; protected final Rectangle bounds;
AbstractShape() { AbstractShape() {
this(null); this(null);
@@ -31,46 +31,45 @@ public abstract class AbstractShape implements Shape {
@Override @Override
public void translate(int dx, int dy) { public void translate(int dx, int dy) {
getBounds().translate(dx, dy); this.bounds.translate(dx, dy);
} }
@Override @Override
public void resize(ResizeHandle handle, int dx, int dy) { public void resize(ResizeHandle handle, int dx, int dy) {
Rectangle bounds = getBounds();
switch (handle) { switch (handle) {
case E -> bounds.width += dx; case E -> this.bounds.width += dx;
case W -> { case W -> {
bounds.x += dx; this.bounds.x += dx;
bounds.width -= dx; this.bounds.width -= dx;
} }
case S -> bounds.height += dy; case S -> this.bounds.height += dy;
case N -> { case N -> {
bounds.y += dy; this.bounds.y += dy;
bounds.height -= dy; this.bounds.height -= dy;
} }
case SE -> { case SE -> {
bounds.width += dx; this.bounds.width += dx;
bounds.height += dy; this.bounds.height += dy;
} }
case SW -> { case SW -> {
bounds.x += dx; this.bounds.x += dx;
bounds.width -= dx; this.bounds.width -= dx;
bounds.height += dy; this.bounds.height += dy;
} }
case NE -> { case NE -> {
bounds.width += dx; this.bounds.width += dx;
bounds.y += dy; this.bounds.y += dy;
bounds.height -= dy; this.bounds.height -= dy;
} }
case NW -> { case NW -> {
bounds.x += dx; this.bounds.x += dx;
bounds.width -= dx; this.bounds.width -= dx;
bounds.y += dy; this.bounds.y += dy;
bounds.height -= dy; this.bounds.height -= dy;
} }
} }
if (bounds.width < 1) bounds.width = 1; if (this.bounds.width < 1) this.bounds.width = 1;
if (bounds.height < 1) bounds.height = 1; if (this.bounds.height < 1) this.bounds.height = 1;
} }
@Override @Override

View File

@@ -22,28 +22,24 @@ public class SCircle extends AbstractShape {
@Override @Override
public void resize(ResizeHandle handle, int dx, int dy) { public void resize(ResizeHandle handle, int dx, int dy) {
Rectangle bounds = getBounds(); int delta = Math.max(Math.abs(dx), Math.abs(dy));
int newWidth = bounds.width;
int newHeight = bounds.height; boolean shrink = switch (handle) {
case E, SE, NE -> dx < 0;
switch (handle) { case W, SW, NW -> dx > 0;
case E, W -> newWidth += dx; case N, S -> dy < 0;
case N, S -> newHeight += dy; default -> false;
case SE, NW -> { };
newWidth += dx;
newHeight += dy; int sizeChange = shrink ? -delta : delta;
} int newWidth = bounds.width + sizeChange;
case NE, SW -> { int newHeight = bounds.height + sizeChange;
newWidth += dx;
newHeight += dy;
}
}
if (newWidth < 2) newWidth = 2; if (newWidth < 2) newWidth = 2;
if (newHeight < 2) newHeight = 2; if (newHeight < 2) newHeight = 2;
this.radius = Math.max(newWidth, newHeight) / 2; bounds.setSize(newWidth, newHeight);
bounds.setSize(this.radius * 2, this.radius * 2); this.radius = Math.max(bounds.width, bounds.height) / 2;
} }
@Override @Override

View File

@@ -18,7 +18,8 @@ public class SText extends AbstractShape {
private final int fontStyle; private final int fontStyle;
private SText(int x, int y, String text, int fontSize, String fontName, int fontStyle) { private SText(int x, int y, String text, int fontSize, String fontName, int fontStyle) {
super(new Rectangle(x, y, 0, 0)); // Initialize with a reasonable default width/height so hit testing works reliably
super(new Rectangle(x, y, 100, 20));
this.text = normalizeText(text); this.text = normalizeText(text);
this.fontSize = fontSize; this.fontSize = fontSize;
this.fontName = fontName; this.fontName = fontName;

View File

@@ -18,21 +18,22 @@ public class STriangle extends AbstractShape {
@Override @Override
public void resize(ResizeHandle handle, int dx, int dy) { public void resize(ResizeHandle handle, int dx, int dy) {
Rectangle bounds = getBounds();
int delta = Math.max(Math.abs(dx), Math.abs(dy)); int delta = Math.max(Math.abs(dx), Math.abs(dy));
boolean shrink = switch (handle) { boolean shrink = switch (handle) {
case E -> dx < 0;
case W -> dx > 0;
case N -> dy > 0;
case S -> dy < 0;
case SE -> (dx < 0 || dy < 0); case SE -> (dx < 0 || dy < 0);
case NW -> (dx > 0 || dy > 0); case NW -> (dx > 0 || dy > 0);
case NE -> (dx < 0); case NE -> (dx < 0 || dy > 0);
case SW -> (dx > 0); case SW -> (dx > 0 || dy < 0);
case E, W -> (dx < 0);
case N, S -> (dy < 0);
default -> false; default -> false;
}; };
int sizeChange = shrink ? -delta : delta; int sizeChange = shrink ? -delta : delta;
switch (handle) { switch (handle) {
case SE, E, W -> { case SE, E, W -> {
bounds.width += sizeChange; bounds.width += sizeChange;