From 4d29cabdc45d68b5e5f210266dc4fbc5560dbcdd Mon Sep 17 00:00:00 2001 From: Daniel Kirschten Date: Tue, 28 May 2019 11:22:37 +0200 Subject: [PATCH] Started restructuring LogicUI --- .../GUIManualSwitch.java | 7 +- .../gui/components => oldsrc}/GUIMerger.java | 7 +- .../mi/gui/components => oldsrc}/GUIMux.java | 7 +- .../components => oldsrc}/GUISplitter.java | 16 +--- .../RSLatchGUIExample.java | 6 +- LogicUI/src/era/mi/gui/LogicUICanvas.java | 46 +++++----- LogicUI/src/era/mi/gui/LogicUIStandalone.java | 65 +++++++------- .../mi/gui/components/BasicGUIComponent.java | 44 ---------- .../src/era/mi/gui/components/GUIAndGate.java | 85 ------------------- .../src/era/mi/gui/components/GUINotGate.java | 76 ----------------- .../src/era/mi/gui/components/GUIOrGate.java | 85 ------------------- .../src/era/mi/gui/examples/Playground.java | 32 +++++++ LogicUI/src/era/mi/gui/model/ViewModel.java | 66 ++++++++++++++ .../mi/gui/model/components/GUIAndGate.java | 12 +++ .../mi/gui/model/components/GUIComponent.java | 78 +++++++++++++++++ .../mi/gui/model/components/GUINotGate.java | 12 +++ .../mi/gui/model/components/GUIOrGate.java | 12 +++ .../components/RectangularShapedGUIGate.java | 74 ++++++++++++++++ .../src/era/mi/gui/model/wires/GUIWire.java | 75 ++++++++++++++++ .../era/mi/gui/model/wires/MovablePin.java | 17 ++++ LogicUI/src/era/mi/gui/model/wires/Pin.java | 46 ++++++++++ .../mi/gui/model/wires/WireCrossPoint.java | 35 ++++++++ .../modeladapter/ViewLogicModelAdapter.java | 6 ++ LogicUI/src/era/mi/gui/wires/GUIWire.java | 67 --------------- .../era/mi/gui/wires/WireConnectionPoint.java | 65 -------------- SWTHelper | 2 +- 26 files changed, 540 insertions(+), 503 deletions(-) rename LogicUI/{src/era/mi/gui/components => oldsrc}/GUIManualSwitch.java (92%) rename LogicUI/{src/era/mi/gui/components => oldsrc}/GUIMerger.java (90%) rename LogicUI/{src/era/mi/gui/components => oldsrc}/GUIMux.java (89%) rename LogicUI/{src/era/mi/gui/components => oldsrc}/GUISplitter.java (77%) rename LogicUI/{src/era/mi/gui/examples => oldsrc}/RSLatchGUIExample.java (87%) delete mode 100644 LogicUI/src/era/mi/gui/components/BasicGUIComponent.java delete mode 100644 LogicUI/src/era/mi/gui/components/GUIAndGate.java delete mode 100644 LogicUI/src/era/mi/gui/components/GUINotGate.java delete mode 100644 LogicUI/src/era/mi/gui/components/GUIOrGate.java create mode 100644 LogicUI/src/era/mi/gui/examples/Playground.java create mode 100644 LogicUI/src/era/mi/gui/model/ViewModel.java create mode 100644 LogicUI/src/era/mi/gui/model/components/GUIAndGate.java create mode 100644 LogicUI/src/era/mi/gui/model/components/GUIComponent.java create mode 100644 LogicUI/src/era/mi/gui/model/components/GUINotGate.java create mode 100644 LogicUI/src/era/mi/gui/model/components/GUIOrGate.java create mode 100644 LogicUI/src/era/mi/gui/model/components/RectangularShapedGUIGate.java create mode 100644 LogicUI/src/era/mi/gui/model/wires/GUIWire.java create mode 100644 LogicUI/src/era/mi/gui/model/wires/MovablePin.java create mode 100644 LogicUI/src/era/mi/gui/model/wires/Pin.java create mode 100644 LogicUI/src/era/mi/gui/model/wires/WireCrossPoint.java create mode 100644 LogicUI/src/era/mi/gui/modeladapter/ViewLogicModelAdapter.java delete mode 100644 LogicUI/src/era/mi/gui/wires/GUIWire.java delete mode 100644 LogicUI/src/era/mi/gui/wires/WireConnectionPoint.java diff --git a/LogicUI/src/era/mi/gui/components/GUIManualSwitch.java b/LogicUI/oldsrc/GUIManualSwitch.java similarity index 92% rename from LogicUI/src/era/mi/gui/components/GUIManualSwitch.java rename to LogicUI/oldsrc/GUIManualSwitch.java index 7dcb025f..318c3f09 100644 --- a/LogicUI/src/era/mi/gui/components/GUIManualSwitch.java +++ b/LogicUI/oldsrc/GUIManualSwitch.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Map; import era.mi.logic.components.ManualSwitch; -import era.mi.logic.timeline.Timeline; import era.mi.logic.types.Bit; import era.mi.logic.wires.Wire.ReadEnd; import era.mi.logic.wires.Wire.ReadWriteEnd; @@ -16,7 +15,7 @@ import net.haspamelodica.swt.helper.swtobjectwrappers.Font; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; -public class GUIManualSwitch extends ManualSwitch implements BasicGUIComponent +public class GUIManualSwitch extends ManualSwitch implements GUIComponent { private static final Map bitNames; static @@ -34,9 +33,9 @@ public class GUIManualSwitch extends ManualSwitch implements BasicGUIComponent private final List connectedWireEnds; private final List wireEndConnectionPoints; - public GUIManualSwitch(Timeline timeline, ReadWriteEnd output) + public GUIManualSwitch(ReadWriteEnd output) { - super(timeline, output); + super(output); this.we = output; diff --git a/LogicUI/src/era/mi/gui/components/GUIMerger.java b/LogicUI/oldsrc/GUIMerger.java similarity index 90% rename from LogicUI/src/era/mi/gui/components/GUIMerger.java rename to LogicUI/oldsrc/GUIMerger.java index 240855c3..64fd0aa9 100644 --- a/LogicUI/src/era/mi/gui/components/GUIMerger.java +++ b/LogicUI/oldsrc/GUIMerger.java @@ -6,23 +6,22 @@ import java.util.Collections; import java.util.List; import era.mi.logic.components.Merger; -import era.mi.logic.timeline.Timeline; import era.mi.logic.wires.Wire.ReadEnd; import era.mi.logic.wires.Wire.ReadWriteEnd; import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; -public class GUIMerger extends Merger implements BasicGUIComponent +public class GUIMerger extends Merger implements GUIComponent { private final int inputCount; private final double height; private final List connectedWireEnds; private final List WireEndConnectionPoints; - public GUIMerger(Timeline timeline, ReadWriteEnd union, ReadEnd... inputs) + public GUIMerger(ReadWriteEnd union, ReadEnd... inputs) { - super(timeline, union, inputs); + super(union, inputs); List connectedWireEndsModifiable = new ArrayList<>(); List WireEndConnectionPointsModifiable = new ArrayList<>(); diff --git a/LogicUI/src/era/mi/gui/components/GUIMux.java b/LogicUI/oldsrc/GUIMux.java similarity index 89% rename from LogicUI/src/era/mi/gui/components/GUIMux.java rename to LogicUI/oldsrc/GUIMux.java index 0eba8f55..d004d90f 100644 --- a/LogicUI/src/era/mi/gui/components/GUIMux.java +++ b/LogicUI/oldsrc/GUIMux.java @@ -6,22 +6,21 @@ import java.util.Collections; import java.util.List; import era.mi.logic.components.Mux; -import era.mi.logic.timeline.Timeline; import era.mi.logic.wires.Wire.ReadEnd; import era.mi.logic.wires.Wire.ReadWriteEnd; import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; -public class GUIMux extends Mux implements BasicGUIComponent +public class GUIMux extends Mux implements GUIComponent { private final double height; private final List connectedWireEnds; private final List WireEndConnectionPoints; - public GUIMux(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd select, ReadEnd... inputs) + public GUIMux(int processTime, ReadWriteEnd out, ReadEnd select, ReadEnd... inputs) { - super(timeline, processTime, out, select, inputs); + super(processTime, out, select, inputs); double height = inputs.length * 5; if (height < 10) diff --git a/LogicUI/src/era/mi/gui/components/GUISplitter.java b/LogicUI/oldsrc/GUISplitter.java similarity index 77% rename from LogicUI/src/era/mi/gui/components/GUISplitter.java rename to LogicUI/oldsrc/GUISplitter.java index 6873e637..1bff4247 100644 --- a/LogicUI/src/era/mi/gui/components/GUISplitter.java +++ b/LogicUI/oldsrc/GUISplitter.java @@ -5,27 +5,19 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import era.mi.gui.ViewModel; import era.mi.logic.components.Splitter; -import era.mi.logic.timeline.Timeline; import era.mi.logic.wires.Wire.ReadEnd; import era.mi.logic.wires.Wire.ReadWriteEnd; import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; -public class GUISplitter extends Splitter implements BasicGUIComponent +public class GUISplitter extends GUIComponent { - private final int outputCount; - private final double height; - private final List connectedWireEnds; - private final List WireEndConnectionPoints; - - public GUISplitter(Timeline timeline, ReadEnd input, ReadWriteEnd... outputs) + public GUISplitter(ViewModel model) { - super(timeline, input, outputs); - - List connectedWireEndsModifiable = new ArrayList<>(); - List WireEndConnectionPointsModifiable = new ArrayList<>(); + super(model); this.outputCount = outputs.length; this.height = (outputCount - 1) * 10; diff --git a/LogicUI/src/era/mi/gui/examples/RSLatchGUIExample.java b/LogicUI/oldsrc/RSLatchGUIExample.java similarity index 87% rename from LogicUI/src/era/mi/gui/examples/RSLatchGUIExample.java rename to LogicUI/oldsrc/RSLatchGUIExample.java index dc6091f6..0fb1886a 100644 --- a/LogicUI/src/era/mi/gui/examples/RSLatchGUIExample.java +++ b/LogicUI/oldsrc/RSLatchGUIExample.java @@ -4,7 +4,7 @@ import era.mi.gui.LogicUICanvas; import era.mi.gui.LogicUIStandalone; import era.mi.gui.components.GUIManualSwitch; import era.mi.gui.components.GUINotGate; -import era.mi.gui.components.GUIOrGate; +import era.mi.gui.components.GUIOrGateOld; import era.mi.gui.wires.WireConnectionPoint; import era.mi.logic.timeline.Timeline; import era.mi.logic.wires.Wire; @@ -35,9 +35,9 @@ public class RSLatchGUIExample GUIManualSwitch rIn = ui.addComponent(new GUIManualSwitch(t, r.createReadWriteEnd()), 100, 100); GUIManualSwitch sIn = ui.addComponent(new GUIManualSwitch(t, s.createReadWriteEnd()), 100, 200); - GUIOrGate or1 = ui.addComponent(new GUIOrGate(t, OR_DELAY, t1.createReadWriteEnd(), r.createReadOnlyEnd(), nq.createReadOnlyEnd()), + GUIOrGateOld or1 = ui.addComponent(new GUIOrGateOld(t, OR_DELAY, t1.createReadWriteEnd(), r.createReadOnlyEnd(), nq.createReadOnlyEnd()), 160, 102.5); - GUIOrGate or2 = ui.addComponent(new GUIOrGate(t, OR_DELAY, t2.createReadWriteEnd(), q.createReadOnlyEnd(), s.createReadOnlyEnd()), + GUIOrGateOld or2 = ui.addComponent(new GUIOrGateOld(t, OR_DELAY, t2.createReadWriteEnd(), q.createReadOnlyEnd(), s.createReadOnlyEnd()), 160, 192.5); GUINotGate not1 = ui.addComponent(new GUINotGate(t, NOT_DELAY, t1.createReadOnlyEnd(), q.createReadWriteEnd()), 200, 107.5); GUINotGate not2 = ui.addComponent(new GUINotGate(t, NOT_DELAY, t2.createReadOnlyEnd(), nq.createReadWriteEnd()), 200, 197.5); diff --git a/LogicUI/src/era/mi/gui/LogicUICanvas.java b/LogicUI/src/era/mi/gui/LogicUICanvas.java index fd6d4daa..4e619884 100644 --- a/LogicUI/src/era/mi/gui/LogicUICanvas.java +++ b/LogicUI/src/era/mi/gui/LogicUICanvas.java @@ -1,19 +1,18 @@ package era.mi.gui; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; -import era.mi.gui.components.BasicGUIComponent; -import era.mi.gui.wires.GUIWire; +import era.mi.gui.model.components.GUIComponent; +import era.mi.gui.model.wires.GUIWire; +import era.mi.gui.model.wires.Pin; import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.gcs.TranslatedGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas; /** @@ -23,8 +22,7 @@ import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas; */ public class LogicUICanvas extends ZoomableCanvas { - private final Set components; - private final Map componentPositions; + private final Set components; private final Set wires; public LogicUICanvas(Composite parent, int style) @@ -32,10 +30,13 @@ public class LogicUICanvas extends ZoomableCanvas super(parent, style); components = new HashSet<>(); - componentPositions = new HashMap<>(); wires = new HashSet<>(); - addZoomedRenderer(gc -> components.forEach(c -> drawComponent(gc, c))); + addZoomedRenderer(gc -> + { + Rectangle visibleRegion = new Rectangle(offX, offY, gW / zoom, gH / zoom); + components.forEach(c -> drawComponent(gc, c, visibleRegion)); + }); addZoomedRenderer(gc -> wires.forEach(w -> w.render(gc))); addListener(SWT.MouseDown, this::mouseDown); } @@ -45,10 +46,10 @@ public class LogicUICanvas extends ZoomableCanvas * * @author Daniel Kirschten */ - public C addComponent(C component, double x, double y) + // TODO replace with model change listener + public C addComponent(C component) { components.add(component); - componentPositions.put(component, new Point(x, y)); return component; } @@ -58,18 +59,21 @@ public class LogicUICanvas extends ZoomableCanvas * * @author Daniel Kirschten */ - public void addWire(BasicGUIComponent component1, int component1ConnectionIndex, BasicGUIComponent component2, - int component2ConnectionIndex, Point... path) + // TODO replace with model change listener + public void addWire(Pin pin1, Pin pin2, Point... path) { - wires.add(new GUIWire(this::redrawThreadsafe, component1, component1ConnectionIndex, componentPositions.get(component1), component2, - component2ConnectionIndex, componentPositions.get(component2), path)); + wires.add(new GUIWire(this::redrawThreadsafe, pin1, pin2, path)); } - private void drawComponent(GeneralGC gc, BasicGUIComponent component) + private void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion) { - TranslatedGC tgc = new TranslatedGC(gc, componentPositions.get(component)); - component.render(tgc); - tgc.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLUE)); + component.render(gc, visibleRegion); + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_CYAN)); + for (Pin p : component.getPins()) + { + Point pos = p.getPos(); + gc.fillOval(pos.x - 1, pos.y - 1, 2, 2); + } } private void mouseDown(Event e) @@ -77,8 +81,8 @@ public class LogicUICanvas extends ZoomableCanvas if (e.button == 1) { Point click = displayToWorldCoords(e.x, e.y); - for (BasicGUIComponent component : components) - if (component.getBounds().translate(componentPositions.get(component)).contains(click)) + for (GUIComponent component : components) + if (component.getBounds().contains(click)) { if (component.clicked(click.x, click.y)) redraw(); diff --git a/LogicUI/src/era/mi/gui/LogicUIStandalone.java b/LogicUI/src/era/mi/gui/LogicUIStandalone.java index 3b3c740f..0bc5d8a7 100644 --- a/LogicUI/src/era/mi/gui/LogicUIStandalone.java +++ b/LogicUI/src/era/mi/gui/LogicUIStandalone.java @@ -7,7 +7,7 @@ import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -import era.mi.logic.timeline.Timeline; +import era.mi.gui.model.ViewModel; import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay; import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput; @@ -18,14 +18,15 @@ import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInpu */ public class LogicUIStandalone { + private ViewModel model; + private final Display display; private final Shell shell; private final LogicUICanvas ui; - private Timeline timeline; - public LogicUIStandalone(Timeline timeline) + public LogicUIStandalone(ViewModel model) { - this.timeline = timeline; + this.model = model; display = new Display(); shell = new Shell(display); shell.setLayout(new FillLayout()); @@ -49,39 +50,39 @@ public class LogicUIStandalone public void run() { AtomicBoolean running = new AtomicBoolean(true); - Thread simulationThread = new Thread(() -> - { - while (running.get()) - { - // always execute to keep timeline from "hanging behind" for too long - timeline.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10); - long sleepTime; - if (timeline.hasNext()) - sleepTime = timeline.nextEventTime() - System.currentTimeMillis(); - else - sleepTime = 10; - try - { - if (sleepTime > 0) - Thread.sleep(sleepTime); - } - catch (InterruptedException e) - { - } // it is normal execution flow to be interrupted - } - }); - simulationThread.start(); - timeline.addEventAddedListener(event -> - { - if (event.getTiming() <= System.currentTimeMillis()) - simulationThread.interrupt(); - }); +// Thread simulationThread = new Thread(() -> +// { +// while (running.get()) +// { +// // always execute to keep timeline from "hanging behind" for too long +// model.timeline.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10); +// long sleepTime; +// if (model.timeline.hasNext()) +// sleepTime = model.timeline.nextEventTime() - System.currentTimeMillis(); +// else +// sleepTime = 10; +// try +// { +// if (sleepTime > 0) +// Thread.sleep(sleepTime); +// } +// catch (InterruptedException e) +// { +// } // it is normal execution flow to be interrupted +// } +// }); +// simulationThread.start(); +// model.timeline.addEventAddedListener(event -> +// { +// if (event.getTiming() <= System.currentTimeMillis()) +// simulationThread.interrupt(); +// }); shell.open(); while (!shell.isDisposed()) if (!display.readAndDispatch()) display.sleep(); running.set(false); - simulationThread.interrupt(); +// simulationThread.interrupt(); } } \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/BasicGUIComponent.java b/LogicUI/src/era/mi/gui/components/BasicGUIComponent.java deleted file mode 100644 index 2d27685b..00000000 --- a/LogicUI/src/era/mi/gui/components/BasicGUIComponent.java +++ /dev/null @@ -1,44 +0,0 @@ -package era.mi.gui.components; - -import era.mi.logic.wires.Wire.ReadEnd; -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; - -public interface BasicGUIComponent -{ - /** - * Render this component to the given gc, at coordinates (0, 0). - */ - public void render(GeneralGC gc); - - /** - * Returns the bounds of this component. Used for calculating which component is clicked. - */ - public Rectangle getBounds(); - - /** - * Called when this component is clicked. Relative coordinates of the click are given. Returns true if this component has to be redrawn. - */ - public default boolean clicked(double x, double y) - { - return false; - } - - // TODO this code will be replaced by code in BasicComponent. - /** - * Returns how many wire arrays are connected to this component. (Connections are static - they can't be removed and no new ones can be - * added) - */ - public int getConnectedWireEndsCount(); - - /** - * Returns the n-th wire array connected to this component. - */ - public ReadEnd getConnectedWireEnd(int connectionIndex); - - /** - * Returns relative coordinates where the n-th wire array is connected to this component. - */ - public Point getWireEndConnectionPoint(int connectionIndex); -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/GUIAndGate.java b/LogicUI/src/era/mi/gui/components/GUIAndGate.java deleted file mode 100644 index c76d65a0..00000000 --- a/LogicUI/src/era/mi/gui/components/GUIAndGate.java +++ /dev/null @@ -1,85 +0,0 @@ -package era.mi.gui.components; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.gates.AndGate; -import era.mi.logic.timeline.Timeline; -import era.mi.logic.wires.Wire.ReadEnd; -import era.mi.logic.wires.Wire.ReadWriteEnd; -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Font; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; - -public class GUIAndGate extends AndGate implements BasicGUIComponent -{ - private static final String LABEL = "&"; - - private final int inputCount; - private final double height; - private final List connectedWireEnds; - private final List wireEndConnectionPoints; - - public GUIAndGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in) - { - super(timeline, processTime, out, in); - - List connectedWireEndsModifiable = new ArrayList<>(); - List wireEndConnectionPointsModifiable = new ArrayList<>(); - - this.inputCount = in.length; - this.height = inputCount * 10; - - { - connectedWireEndsModifiable.addAll(Arrays.asList(in)); - double inputHeight = 5; - for (int i = 0; i < inputCount; i++, inputHeight += 10) - wireEndConnectionPointsModifiable.add(new Point(0, inputHeight)); - } - - connectedWireEndsModifiable.add(out); - wireEndConnectionPointsModifiable.add(new Point(20, height / 2)); - - this.connectedWireEnds = Collections.unmodifiableList(connectedWireEndsModifiable); - this.wireEndConnectionPoints = Collections.unmodifiableList(wireEndConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, height); - } - - @Override - public void render(GeneralGC gc) - { - gc.drawRectangle(0, 0, 20, height); - Font oldFont = gc.getFont(); - Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle()); - gc.setFont(labelFont); - Point textExtent = gc.textExtent(LABEL); - gc.drawText(LABEL, 10 - textExtent.x / 2, (height - textExtent.y) / 2, true); - gc.setFont(oldFont); - } - - @Override - public int getConnectedWireEndsCount() - { - return connectedWireEnds.size(); - } - - @Override - public ReadEnd getConnectedWireEnd(int connectionIndex) - { - return connectedWireEnds.get(connectionIndex); - } - - @Override - public Point getWireEndConnectionPoint(int connectionI) - { - return wireEndConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/GUINotGate.java b/LogicUI/src/era/mi/gui/components/GUINotGate.java deleted file mode 100644 index fa4730a1..00000000 --- a/LogicUI/src/era/mi/gui/components/GUINotGate.java +++ /dev/null @@ -1,76 +0,0 @@ -package era.mi.gui.components; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.gates.NotGate; -import era.mi.logic.timeline.Timeline; -import era.mi.logic.wires.Wire.ReadEnd; -import era.mi.logic.wires.Wire.ReadWriteEnd; -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Font; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; - -public class GUINotGate extends NotGate implements BasicGUIComponent -{ - private static final String LABEL = "\u22651";// >=1 - - private final List connectedWireEnds; - private final List WireEndConnectionPoints; - - public GUINotGate(Timeline timeline, int processTime, ReadEnd in, ReadWriteEnd out) - { - super(timeline, processTime, in, out); - - List connectedWireEndsModifiable = new ArrayList<>(); - List WireEndConnectionPointsModifiable = new ArrayList<>(); - - connectedWireEndsModifiable.add(in); - WireEndConnectionPointsModifiable.add(new Point(0, 5)); - - connectedWireEndsModifiable.add(out); - WireEndConnectionPointsModifiable.add(new Point(20, 5)); - - this.connectedWireEnds = Collections.unmodifiableList(connectedWireEndsModifiable); - this.WireEndConnectionPoints = Collections.unmodifiableList(WireEndConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, 10); - } - - @Override - public void render(GeneralGC gc) - { - gc.drawRectangle(0, 0, 17, 10); - Font oldFont = gc.getFont(); - Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle()); - gc.setFont(labelFont); - Point textExtent = gc.textExtent(LABEL); - gc.drawText(LABEL, 8.5 - textExtent.x / 2, 5 - textExtent.y / 2, true); - gc.setFont(oldFont); - gc.drawOval(17, 3.5, 3, 3); - } - - @Override - public int getConnectedWireEndsCount() - { - return connectedWireEnds.size(); - } - - @Override - public ReadEnd getConnectedWireEnd(int connectionIndex) - { - return connectedWireEnds.get(connectionIndex); - } - - @Override - public Point getWireEndConnectionPoint(int connectionI) - { - return WireEndConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/GUIOrGate.java b/LogicUI/src/era/mi/gui/components/GUIOrGate.java deleted file mode 100644 index 549cb402..00000000 --- a/LogicUI/src/era/mi/gui/components/GUIOrGate.java +++ /dev/null @@ -1,85 +0,0 @@ -package era.mi.gui.components; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.gates.OrGate; -import era.mi.logic.timeline.Timeline; -import era.mi.logic.wires.Wire.ReadEnd; -import era.mi.logic.wires.Wire.ReadWriteEnd; -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Font; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; - -public class GUIOrGate extends OrGate implements BasicGUIComponent -{ - private static final String LABEL = "\u22651";// >=1 - - private final int inputCount; - private final double height; - private final List connectedWireEnds; - private final List WireEndConnectionPoints; - - public GUIOrGate(Timeline timeline, int processTime, ReadWriteEnd out, ReadEnd... in) - { - super(timeline, processTime, out, in); - - List connectedWireEndsModifiable = new ArrayList<>(); - List WireEndConnectionPointsModifiable = new ArrayList<>(); - - this.inputCount = in.length; - this.height = inputCount * 10; - - { - connectedWireEndsModifiable.addAll(Arrays.asList(in)); - double inputHeight = 5; - for (int i = 0; i < inputCount; i++, inputHeight += 10) - WireEndConnectionPointsModifiable.add(new Point(0, inputHeight)); - } - - connectedWireEndsModifiable.add(out); - WireEndConnectionPointsModifiable.add(new Point(20, height / 2)); - - this.connectedWireEnds = Collections.unmodifiableList(connectedWireEndsModifiable); - this.WireEndConnectionPoints = Collections.unmodifiableList(WireEndConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, height); - } - - @Override - public void render(GeneralGC gc) - { - gc.drawRectangle(0, 0, 20, height); - Font oldFont = gc.getFont(); - Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle()); - gc.setFont(labelFont); - Point textExtent = gc.textExtent(LABEL); - gc.drawText(LABEL, 10 - textExtent.x / 2, (height - textExtent.y) / 2, true); - gc.setFont(oldFont); - } - - @Override - public int getConnectedWireEndsCount() - { - return connectedWireEnds.size(); - } - - @Override - public ReadEnd getConnectedWireEnd(int connectionIndex) - { - return connectedWireEnds.get(connectionIndex); - } - - @Override - public Point getWireEndConnectionPoint(int connectionI) - { - return WireEndConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/examples/Playground.java b/LogicUI/src/era/mi/gui/examples/Playground.java new file mode 100644 index 00000000..eafa1a58 --- /dev/null +++ b/LogicUI/src/era/mi/gui/examples/Playground.java @@ -0,0 +1,32 @@ +package era.mi.gui.examples; + +import era.mi.gui.LogicUICanvas; +import era.mi.gui.LogicUIStandalone; +import era.mi.gui.model.ViewModel; +import era.mi.gui.model.components.GUIAndGate; +import era.mi.gui.model.components.GUINotGate; + +public class Playground +{ + private static final int WIRE_DELAY = 10; + private static final int OR_DELAY = 50; + private static final int NOT_DELAY = 50; + + public static void main(String[] args) + { + ViewModel model = new ViewModel(); + LogicUIStandalone ui = new LogicUIStandalone(model); + addComponentsAndWires(ui.getLogicUICanvas(), model); + ui.run(); + } + + public static void addComponentsAndWires(LogicUICanvas ui, ViewModel model) + { + GUIAndGate andGate = ui.addComponent(new GUIAndGate(model)); + andGate.moveTo(10, 10); + GUINotGate notGate = ui.addComponent(new GUINotGate(model)); + notGate.moveTo(10, 40); + + ui.addWire(andGate.getPins().get(0), notGate.getPins().get(1)); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/ViewModel.java b/LogicUI/src/era/mi/gui/model/ViewModel.java new file mode 100644 index 00000000..de22f447 --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/ViewModel.java @@ -0,0 +1,66 @@ +package era.mi.gui.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import era.mi.gui.model.components.GUIComponent; +import era.mi.gui.model.wires.GUIWire; + +public class ViewModel +{ + private final List components; + private final List wires; + + private final List> componentAddedListeners; + private final List> componentRemovedListeners; + private final List> wireAddedListeners; + private final List> wireRemovedListeners; + + public ViewModel() + { + components = new ArrayList<>(); + wires = new ArrayList<>(); + + componentAddedListeners = new ArrayList<>(); + componentRemovedListeners = new ArrayList<>(); + wireAddedListeners = new ArrayList<>(); + wireRemovedListeners = new ArrayList<>(); + } + + /** + * Adds the given component to the list of components and calls all componentAddedListeners. Don't call this method from application + * code as it is automatically called in GUIComponent::new. + */ + public void addComponent(GUIComponent component) + { + if (components.contains(component)) + throw new IllegalStateException("Don't add the same component twice!"); + components.add(component); + componentAddedListeners.forEach(l -> l.accept(component)); + } + + /** + * Removes the given component from the list of components and calls all componentRemovedListeners. Don't call this method from + * application code as it is automatically called in GUIComponent::destroy. + */ + public void removeComponent(GUIComponent component) + { + if (!components.contains(component)) + throw new IllegalStateException("Don't remove the same component twice!"); + components.remove(component); + componentRemovedListeners.forEach(l -> l.accept(component)); + } + + // @formatter:off + public void addComponentAddedListener (Consumer listener){componentAddedListeners .add (listener);} + public void addComponentRemovedListener (Consumer listener){componentRemovedListeners.add (listener);} + public void addWireAddedListener (Consumer listener){wireAddedListeners .add (listener);} + public void addWireRemovedListener (Consumer listener){wireRemovedListeners .add (listener);} + + public void removeComponentAddedListener (Consumer listener){componentAddedListeners .remove(listener);} + public void removeComponentRemovedListener(Consumer listener){componentRemovedListeners.remove(listener);} + public void removeWireAddedListener (Consumer listener){wireAddedListeners .remove(listener);} + public void removeWireRemovedListener (Consumer listener){wireRemovedListeners .remove(listener);} + // @formatter:on +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/components/GUIAndGate.java b/LogicUI/src/era/mi/gui/model/components/GUIAndGate.java new file mode 100644 index 00000000..4f69d36d --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/components/GUIAndGate.java @@ -0,0 +1,12 @@ +package era.mi.gui.model.components; + +import era.mi.gui.model.ViewModel; + +public class GUIAndGate extends RectangularShapedGUIGate +{ + public GUIAndGate(ViewModel model) + { + super(model, "&", false); + setInputCount(2); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/components/GUIComponent.java b/LogicUI/src/era/mi/gui/model/components/GUIComponent.java new file mode 100644 index 00000000..75a7a53f --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/components/GUIComponent.java @@ -0,0 +1,78 @@ +package era.mi.gui.model.components; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import era.mi.gui.model.ViewModel; +import era.mi.gui.model.wires.Pin; +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; + +public abstract class GUIComponent +{ + protected final ViewModel model; + private final Rectangle bounds; + private final List pins; + protected final List pinsUnmodifiable; + + public GUIComponent(ViewModel model) + { + this.model = model; + this.bounds = new Rectangle(0, 0, 0, 0); + this.pins = new ArrayList<>(); + this.pinsUnmodifiable = Collections.unmodifiableList(pins); + } + + public void moveTo(double x, double y) + { + bounds.x = x; + bounds.y = y; + } + + /** + * Returns the bounds of this component. Used for calculating which component is clicked. + */ + public Rectangle getBounds() + { + return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); + } + + // TODO + /** + * Called when this component is clicked. Relative coordinates of the click are given. Returns true if this component has to be redrawn. + */ + public boolean clicked(double x, double y) + { + return false; + } + + /** + * Returns a list of pins of this component. + */ + public List getPins() + { + return pinsUnmodifiable; + } + + /** + * Render this component to the given gc. + */ + public abstract void render(GeneralGC gc, Rectangle visibleRegion); + + protected void setSize(double width, double height) + { + bounds.width = width; + bounds.height = height; + } + + protected void addPin(Pin pin) + {// TODO notify pins they are "created" + pins.add(pin); + } + + protected void removePin(Pin pin) + {// TODO notify pins they are "destroyed" + pins.remove(pin); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/components/GUINotGate.java b/LogicUI/src/era/mi/gui/model/components/GUINotGate.java new file mode 100644 index 00000000..5f41592b --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/components/GUINotGate.java @@ -0,0 +1,12 @@ +package era.mi.gui.model.components; + +import era.mi.gui.model.ViewModel; + +public class GUINotGate extends RectangularShapedGUIGate +{ + public GUINotGate(ViewModel model) + { + super(model, "1", true); + setInputCount(1); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/components/GUIOrGate.java b/LogicUI/src/era/mi/gui/model/components/GUIOrGate.java new file mode 100644 index 00000000..df64bba1 --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/components/GUIOrGate.java @@ -0,0 +1,12 @@ +package era.mi.gui.model.components; + +import era.mi.gui.model.ViewModel; + +public class GUIOrGate extends RectangularShapedGUIGate +{ + public GUIOrGate(ViewModel model) + { + super(model, "\u22651", false);// ">=1" + setInputCount(2); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/components/RectangularShapedGUIGate.java b/LogicUI/src/era/mi/gui/model/components/RectangularShapedGUIGate.java new file mode 100644 index 00000000..c7d0b346 --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/components/RectangularShapedGUIGate.java @@ -0,0 +1,74 @@ +package era.mi.gui.model.components; + +import java.util.ArrayList; +import java.util.List; + +import era.mi.gui.model.ViewModel; +import era.mi.gui.model.wires.MovablePin; +import era.mi.gui.model.wires.Pin; +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Font; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; + +public class RectangularShapedGUIGate extends GUIComponent +{ + private static final double width = 20; + private static final double pinDistance = 10; + private static final double fontHeight = 5; + private static final double invertedCircleDiam = 3.5; + + private final String label; + private final boolean isInverted; + private final double rectWidth; + + private MovablePin outputPin; + private final List inputPins; + + protected RectangularShapedGUIGate(ViewModel model, String label, boolean isInverted) + { + super(model); + this.label = label; + this.isInverted = isInverted; + this.rectWidth = width - (isInverted ? invertedCircleDiam : 0); + this.outputPin = new MovablePin(this, width, 0); + addPin(outputPin); + this.inputPins = new ArrayList<>(); + setInputCount(1); + } + + protected void setInputCount(int inputCount) + { + int oldInputCount = inputPins.size(); + setSize(width, inputCount * pinDistance); + if (oldInputCount > inputCount) + while (inputPins.size() > inputCount) + removePin(inputPins.get(inputCount)); + else if (oldInputCount < inputCount) + for (int i = oldInputCount; i < inputCount; i++) + { + Pin pin = new Pin(this, 0, pinDistance / 2 + i * pinDistance); + inputPins.add(pin); + addPin(pin); + } + outputPin.setRelPos(width, inputCount * pinDistance / 2); + } + + @Override + public void render(GeneralGC gc, Rectangle visibleRegion) + { + double posX = getBounds().x; + double posY = getBounds().y; + + double height = inputPins.size() * pinDistance; + gc.drawRectangle(posX, posY, rectWidth, height); + Font oldFont = gc.getFont(); + Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle()); + gc.setFont(labelFont); + Point textExtent = gc.textExtent(label); + gc.drawText(label, posX + (rectWidth - textExtent.x) / 2, posY + (height - textExtent.y) / 2, true); + gc.setFont(oldFont); + if (isInverted) + gc.drawOval(posX + rectWidth, posY + (height - invertedCircleDiam) / 2, invertedCircleDiam, invertedCircleDiam); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/wires/GUIWire.java b/LogicUI/src/era/mi/gui/model/wires/GUIWire.java new file mode 100644 index 00000000..d0bd9908 --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/wires/GUIWire.java @@ -0,0 +1,75 @@ +package era.mi.gui.model.wires; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; + +import era.mi.logic.types.Bit; +import era.mi.logic.wires.Wire; +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; + +public class GUIWire +{ + private Pin pin1; + private Pin pin2; + private double[] path; + + private Wire wire; + + public GUIWire(Runnable redraw, Pin pin1, Pin pin2, Point... path) + { + this.path = new double[path.length * 2 + 4]; + for (int srcI = 0, dstI = 2; srcI < path.length; srcI++, dstI += 2) + { + this.path[dstI + 0] = path[srcI].x; + this.path[dstI + 1] = path[srcI].y; + } + // TODO support moving pins + Point pos; + pos = pin1.getPos(); + this.path[0] = pos.x; + this.path[1] = pos.y; + pos = pin2.getPos(); + this.path[this.path.length - 2] = pos.x; + this.path[this.path.length - 1] = pos.y; + } + + public void render(GeneralGC gc) + { + Color oldFG = gc.getForeground(); + gc.setForeground(gc.getDevice().getSystemColor(getSWTColorConstantForWire(wire))); + gc.drawPolyline(path); + gc.setForeground(oldFG); + } + + public void setLogicModelWire(Wire wire) + { + this.wire = wire; + } + + public static int getSWTColorConstantForWire(Wire wire) + { + if (wire != null && wire.length == 1) + return getSWTColorConstantForBit(wire.getValue()); + else + return SWT.COLOR_BLACK; + } + + public static int getSWTColorConstantForBit(Bit bit) + { + switch (bit) + { + case ONE: + return SWT.COLOR_GREEN; + case ZERO: + return SWT.COLOR_BLUE; + case Z: + return SWT.COLOR_BLACK; + case U: + case X: + return SWT.COLOR_RED; + default: + throw new IllegalArgumentException("Unknown enum constant: " + bit); + } + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/wires/MovablePin.java b/LogicUI/src/era/mi/gui/model/wires/MovablePin.java new file mode 100644 index 00000000..673b2578 --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/wires/MovablePin.java @@ -0,0 +1,17 @@ +package era.mi.gui.model.wires; + +import era.mi.gui.model.components.GUIComponent; + +public class MovablePin extends Pin +{ + public MovablePin(GUIComponent component, double relX, double relY) + { + super(component, relX, relY); + } + + @Override + public void setRelPos(double relX, double relY) + { + super.setRelPos(relX, relY); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/wires/Pin.java b/LogicUI/src/era/mi/gui/model/wires/Pin.java new file mode 100644 index 00000000..1ab74047 --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/wires/Pin.java @@ -0,0 +1,46 @@ +package era.mi.gui.model.wires; + +import era.mi.gui.model.components.GUIComponent; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; + +public class Pin +{ + public final GUIComponent component; + protected double relX; + protected double relY; + + public Pin(GUIComponent component, double relX, double relY) + { + this.component = component; + this.relX = relX; + this.relY = relY; + } + + public double getRelX() + { + return relX; + } + + public double getRelY() + { + return relY; + } + + public Point getRelPos() + { + return new Point(relX, relY); + } + + public Point getPos() + { + Rectangle componentBounds = component.getBounds(); + return new Point(relX + componentBounds.x, relY + componentBounds.y); + } + + protected void setRelPos(double relX, double relY) + { + this.relX = relX; + this.relY = relY; + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/model/wires/WireCrossPoint.java b/LogicUI/src/era/mi/gui/model/wires/WireCrossPoint.java new file mode 100644 index 00000000..84179fad --- /dev/null +++ b/LogicUI/src/era/mi/gui/model/wires/WireCrossPoint.java @@ -0,0 +1,35 @@ +package era.mi.gui.model.wires; + +import org.eclipse.swt.graphics.Color; + +import era.mi.gui.model.ViewModel; +import era.mi.gui.model.components.GUIComponent; +import era.mi.logic.wires.Wire; +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; + +public class WireCrossPoint extends GUIComponent +{ + private Wire wire; + + public WireCrossPoint(ViewModel model) + { + super(model); + setSize(0, 0); + addPin(new Pin(this, 0, 0)); + } + + @Override + public void render(GeneralGC gc, Rectangle visibleRegion) + { + Color oldBG = gc.getBackground(); + gc.setBackground(gc.getDevice().getSystemColor(GUIWire.getSWTColorConstantForWire(wire))); + gc.fillOval(-1, -1, 2, 2); + gc.setBackground(oldBG); + } + + public void setLogicModelWire(Wire wire) + { + this.wire = wire; + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/modeladapter/ViewLogicModelAdapter.java b/LogicUI/src/era/mi/gui/modeladapter/ViewLogicModelAdapter.java new file mode 100644 index 00000000..f005a80b --- /dev/null +++ b/LogicUI/src/era/mi/gui/modeladapter/ViewLogicModelAdapter.java @@ -0,0 +1,6 @@ +package era.mi.gui.modeladapter; + +public class ViewLogicModelAdapter +{ + +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/wires/GUIWire.java b/LogicUI/src/era/mi/gui/wires/GUIWire.java deleted file mode 100644 index 53e122a3..00000000 --- a/LogicUI/src/era/mi/gui/wires/GUIWire.java +++ /dev/null @@ -1,67 +0,0 @@ -package era.mi.gui.wires; - -import java.util.Objects; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; - -import era.mi.gui.components.BasicGUIComponent; -import era.mi.logic.types.Bit; -import era.mi.logic.wires.Wire; -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; - -public class GUIWire -{ - private final Wire wire; - private final double[] path; - - public GUIWire(Runnable redraw, BasicGUIComponent component1, int component1ConnectionIndex, Point component1Pos, - BasicGUIComponent component2, int component2ConnectionIndex, Point component2Pos, Point... path) - { - this.wire = component1.getConnectedWireEnd(component1ConnectionIndex).getWire(); - if (!Objects.equals(wire, component2.getConnectedWireEnd(component2ConnectionIndex).getWire())) - throw new IllegalArgumentException("Given connection points are not connected!"); - this.path = new double[path.length * 2 + 4]; - Point component1ConnectionPoint = component1.getWireEndConnectionPoint(component1ConnectionIndex); - this.path[0] = component1Pos.x + component1ConnectionPoint.x; - this.path[1] = component1Pos.y + component1ConnectionPoint.y; - for (int srcI = 0, dstI = 2; srcI < path.length; srcI++, dstI += 2) - { - this.path[dstI + 0] = path[srcI].x; - this.path[dstI + 1] = path[srcI].y; - } - Point component2ConnectionPoint = component2.getWireEndConnectionPoint(component2ConnectionIndex); - this.path[this.path.length - 2] = component2Pos.x + component2ConnectionPoint.x; - this.path[this.path.length - 1] = component2Pos.y + component2ConnectionPoint.y; - - wire.createReadOnlyEnd().addObserver((initiator, oldValues) -> redraw.run()); - } - - public void render(GeneralGC gc) - { - Color oldFG = gc.getForeground(); - if (wire.length == 1) - gc.setForeground(gc.getDevice().getSystemColor(getSWTColorConstantForBit(wire.getValue()))); - gc.drawPolyline(path); - gc.setForeground(oldFG); - } - - public static int getSWTColorConstantForBit(Bit bit) - { - switch (bit) - { - case ONE: - return SWT.COLOR_GREEN; - case ZERO: - return SWT.COLOR_BLUE; - case Z: - return SWT.COLOR_BLACK; - case U: - case X: - return SWT.COLOR_RED; - default: - throw new IllegalArgumentException("Unknown enum constant: " + bit); - } - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/wires/WireConnectionPoint.java b/LogicUI/src/era/mi/gui/wires/WireConnectionPoint.java deleted file mode 100644 index df82a733..00000000 --- a/LogicUI/src/era/mi/gui/wires/WireConnectionPoint.java +++ /dev/null @@ -1,65 +0,0 @@ -package era.mi.gui.wires; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.swt.graphics.Color; - -import era.mi.gui.components.BasicGUIComponent; -import era.mi.logic.wires.Wire; -import era.mi.logic.wires.Wire.ReadEnd; -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; - -public class WireConnectionPoint implements BasicGUIComponent -{ - private final Wire wire; - private final List wireEnds; - private final int wiresCrossing; - - public WireConnectionPoint(Wire wire, int wiresCrossing) - { - this.wire = wire; - List wireEndsModifiable = new ArrayList<>(); - for (int i = 0; i < wiresCrossing; i++) - wireEndsModifiable.add(wire.createReadOnlyEnd()); - wireEnds = Collections.unmodifiableList(wireEndsModifiable); - this.wiresCrossing = wiresCrossing; - } - - @Override - public void render(GeneralGC gc) - { - Color oldBG = gc.getBackground(); - if (wire.length == 1) - gc.setBackground(gc.getDevice().getSystemColor(GUIWire.getSWTColorConstantForBit(wire.getValue()))); - gc.fillOval(-1, -1, 2, 2); - gc.setBackground(oldBG); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 0, 0); - } - - @Override - public int getConnectedWireEndsCount() - { - return wiresCrossing; - } - - @Override - public ReadEnd getConnectedWireEnd(int connectionIndex) - { - return wireEnds.get(connectionIndex); - } - - @Override - public Point getWireEndConnectionPoint(int connectionIndex) - { - return new Point(0, 0); - } -} \ No newline at end of file diff --git a/SWTHelper b/SWTHelper index 6f9a55d4..1b4a52c0 160000 --- a/SWTHelper +++ b/SWTHelper @@ -1 +1 @@ -Subproject commit 6f9a55d483020bad4a5f66de375c3d0d6da585df +Subproject commit 1b4a52c0491e8d22fe6b2352a11d7d82f14c7074 -- 2.17.1