Hover + Wire delete

This commit is contained in:
Patrick Haßel 2024-05-16 16:37:24 +02:00
parent 7ae8a35e0c
commit da23e1d40a
7 changed files with 124 additions and 42 deletions

View File

@ -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);

View File

@ -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<Part> findPart(final Point point) {
final Point cell = div(point, RASTER);
return streamParts().filter(p -> p.getPosition().equals(cell)).findFirst();
}
public Optional<Junction> findJunctionByPoint(final Point point) {
return findPart(point).flatMap(part -> part.findJunction(point));
}
public Optional<Wire> findWireByPoint(final Point point) {
return getWires().stream().filter(wire -> wire.intersects(point)).findFirst();
}
}

View File

@ -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);

View File

@ -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<Wire> 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<Part> 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<Part> 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);
}
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}