diff --git a/src/main/java/de/ph87/electro/Window.java b/src/main/java/de/ph87/electro/Window.java index 67e06b7..f97f9cf 100644 --- a/src/main/java/de/ph87/electro/Window.java +++ b/src/main/java/de/ph87/electro/Window.java @@ -8,8 +8,6 @@ import java.awt.*; public class Window extends JFrame { - private final CircuitPanel circuit = new CircuitPanel(); - public Window() { GridBagConstraints c; setLayout(new GridBagLayout()); @@ -19,14 +17,14 @@ public class Window extends JFrame { c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.BOTH; - add(new Sidebar(part -> circuit.getCircuit().partAdd(part)), c); + add(new Sidebar(), c); c = new GridBagConstraints(); c.gridx = 1; c.weightx = 4; c.weighty = 1; c.fill = GridBagConstraints.BOTH; - add(circuit, c); + add(new CircuitPanel(), c); positionOnRightMostScreen(); setDefaultCloseOperation(EXIT_ON_CLOSE); diff --git a/src/main/java/de/ph87/electro/circuit/Circuit.java b/src/main/java/de/ph87/electro/circuit/Circuit.java index a955e04..a77c7c4 100644 --- a/src/main/java/de/ph87/electro/circuit/Circuit.java +++ b/src/main/java/de/ph87/electro/circuit/Circuit.java @@ -63,15 +63,12 @@ public class Circuit { public void connect(final Junction a, final Junction b) { a.getDestinations().add(b); b.getDestinations().add(a); + evaluate(); } public void evaluate() { parts.forEach(Part::reset); streamBatteries().forEach(PartBattery::startPropagation); - render(); - } - - public void render() { parts.forEach(Part::render); } diff --git a/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java b/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java index 13edbf3..ecd7a8c 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java @@ -1,27 +1,29 @@ package de.ph87.electro.circuit; +import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Part; +import lombok.extern.slf4j.Slf4j; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Optional; -import static de.ph87.electro.CONFIG.HALF; -import static de.ph87.electro.CONFIG.RASTER; +import static de.ph87.electro.CONFIG.*; import static de.ph87.electro.common.MathHelpers.div; import static java.awt.event.MouseEvent.BUTTON1; import static java.awt.event.MouseEvent.BUTTON3; +@Slf4j class CircuitPanelMouseAdapter extends MouseAdapter { private final CircuitPanel circuitPanel; - private Part dragPart = null; + private Part part = null; - private Point dragPoint = null; + private Junction junction = null; - private Point dragOffset = null; + private Point dragPosition = null; CircuitPanelMouseAdapter(final CircuitPanel circuitPanel) { this.circuitPanel = circuitPanel; @@ -35,52 +37,63 @@ class CircuitPanelMouseAdapter extends MouseAdapter { final Optional partOptional = circuitPanel.getCircuit().streamParts().filter(p -> p.getPosition().equals(cell)).findFirst(); switch (e.getButton()) { case BUTTON1: - partOptional.ifPresent(part -> { - part.click(); - circuitPanel.getCircuit().evaluate(); - circuitPanel.repaint(); - }); + partOptional.ifPresent(Part::action); + circuitPanel.getCircuit().evaluate(); break; case BUTTON3: - partOptional.ifPresent(part -> { - part.clockwise(); - circuitPanel.getCircuit().render(); - circuitPanel.repaint(); - }); + partOptional.ifPresent(Part::clockwise); break; } } @Override - public void mousePressed(final MouseEvent e) { - final Point cell = div(e.getPoint(), RASTER); - dragOffset = new Point(HALF, HALF); - dragPart = circuitPanel.getCircuit().streamParts().filter(p -> p.getPosition().equals(cell)).findFirst().orElse(null); + public void mousePressed(final MouseEvent event) { + 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(); } @Override public void mouseDragged(final MouseEvent e) { - if (dragPart != null) { - dragPoint = e.getPoint(); + if (part != null || junction != null) { + dragPosition = e.getPoint(); circuitPanel.repaint(); } } @Override - public void mouseReleased(final MouseEvent e) { - if (dragPart != null) { - circuitPanel.getCircuit().partMove(dragPart, div(e.getPoint(), RASTER)); - dragPart = null; - dragPoint = null; - dragOffset = null; + public void mouseReleased(final MouseEvent event) { + if (part != null) { + circuitPanel.getCircuit().partMove(part, div(event.getPoint(), RASTER)); + + part = null; + circuitPanel.repaint(); + } + + 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(); } } public void drawDrag(final Graphics2D g) { - if (dragPart != null && dragPoint != null) { + if (part != null) { g.setColor(new Color(192, 192, 192, 128)); - g.fillRect(dragPoint.x - dragOffset.x, dragPoint.y - dragOffset.y, RASTER, RASTER); + g.fillRect(dragPosition.x - HALF, dragPosition.y - HALF, RASTER, RASTER); + } + if (junction != null) { + junction.getOwner().line(g, junction.getAbsolute(), dragPosition, junction.getColor(), WIRE_STROKE); } } 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 da28dd2..fbbe7b4 100644 --- a/src/main/java/de/ph87/electro/circuit/part/Junction.java +++ b/src/main/java/de/ph87/electro/circuit/part/Junction.java @@ -13,6 +13,7 @@ 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) @@ -107,4 +108,8 @@ public class Junction { return owner.getOrientation().rotate(position); } + public boolean intersects(final Point absolute) { + return distance(getAbsolute(), absolute) <= JUNCTION_RADIUS; + } + } diff --git a/src/main/java/de/ph87/electro/circuit/part/Part.java b/src/main/java/de/ph87/electro/circuit/part/Part.java index 4db815a..9b3adbc 100644 --- a/src/main/java/de/ph87/electro/circuit/part/Part.java +++ b/src/main/java/de/ph87/electro/circuit/part/Part.java @@ -11,6 +11,7 @@ import java.awt.*; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; import static de.ph87.electro.CONFIG.*; @@ -85,12 +86,17 @@ public abstract class Part { public void clockwise() { orientation = orientation.clockwise(); + render(); } public void line(final Graphics2D g, final Junction junction0, final Junction junction1, final Color color, final BasicStroke stroke) { line(g, junction0.getPosition().x, junction0.getPosition().y, junction1.getPosition().x, junction1.getPosition().y, color, stroke); } + public void line(final Graphics2D g, final Point p0, final Point p1, final Color color, final BasicStroke stroke) { + line(g, p0.x, p0.y, p1.x, p1.y, color, stroke); + } + public void line(final Graphics2D g, final Junction junction0, final double x1, final double y1, final Color color, final BasicStroke stroke) { line(g, junction0.getPosition().x, junction0.getPosition().y, x1, y1, color, stroke); } @@ -147,7 +153,11 @@ public abstract class Part { ); } - public abstract void click(); + public Optional findJunction(final Point absolute) { + return junctions.stream().filter(junction -> junction.intersects(absolute)).findFirst(); + } + + public abstract void action(); public abstract void propagate(final Junction source) throws ShortCircuit; diff --git a/src/main/java/de/ph87/electro/circuit/part/impl/PartBattery.java b/src/main/java/de/ph87/electro/circuit/part/impl/PartBattery.java index ad7b9b0..2cc9eca 100644 --- a/src/main/java/de/ph87/electro/circuit/part/impl/PartBattery.java +++ b/src/main/java/de/ph87/electro/circuit/part/impl/PartBattery.java @@ -54,11 +54,6 @@ public class PartBattery extends Part { voltage = dto.getVoltage(); } - @Override - public void clockwise() { - super.clockwise(); - } - public void startPropagation() { try { shortCircuit = null; @@ -83,7 +78,7 @@ public class PartBattery extends Part { } @Override - public void click() { + public void action() { // nothing } diff --git a/src/main/java/de/ph87/electro/circuit/part/impl/PartLight.java b/src/main/java/de/ph87/electro/circuit/part/impl/PartLight.java index d657dcf..fa1a2ee 100644 --- a/src/main/java/de/ph87/electro/circuit/part/impl/PartLight.java +++ b/src/main/java/de/ph87/electro/circuit/part/impl/PartLight.java @@ -91,7 +91,7 @@ public class PartLight extends PartOther { } @Override - public void click() { + public void action() { defect = false; } diff --git a/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x1.java b/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x1.java index 35c4c40..52aea9b 100644 --- a/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x1.java +++ b/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x1.java @@ -65,7 +65,7 @@ public class PartSwitch1x1 extends PartOther { } @Override - public void click() { + public void action() { state = !state; } diff --git a/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x2.java b/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x2.java index 5cd3bf9..0396e1b 100644 --- a/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x2.java +++ b/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitch1x2.java @@ -75,7 +75,7 @@ public class PartSwitch1x2 extends PartOther { } @Override - public void click() { + public void action() { state = !state; } diff --git a/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitchCross.java b/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitchCross.java index 3577063..79f2155 100644 --- a/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitchCross.java +++ b/src/main/java/de/ph87/electro/circuit/part/impl/PartSwitchCross.java @@ -91,7 +91,7 @@ public class PartSwitchCross extends PartOther { } @Override - public void click() { + public void action() { state = !state; } diff --git a/src/main/java/de/ph87/electro/common/MathHelpers.java b/src/main/java/de/ph87/electro/common/MathHelpers.java index 0638e5b..966a3fa 100644 --- a/src/main/java/de/ph87/electro/common/MathHelpers.java +++ b/src/main/java/de/ph87/electro/common/MathHelpers.java @@ -2,10 +2,17 @@ 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)); + } + } diff --git a/src/main/java/de/ph87/electro/demo/DemoAll.java b/src/main/java/de/ph87/electro/demo/DemoAll.java index e344539..10251d9 100644 --- a/src/main/java/de/ph87/electro/demo/DemoAll.java +++ b/src/main/java/de/ph87/electro/demo/DemoAll.java @@ -9,8 +9,6 @@ import static de.ph87.electro.CONFIG.VOLTAGE; public class DemoAll { public static Circuit complexTrippleAndSimple() { - final double voltage = 3.0; - final Circuit circuit = new Circuit(); final PartBattery battery = circuit.addBattery("Batterie", 0, 0, Orientation.R2, VOLTAGE); @@ -30,18 +28,15 @@ public class DemoAll { circuit.connect(switcherX.getOutput1(), switcher1.getOutput0()); circuit.connect(switcher1.getCommon(), light.getPin1()); - circuit.evaluate(); return circuit; } public static Circuit simpleAlternative() { - final double voltage = 3.0; - final Circuit circuit = new Circuit(); - final PartBattery battery = circuit.addBattery("Batterie", 2, 0, Orientation.R1, voltage); - final PartLight light0 = circuit.addLight("Licht 0", 4, 2, Orientation.R1, voltage); - final PartLight light1 = circuit.addLight("Licht 1", 0, 2, Orientation.R1, voltage); + final PartBattery battery = circuit.addBattery("Batterie", 2, 0, Orientation.R1, VOLTAGE); + final PartLight light0 = circuit.addLight("Licht 0", 4, 2, Orientation.R1, VOLTAGE); + final PartLight light1 = circuit.addLight("Licht 1", 0, 2, Orientation.R1, VOLTAGE); final PartSwitch1x2 switcher0 = circuit.addSwitch1x2("Wechselschalter 0", 2, 2, Orientation.R1, false); circuit.connect(battery.getMinus(), light0.getPin0()); @@ -51,7 +46,6 @@ public class DemoAll { circuit.connect(switcher0.getOutput0(), light0.getPin1()); circuit.connect(switcher0.getOutput1(), light1.getPin1()); - circuit.evaluate(); return circuit; } diff --git a/src/main/java/de/ph87/electro/sidebar/Sidebar.java b/src/main/java/de/ph87/electro/sidebar/Sidebar.java index 5962b94..7ee2243 100644 --- a/src/main/java/de/ph87/electro/sidebar/Sidebar.java +++ b/src/main/java/de/ph87/electro/sidebar/Sidebar.java @@ -5,14 +5,10 @@ import de.ph87.electro.circuit.part.impl.*; import javax.swing.*; import java.awt.*; -import java.util.function.Consumer; public class Sidebar extends JPanel { - private final Consumer onAdd; - - public Sidebar(final Consumer onAdd) { - this.onAdd = onAdd; + public Sidebar() { setLayout(new FlowLayout()); add(new PartBattery(new Point(0, 0))); add(new PartLight(new Point(0, 0))); @@ -22,7 +18,7 @@ public class Sidebar extends JPanel { } private void add(final Part part) { - final SidebarPart entry = new SidebarPart(part, onAdd); + final SidebarPart entry = new SidebarPart(part); add(entry); } diff --git a/src/main/java/de/ph87/electro/sidebar/SidebarPart.java b/src/main/java/de/ph87/electro/sidebar/SidebarPart.java index 1a01c8c..3138aaa 100644 --- a/src/main/java/de/ph87/electro/sidebar/SidebarPart.java +++ b/src/main/java/de/ph87/electro/sidebar/SidebarPart.java @@ -9,7 +9,6 @@ import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragSource; -import java.util.function.Consumer; import static de.ph87.electro.CONFIG.RASTER; @@ -19,11 +18,8 @@ public class SidebarPart extends JPanel { private final Part part; - private final Consumer add; - - public SidebarPart(final Part part, final Consumer add) { + public SidebarPart(final Part part) { this.part = part; - this.add = add; setTransferHandler(new TransferHandler("text")); setPreferredSize(new Dimension(RASTER, RASTER)); createDragSource(part);