From b4eac668c8ffd3ba1f37b701c9fdf798d8c25fbd Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 19 Feb 2025 10:50:27 +0100 Subject: [PATCH] Add delete shape operation --- .../newshapes/shapes/AbstractShape.java | 4 +-- .../gasser/newshapes/shapes/SCollection.java | 11 ++++-- .../ovh/gasser/newshapes/ui/Controller.java | 35 ++++++++++++++++++- .../gasser/newshapes/ui/ShapeDraftman.java | 2 +- .../newshapes/ui/html/HTMLDraftman.java | 4 +-- 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/main/java/ovh/gasser/newshapes/shapes/AbstractShape.java b/src/main/java/ovh/gasser/newshapes/shapes/AbstractShape.java index dc3650a..2515878 100644 --- a/src/main/java/ovh/gasser/newshapes/shapes/AbstractShape.java +++ b/src/main/java/ovh/gasser/newshapes/shapes/AbstractShape.java @@ -8,8 +8,8 @@ import java.util.TreeMap; public abstract class AbstractShape implements Shape { - private Map attributes = new TreeMap<>(); - private Rectangle bounds; + private final Map attributes = new TreeMap<>(); + private final Rectangle bounds; AbstractShape() { this(null); diff --git a/src/main/java/ovh/gasser/newshapes/shapes/SCollection.java b/src/main/java/ovh/gasser/newshapes/shapes/SCollection.java index 6eddb68..f5ffdbb 100644 --- a/src/main/java/ovh/gasser/newshapes/shapes/SCollection.java +++ b/src/main/java/ovh/gasser/newshapes/shapes/SCollection.java @@ -8,16 +8,17 @@ import ovh.gasser.newshapes.attributes.SelectionAttributes; import ovh.gasser.newshapes.util.Streamable; import java.awt.*; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Spliterator; public class SCollection extends AbstractShape implements Streamable { private final static Logger logger = LoggerFactory.getLogger(SCollection.class); - private final List children; + private List children; private SCollection(Shape... shapes) { - this.children = List.of(shapes); + this.children = new ArrayList<>(List.of(shapes)); } @Override @@ -58,6 +59,12 @@ public class SCollection extends AbstractShape implements Streamable { return children.spliterator(); } + public void remove(Shape s) { + if (!children.remove(s)) { + logger.error("Unable to delete shape: {}", s); + } + } + @Override public String toString() { StringBuilder sb = new StringBuilder("SCollection{"); diff --git a/src/main/java/ovh/gasser/newshapes/ui/Controller.java b/src/main/java/ovh/gasser/newshapes/ui/Controller.java index 8e29120..70a38dd 100644 --- a/src/main/java/ovh/gasser/newshapes/ui/Controller.java +++ b/src/main/java/ovh/gasser/newshapes/ui/Controller.java @@ -6,12 +6,14 @@ import ovh.gasser.newshapes.Selection; import ovh.gasser.newshapes.shapes.SCollection; import ovh.gasser.newshapes.shapes.Shape; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Optional; public class Controller { - private final static Logger logger = LoggerFactory.getLogger(ShapesView.class); + private final static Logger logger = LoggerFactory.getLogger(Controller.class); private final ShapesView view; private final Shape model; private Selection selection; @@ -19,6 +21,7 @@ public class Controller { Controller(ShapesView view, Shape model) { this.view = view; this.model = model; + var adapter = new MouseAdapter() { @Override public void mousePressed(MouseEvent evt) { @@ -32,6 +35,16 @@ public class Controller { }; this.view.addMouseMotionListener(adapter); this.view.addMouseListener(adapter); + + this.view.setFocusable(true); + boolean res = this.view.requestFocusInWindow(); + assert res; + this.view.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + handleKeyPressed(e); + } + }); } private void handleMouseDragged(MouseEvent evt) { @@ -55,6 +68,26 @@ public class Controller { view.repaint(); } + private void handleKeyPressed(KeyEvent evt) { + switch (evt.getKeyCode()) { + case KeyEvent.VK_DELETE: + deleteSelected(); + break; + default: + logger.warn("Pressed unhandled key: {}", evt.getKeyChar()); + break; + } + } + + private void deleteSelected() { + if (selection == null) return; + logger.debug("Deleting selected shape(s)"); + var sc = (SCollection) this.model; + sc.remove(selection.shape); + selection = null; + view.repaint(); + } + private void resetSelection() { logger.debug("Un-selecting {}", selection.shape); selection.unselect(); diff --git a/src/main/java/ovh/gasser/newshapes/ui/ShapeDraftman.java b/src/main/java/ovh/gasser/newshapes/ui/ShapeDraftman.java index 4460702..983ba9b 100644 --- a/src/main/java/ovh/gasser/newshapes/ui/ShapeDraftman.java +++ b/src/main/java/ovh/gasser/newshapes/ui/ShapeDraftman.java @@ -14,7 +14,7 @@ public class ShapeDraftman implements ShapeVisitor { private static final ColorAttributes DEFAULT_COLOR_ATTRIBUTES = new ColorAttributes(false, true, Color.BLACK, Color.BLACK); - private Graphics2D g2d; + private final Graphics2D g2d; public ShapeDraftman(Graphics graph) { diff --git a/src/main/java/ovh/gasser/newshapes/ui/html/HTMLDraftman.java b/src/main/java/ovh/gasser/newshapes/ui/html/HTMLDraftman.java index b696f2e..062a47f 100644 --- a/src/main/java/ovh/gasser/newshapes/ui/html/HTMLDraftman.java +++ b/src/main/java/ovh/gasser/newshapes/ui/html/HTMLDraftman.java @@ -23,8 +23,8 @@ public class HTMLDraftman implements ShapeVisitor { private static final String FOOTER_TEMPLATE = ""; - private PrintWriter htmlOutput; - private PrintWriter cssOutput; + private final PrintWriter htmlOutput; + private final PrintWriter cssOutput; public HTMLDraftman(PrintWriter htmlOutput, PrintWriter cssOutput) { this.htmlOutput = htmlOutput;