From da23e1d40a26359d317ae876da440ad373015fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Thu, 16 May 2024 16:37:24 +0200 Subject: [PATCH] Hover + Wire delete --- src/main/java/de/ph87/electro/CONFIG.java | 10 +- .../java/de/ph87/electro/circuit/Circuit.java | 17 +++ .../de/ph87/electro/circuit/CircuitPanel.java | 4 - .../circuit/CircuitPanelMouseAdapter.java | 104 +++++++++++++----- .../java/de/ph87/electro/circuit/Wire.java | 21 ++++ .../ph87/electro/circuit/part/Junction.java | 3 +- .../de/ph87/electro/common/MathHelpers.java | 7 -- 7 files changed, 124 insertions(+), 42 deletions(-) diff --git a/src/main/java/de/ph87/electro/CONFIG.java b/src/main/java/de/ph87/electro/CONFIG.java index 617d735..c6aa60a 100644 --- a/src/main/java/de/ph87/electro/CONFIG.java +++ b/src/main/java/de/ph87/electro/CONFIG.java @@ -7,7 +7,7 @@ import static java.lang.Math.round; public class CONFIG { public static final double BULB_VOLTAGE_MIN = 0.5; - + public static final double VOLTAGE = 3.0; public static final int RASTER = 200; @@ -24,8 +24,12 @@ public class CONFIG { public static final int JUNCTION_RADIUS = (int) round(0.05 * RASTER); + public static final int JUNCTION_RADIUS_HOVER = (int) round(1.5 * JUNCTION_RADIUS); + public static final Color PART_BACKGROUND = new Color(224, 224, 224); + public static final Color PART_HOVER_COLOR = new Color(192, 192, 192, 128); + public static final Color RASTER_COLOR = Color.gray; public static final Color VOLTAGE_UNKNOWN_COLOR = Color.darkGray; @@ -42,7 +46,9 @@ public class CONFIG { public static final BasicStroke WIRE_STROKE = new BasicStroke(5); - public static final BasicStroke WIRE_STROKE_BACK = new BasicStroke(0); + public static final BasicStroke WIRE_STROKE_BACK = new BasicStroke(WIRE_STROKE.getLineWidth() + 2); + + public static final BasicStroke WIRE_STROKE_BACK2 = new BasicStroke(WIRE_STROKE_BACK.getLineWidth() + 2); public static final BasicStroke SWITCH_STROKE = new BasicStroke(15); diff --git a/src/main/java/de/ph87/electro/circuit/Circuit.java b/src/main/java/de/ph87/electro/circuit/Circuit.java index 893ea32..ffcfb49 100644 --- a/src/main/java/de/ph87/electro/circuit/Circuit.java +++ b/src/main/java/de/ph87/electro/circuit/Circuit.java @@ -12,8 +12,12 @@ import lombok.extern.slf4j.Slf4j; import java.awt.*; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Stream; +import static de.ph87.electro.CONFIG.RASTER; +import static de.ph87.electro.common.MathHelpers.div; + @Slf4j @NoArgsConstructor public class Circuit { @@ -121,4 +125,17 @@ public class Circuit { return parts.size(); } + public Optional findPart(final Point point) { + final Point cell = div(point, RASTER); + return streamParts().filter(p -> p.getPosition().equals(cell)).findFirst(); + } + + public Optional findJunctionByPoint(final Point point) { + return findPart(point).flatMap(part -> part.findJunction(point)); + } + + public Optional findWireByPoint(final Point point) { + return getWires().stream().filter(wire -> wire.intersects(point)).findFirst(); + } + } diff --git a/src/main/java/de/ph87/electro/circuit/CircuitPanel.java b/src/main/java/de/ph87/electro/circuit/CircuitPanel.java index be11a62..cffd33b 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitPanel.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitPanel.java @@ -57,10 +57,6 @@ public class CircuitPanel extends JPanel { final Point a = wire.getA().getAbsolute(); final Point b = wire.getB().getAbsolute(); - g.setColor(Color.BLACK); - g.setStroke(WIRE_STROKE_BACK); - g.drawLine(a.x, a.y, b.x, b.y); - g.setColor(wire.getA().getColor()); g.setStroke(WIRE_STROKE); g.drawLine(a.x, a.y, b.x, b.y); diff --git a/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java b/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java index ecd7a8c..3b4d728 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java @@ -19,9 +19,15 @@ class CircuitPanelMouseAdapter extends MouseAdapter { private final CircuitPanel circuitPanel; - private Part part = null; + private Part partHover = null; - private Junction junction = null; + private Junction junctionHover = null; + + private Wire wireHover = null; + + private Part partDrag = null; + + private Junction junctionDrag = null; private Point dragPosition = null; @@ -33,6 +39,18 @@ class CircuitPanelMouseAdapter extends MouseAdapter { @Override public void mouseClicked(final MouseEvent e) { + if (e.getButton() == BUTTON3) { + final Optional wireOptional = circuitPanel.getCircuit().findWireByPoint(e.getPoint()); + if (wireOptional.isPresent()) { + final Wire wire = wireOptional.get(); + wire.getA().getDestinations().remove(wire.getB()); + wire.getB().getDestinations().remove(wire.getA()); + circuitPanel.getCircuit().evaluate(); + circuitPanel.repaint(); + return; + } + } + final Point cell = div(e.getPoint(), RASTER); final Optional partOptional = circuitPanel.getCircuit().streamParts().filter(p -> p.getPosition().equals(cell)).findFirst(); switch (e.getButton()) { @@ -46,54 +64,86 @@ class CircuitPanelMouseAdapter extends MouseAdapter { } } + @Override + public void mouseMoved(final MouseEvent e) { + findHover(e.getPoint()); + circuitPanel.repaint(); + } + @Override public void mousePressed(final MouseEvent event) { - findPart(event.getPoint()).ifPresent(part -> startPartOrJunction(part, event.getPoint())); + circuitPanel.getCircuit().findPart(event.getPoint()).ifPresent(part -> startPartOrJunction(part, event.getPoint())); } private void startPartOrJunction(final Part part, final Point point) { - part.findJunction(point).ifPresentOrElse(junction -> this.junction = junction, () -> this.part = part); - } - - private Optional findPart(final Point point) { - final Point cell = div(point, RASTER); - return circuitPanel.getCircuit().streamParts().filter(p -> p.getPosition().equals(cell)).findFirst(); + part.findJunction(point).ifPresentOrElse(junction -> { + partDrag = null; + junctionDrag = junction; + }, () -> { + partDrag = part; + junctionDrag = null; + }); } @Override public void mouseDragged(final MouseEvent e) { - if (part != null || junction != null) { + findHover(e.getPoint()); + if (partDrag != null || junctionDrag != null) { dragPosition = e.getPoint(); circuitPanel.repaint(); } } + private void findHover(final Point point) { + partHover = circuitPanel.getCircuit().findPart(point).orElse(null); + junctionHover = partHover != null ? partHover.findJunction(point).orElse(null) : null; + if (junctionHover == null) { + wireHover = circuitPanel.getCircuit().findWireByPoint(point).orElse(null); + } else { + wireHover = null; + } + circuitPanel.repaint(); + } + @Override public void mouseReleased(final MouseEvent event) { - if (part != null) { - circuitPanel.getCircuit().partMove(part, div(event.getPoint(), RASTER)); - - part = null; - circuitPanel.repaint(); + if (partDrag != null && junctionDrag != null) { + throw new RuntimeException(); + } + if ((partDrag != null || junctionDrag != null) == (dragPosition == null)) { + throw new RuntimeException(); } - if (junction != null) { - findPart(event.getPoint()) - .flatMap(part -> part.findJunction(event.getPoint()).filter(destination -> destination != junction)) - .ifPresent(destination -> circuitPanel.getCircuit().connect(junction, destination)); - - junction = null; - circuitPanel.repaint(); + if (partDrag != null) { + circuitPanel.getCircuit().partMove(partDrag, div(event.getPoint(), RASTER)); } + + if (junctionDrag != null) { + circuitPanel.getCircuit().findJunctionByPoint(event.getPoint()).filter(destination -> destination != junctionDrag).ifPresent(destination -> circuitPanel.getCircuit().connect(junctionDrag, destination)); + } + + partDrag = null; + junctionDrag = null; + dragPosition = null; + circuitPanel.repaint(); } public void drawDrag(final Graphics2D g) { - if (part != null) { - g.setColor(new Color(192, 192, 192, 128)); - g.fillRect(dragPosition.x - HALF, dragPosition.y - HALF, RASTER, RASTER); + if (junctionHover != null) { + junctionHover.getOwner().circle(g, junctionHover.getAbsolute().x, junctionHover.getAbsolute().y, JUNCTION_RADIUS_HOVER, Color.BLACK, NORMAL_STROKE, junctionHover.getColor()); } - if (junction != null) { - junction.getOwner().line(g, junction.getAbsolute(), dragPosition, junction.getColor(), WIRE_STROKE); + if (wireHover != null) { + wireHover.getA().getOwner().line(g, wireHover.getA().getAbsolute(), wireHover.getB().getAbsolute(), Color.black, WIRE_STROKE_BACK2); + wireHover.getA().getOwner().line(g, wireHover.getA().getAbsolute(), wireHover.getB().getAbsolute(), wireHover.getA().getColor(), WIRE_STROKE_BACK); + } + if (dragPosition != null) { + if (partDrag != null) { + g.setColor(PART_HOVER_COLOR); + g.fillRect(dragPosition.x - HALF, dragPosition.y - HALF, RASTER, RASTER); + } + if (junctionDrag != null) { + junctionDrag.getOwner().line(g, junctionDrag.getAbsolute(), dragPosition, junctionDrag.getColor(), WIRE_STROKE); + } } } diff --git a/src/main/java/de/ph87/electro/circuit/Wire.java b/src/main/java/de/ph87/electro/circuit/Wire.java index 388936f..1f39149 100644 --- a/src/main/java/de/ph87/electro/circuit/Wire.java +++ b/src/main/java/de/ph87/electro/circuit/Wire.java @@ -3,6 +3,10 @@ package de.ph87.electro.circuit; import de.ph87.electro.circuit.part.Junction; import lombok.Data; +import java.awt.*; + +import static de.ph87.electro.CONFIG.WIRE_STROKE_BACK2; + @Data public class Wire { @@ -19,4 +23,21 @@ public class Wire { return (a == x && b == y) || (a == y && b == x); } + public boolean intersects(final Point p) { + final Point start = a.getAbsolute(); + final Point end = b.getAbsolute(); + double dx = end.x - start.x; + double dy = end.y - start.y; + double length = dx * dx + dy * dy; + if (length == 0) { + return p.distance(start) <= WIRE_STROKE_BACK2.getLineWidth(); + } + + double t = ((p.x - start.x) * dx + (p.y - start.y) * dy) / length; + t = Math.max(0, Math.min(1, t)); + double closestX = start.x + t * dx; + double closestY = start.y + t * dy; + return p.distance(closestX, closestY) <= WIRE_STROKE_BACK2.getLineWidth(); + } + } diff --git a/src/main/java/de/ph87/electro/circuit/part/Junction.java b/src/main/java/de/ph87/electro/circuit/part/Junction.java index fbbe7b4..482c4ab 100644 --- a/src/main/java/de/ph87/electro/circuit/part/Junction.java +++ b/src/main/java/de/ph87/electro/circuit/part/Junction.java @@ -13,7 +13,6 @@ import java.util.Set; import java.util.UUID; import static de.ph87.electro.CONFIG.*; -import static de.ph87.electro.common.MathHelpers.distance; @Getter @ToString(onlyExplicitlyIncluded = true) @@ -109,7 +108,7 @@ public class Junction { } public boolean intersects(final Point absolute) { - return distance(getAbsolute(), absolute) <= JUNCTION_RADIUS; + return getAbsolute().distance(absolute) <= JUNCTION_RADIUS_HOVER; } } diff --git a/src/main/java/de/ph87/electro/common/MathHelpers.java b/src/main/java/de/ph87/electro/common/MathHelpers.java index 966a3fa..0638e5b 100644 --- a/src/main/java/de/ph87/electro/common/MathHelpers.java +++ b/src/main/java/de/ph87/electro/common/MathHelpers.java @@ -2,17 +2,10 @@ package de.ph87.electro.common; import java.awt.*; -import static java.lang.Math.pow; -import static java.lang.Math.sqrt; - public class MathHelpers { public static Point div(final Point p, final int div) { return new Point(p.x / div, p.y / div); } - public static double distance(final Point a, final Point b) { - return sqrt(pow(b.x - a.x, 2) + pow(b.y - a.y, 2)); - } - }