From: Daniel Kirschten Date: Thu, 16 May 2019 08:47:03 +0000 (+0200) Subject: Restructured packages X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=d3a382377768fdb1434d5baebf73c9413e61e46f;p=Mograsim.git Restructured packages --- diff --git a/LogicUI/src/era/mi/components/gui/BasicGUIComponent.java b/LogicUI/src/era/mi/components/gui/BasicGUIComponent.java deleted file mode 100644 index a7212f98..00000000 --- a/LogicUI/src/era/mi/components/gui/BasicGUIComponent.java +++ /dev/null @@ -1,42 +0,0 @@ -package era.mi.components.gui; - -import era.mi.logic.wires.WireArray; -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 getConnectedWireArraysCount(); - /** - * Returns the n-th wire array connected to this component. - */ - public WireArray getConnectedWireArray(int connectionIndex); - /** - * Returns relative coordinates where the n-th wire array is connected to this component. - */ - public Point getWireArrayConnectionPoint(int connectionIndex); -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/components/gui/GUIAndGate.java b/LogicUI/src/era/mi/components/gui/GUIAndGate.java deleted file mode 100644 index 93429e84..00000000 --- a/LogicUI/src/era/mi/components/gui/GUIAndGate.java +++ /dev/null @@ -1,81 +0,0 @@ -package era.mi.components.gui; - -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.wires.WireArray; -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 connectedWireArrays; - private final List wireArrayConnectionPoints; - - public GUIAndGate(int processTime, WireArray out, WireArray... in) - { - super(processTime, out, in); - - List connectedWireArraysModifiable = new ArrayList<>(); - List wireArrayConnectionPointsModifiable = new ArrayList<>(); - - this.inputCount = in.length; - this.height = inputCount * 10; - - { - connectedWireArraysModifiable.addAll(Arrays.asList(in)); - double inputHeight = 5; - for(int i = 0; i < inputCount; i ++, inputHeight += 10) - wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); - } - - connectedWireArraysModifiable.add(out); - wireArrayConnectionPointsModifiable.add(new Point(20, height / 2)); - - this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); - this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, height); - } - @Override - public void render(GeneralGC gc) - { - gc.drawRectangle(0, 0, 17, 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, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true); - gc.setFont(oldFont); - gc.drawOval(17, height / 2 - 1.5, 3, 3); - } - - @Override - public int getConnectedWireArraysCount() - { - return connectedWireArrays.size(); - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return connectedWireArrays.get(connectionIndex); - } - @Override - public Point getWireArrayConnectionPoint(int connectionI) - { - return wireArrayConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/components/gui/GUIManualSwitch.java b/LogicUI/src/era/mi/components/gui/GUIManualSwitch.java deleted file mode 100644 index b12177f7..00000000 --- a/LogicUI/src/era/mi/components/gui/GUIManualSwitch.java +++ /dev/null @@ -1,72 +0,0 @@ -package era.mi.components.gui; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.ManualSwitch; -import era.mi.logic.wires.WireArray; -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 GUIManualSwitch extends ManualSwitch implements BasicGUIComponent -{ - private final List connectedWireArrays; - private final List wireArrayConnectionPoints; - - public GUIManualSwitch(WireArray output) - { - super(output); - - List connectedWireArraysModifiable = new ArrayList<>(); - List wireArrayConnectionPointsModifiable = new ArrayList<>(); - - connectedWireArraysModifiable.add(output); - wireArrayConnectionPointsModifiable.add(new Point(20, 7.5)); - - this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); - this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, 15); - } - @Override - public void render(GeneralGC gc) - { - gc.drawRectangle(0, 0, 20, 15); - String label = isOn() ? "ON" : "OFF"; - Font oldFont = gc.getFont(); - Font labelFont = new Font(oldFont.getName(), 6, oldFont.getStyle()); - gc.setFont(labelFont); - Point textExtent = gc.textExtent(label); - gc.drawText(label, 10 - textExtent.x / 2, 7.5 - textExtent.y / 2, true); - gc.setFont(oldFont); - } - @Override - public boolean clicked(double x, double y) - { - toggle(); - return true; - } - - @Override - public int getConnectedWireArraysCount() - { - return connectedWireArrays.size(); - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return connectedWireArrays.get(connectionIndex); - } - @Override - public Point getWireArrayConnectionPoint(int connectionI) - { - return wireArrayConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/components/gui/GUIMerger.java b/LogicUI/src/era/mi/components/gui/GUIMerger.java deleted file mode 100644 index 69a47a22..00000000 --- a/LogicUI/src/era/mi/components/gui/GUIMerger.java +++ /dev/null @@ -1,75 +0,0 @@ -package era.mi.components.gui; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.Merger; -import era.mi.logic.wires.WireArray; -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 -{ - private final int inputCount; - private final double height; - private final List connectedWireArrays; - private final List wireArrayConnectionPoints; - - public GUIMerger(WireArray union, WireArray... inputs) - { - super(union, inputs); - - List connectedWireArraysModifiable = new ArrayList<>(); - List wireArrayConnectionPointsModifiable = new ArrayList<>(); - - this.inputCount = inputs.length; - this.height = (inputCount - 1) * 10; - - { - connectedWireArraysModifiable.addAll(Arrays.asList(inputs)); - double inputHeight = 0; - for(int i = 0; i < inputCount; i ++, inputHeight += 10) - wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); - } - - connectedWireArraysModifiable.add(union); - wireArrayConnectionPointsModifiable.add(new Point(20, height / 2)); - - this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); - this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, height); - } - @Override - public void render(GeneralGC gc) - { - double inputHeight = 0; - for(int i = 0; i < inputCount; i ++, inputHeight += 10) - gc.drawLine(0, inputHeight, 10, inputHeight); - gc.drawLine(10, 0, 10, height); - gc.drawLine(10, height / 2, 20, height / 2); - } - - @Override - public int getConnectedWireArraysCount() - { - return connectedWireArrays.size(); - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return connectedWireArrays.get(connectionIndex); - } - @Override - public Point getWireArrayConnectionPoint(int connectionI) - { - return wireArrayConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/components/gui/GUIMux.java b/LogicUI/src/era/mi/components/gui/GUIMux.java deleted file mode 100644 index df61ca77..00000000 --- a/LogicUI/src/era/mi/components/gui/GUIMux.java +++ /dev/null @@ -1,79 +0,0 @@ -package era.mi.components.gui; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.Mux; -import era.mi.logic.wires.WireArray; -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 -{ - private final double height; - private final List connectedWireArrays; - private final List wireArrayConnectionPoints; - - public GUIMux(int processTime, WireArray out, WireArray select, WireArray... inputs) - { - super(processTime, out, select, inputs); - - double height = inputs.length * 5; - if(height < 10) - height = 10; - this.height = height; - - List connectedWireArraysModifiable = new ArrayList<>(); - List wireArrayConnectionPointsModifiable = new ArrayList<>(); - - connectedWireArraysModifiable.add(out); - wireArrayConnectionPointsModifiable.add(new Point(20, 10 + height / 2)); - - connectedWireArraysModifiable.add(select); - wireArrayConnectionPointsModifiable.add(new Point(10, 5)); - - { - connectedWireArraysModifiable.addAll(Arrays.asList(inputs)); - double inputHeightIncrement = (height + 20) / inputs.length; - double inputHeight = inputHeightIncrement / 2; - for(int i = 0; i < inputs.length; i ++, inputHeight += inputHeightIncrement) - wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); - } - - this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); - this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, height + 20); - } - @Override - public void render(GeneralGC gc) - { - gc.drawPolygon(new double[] { - 0, 0, - 20, 10, - 20, height + 10, - 0, height + 20}); - } - @Override - public int getConnectedWireArraysCount() - { - return connectedWireArrays.size(); - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return connectedWireArrays.get(connectionIndex); - } - @Override - public Point getWireArrayConnectionPoint(int connectionI) - { - return wireArrayConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/components/gui/GUINotGate.java b/LogicUI/src/era/mi/components/gui/GUINotGate.java deleted file mode 100644 index b428888a..00000000 --- a/LogicUI/src/era/mi/components/gui/GUINotGate.java +++ /dev/null @@ -1,71 +0,0 @@ -package era.mi.components.gui; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.gates.NotGate; -import era.mi.logic.wires.WireArray; -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 connectedWireArrays; - private final List wireArrayConnectionPoints; - - public GUINotGate(int processTime, WireArray in, WireArray out) - { - super(processTime, in, out); - - List connectedWireArraysModifiable = new ArrayList<>(); - List wireArrayConnectionPointsModifiable = new ArrayList<>(); - - connectedWireArraysModifiable.add(in); - wireArrayConnectionPointsModifiable.add(new Point(0, 5)); - - connectedWireArraysModifiable.add(out); - wireArrayConnectionPointsModifiable.add(new Point(20, 5)); - - this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); - this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); - } - - @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 getConnectedWireArraysCount() - { - return connectedWireArrays.size(); - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return connectedWireArrays.get(connectionIndex); - } - @Override - public Point getWireArrayConnectionPoint(int connectionI) - { - return wireArrayConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/components/gui/GUIOrGate.java b/LogicUI/src/era/mi/components/gui/GUIOrGate.java deleted file mode 100644 index 3b497f28..00000000 --- a/LogicUI/src/era/mi/components/gui/GUIOrGate.java +++ /dev/null @@ -1,81 +0,0 @@ -package era.mi.components.gui; - -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.wires.WireArray; -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 connectedWireArrays; - private final List wireArrayConnectionPoints; - - public GUIOrGate(int processTime, WireArray out, WireArray... in) - { - super(processTime, out, in); - - List connectedWireArraysModifiable = new ArrayList<>(); - List wireArrayConnectionPointsModifiable = new ArrayList<>(); - - this.inputCount = in.length; - this.height = inputCount * 10; - - { - connectedWireArraysModifiable.addAll(Arrays.asList(in)); - double inputHeight = 5; - for(int i = 0; i < inputCount; i ++, inputHeight += 10) - wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); - } - - connectedWireArraysModifiable.add(out); - wireArrayConnectionPointsModifiable.add(new Point(20, height / 2)); - - this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); - this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, height); - } - @Override - public void render(GeneralGC gc) - { - gc.drawRectangle(0, 0, 17, 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, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true); - gc.setFont(oldFont); - gc.drawOval(17, height / 2 - 1.5, 3, 3); - } - - @Override - public int getConnectedWireArraysCount() - { - return connectedWireArrays.size(); - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return connectedWireArrays.get(connectionIndex); - } - @Override - public Point getWireArrayConnectionPoint(int connectionI) - { - return wireArrayConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/components/gui/GUISplitter.java b/LogicUI/src/era/mi/components/gui/GUISplitter.java deleted file mode 100644 index aab18cf4..00000000 --- a/LogicUI/src/era/mi/components/gui/GUISplitter.java +++ /dev/null @@ -1,75 +0,0 @@ -package era.mi.components.gui; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import era.mi.logic.components.Splitter; -import era.mi.logic.wires.WireArray; -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 -{ - private final int outputCount; - private final double height; - private final List connectedWireArrays; - private final List wireArrayConnectionPoints; - - public GUISplitter(WireArray input, WireArray... outputs) - { - super(input, outputs); - - List connectedWireArraysModifiable = new ArrayList<>(); - List wireArrayConnectionPointsModifiable = new ArrayList<>(); - - this.outputCount = outputs.length; - this.height = (outputCount - 1) * 10; - - connectedWireArraysModifiable.add(input); - wireArrayConnectionPointsModifiable.add(new Point(0, height / 2)); - - { - connectedWireArraysModifiable.addAll(Arrays.asList(outputs)); - double outputHeight = 0; - for(int i = 0; i < outputCount; i ++, outputHeight += 10) - wireArrayConnectionPointsModifiable.add(new Point(20, outputHeight)); - } - - this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); - this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); - } - - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 20, height); - } - @Override - public void render(GeneralGC gc) - { - gc.drawLine(0, height / 2, 10, height / 2); - gc.drawLine(10, 0, 10, height); - double outputHeight = 0; - for(int i = 0; i < outputCount; i ++, outputHeight += 10) - gc.drawLine(10, outputHeight, 20, outputHeight); - } - - @Override - public int getConnectedWireArraysCount() - { - return connectedWireArrays.size(); - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return connectedWireArrays.get(connectionIndex); - } - @Override - public Point getWireArrayConnectionPoint(int connectionI) - { - return wireArrayConnectionPoints.get(connectionI); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/examples/gui/LogicUI.java b/LogicUI/src/era/mi/examples/gui/LogicUI.java deleted file mode 100644 index a0ef151d..00000000 --- a/LogicUI/src/era/mi/examples/gui/LogicUI.java +++ /dev/null @@ -1,174 +0,0 @@ -package era.mi.examples.gui; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Shell; - -import era.mi.components.gui.BasicGUIComponent; -import era.mi.components.gui.GUIManualSwitch; -import era.mi.components.gui.GUINotGate; -import era.mi.components.gui.GUIOrGate; -import era.mi.logic.Simulation; -import era.mi.logic.wires.WireArray; -import era.mi.wires.gui.GUIWire; -import era.mi.wires.gui.WireConnectionPoint; -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.zoomablecanvas.ZoomableCanvas; -import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay; -import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput; - -public class LogicUI -{ - private static final int WIRE_DELAY = 40; - private static final int OR_DELAY = 100; - private static final int NOT_DELAY = 100; - private final Display display; - private final Shell shell; - private final ZoomableCanvas canvas; - private final Set components; - private final Map componentPositions; - private final Set wires; - - public LogicUI() - { - display = new Display(); - shell = new Shell(display); - shell.setLayout(new FillLayout()); - canvas = new ZoomableCanvas(shell, SWT.NONE); - - components = new HashSet<>(); - componentPositions = new HashMap<>(); - wires = new HashSet<>(); - initComponents(); - - canvas.addZoomedRenderer(gc -> components.forEach(c -> drawComponent(gc, c))); - canvas.addZoomedRenderer(gc -> wires.forEach(w -> w.render(gc))); - ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(canvas); - userInput.buttonDrag = 3; - userInput.buttonZoom = 2; - userInput.enableUserInput(); - new ZoomableCanvasOverlay(canvas, null).enableScale(); - canvas.addListener(SWT.MouseDown, this::mouseDown); - } - private void initComponents() - { - Simulation.TIMELINE.reset(); - WireArray r = new WireArray(1, WIRE_DELAY); - WireArray s = new WireArray(1, WIRE_DELAY); - WireArray t2 = new WireArray(1, WIRE_DELAY); - WireArray t1 = new WireArray(1, WIRE_DELAY); - WireArray q = new WireArray(1, WIRE_DELAY); - WireArray nq = new WireArray(1, WIRE_DELAY); - - GUIManualSwitch rIn = addComponent(new GUIManualSwitch(r), 100, 100); - GUIManualSwitch sIn = addComponent(new GUIManualSwitch(s), 100, 200); - GUIOrGate or1 = addComponent(new GUIOrGate(OR_DELAY, t1, r, nq), 160, 102.5); - GUIOrGate or2 = addComponent(new GUIOrGate(OR_DELAY, t2, q, s), 160, 192.5); - GUINotGate not1 = addComponent(new GUINotGate(NOT_DELAY, t1, q), 200, 107.5); - GUINotGate not2 = addComponent(new GUINotGate(NOT_DELAY, t2, nq), 200, 197.5); - - WireConnectionPoint p1 = addComponent(new WireConnectionPoint(q, 2), 250, 112.5); - WireConnectionPoint p2 = addComponent(new WireConnectionPoint(nq, 2), 250, 202.5); - - addWire(rIn, 0, or1, 0); - addWire(sIn, 0, or2, 1); - addWire(or1, 2, not1, 0); - addWire(or2, 2, not2, 0); - addWire(not1, 1, p1, 0); - addWire(not2, 1, p2, 0); - addWire(p1, 1, or2, 0, new Point(250, 130), new Point(140, 185), new Point(140, 197.5)); - addWire(p2, 1, or1, 1, new Point(250, 185), new Point(140, 130), new Point(140, 117.5)); - } - /** - * Returns the given component for convenience. - */ - private C addComponent(C component, double x, double y) - { - components.add(component); - componentPositions.put(component, new Point(x, y)); - return component; - } - private void addWire(BasicGUIComponent component1, int component1ConnectionIndex, BasicGUIComponent component2, int component2ConnectionIndex, Point... path) - { - wires.add(new GUIWire(canvas::redrawThreadsafe, component1, component1ConnectionIndex, componentPositions.get(component1), component2, component2ConnectionIndex, componentPositions.get(component2), path)); - } - private void drawComponent(GeneralGC gc, BasicGUIComponent component) - { - TranslatedGC tgc = new TranslatedGC(gc, componentPositions.get(component)); - component.render(tgc); - tgc.setBackground(display.getSystemColor(SWT.COLOR_BLUE)); - for(int i = 0; i < component.getConnectedWireArraysCount(); i ++) - { - Point connectionPoint = component.getWireArrayConnectionPoint(i); - if(connectionPoint != null) - tgc.fillOval(connectionPoint.x - 1, connectionPoint.y - 1, 2, 2); - } - } - private void mouseDown(Event e) - { - if(e.button == 1) - { - Point click = canvas.displayToWorldCoords(e.x, e.y); - for(BasicGUIComponent component : components) - if(component.getBounds().translate(componentPositions.get(component)).contains(click)) - { - if(component.clicked(click.x, click.y)) - canvas.redraw(); - break; - } - } - } - - 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 - Simulation.TIMELINE.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10); - long sleepTime; - if(Simulation.TIMELINE.hasNext()) - { - sleepTime = Simulation.TIMELINE.nextEventTime() - System.currentTimeMillis(); - } else - sleepTime = 100; - try - { - if(sleepTime > 0) - Thread.sleep(sleepTime); - } catch(InterruptedException e) - {} //it is normal execution flow to be interrupted - } - }); - simulationThread.start(); - Simulation.TIMELINE.addEventAddedListener(event -> - { - if(event.getTiming() >= System.currentTimeMillis() / (double) 1) - simulationThread.interrupt(); - }); - - shell.open(); - while(!shell.isDisposed()) - if(!display.readAndDispatch()) - display.sleep(); - running.set(false); - simulationThread.interrupt(); - } - - public static void main(String[] args) - { - new LogicUI().run(); - } -} \ 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 new file mode 100644 index 00000000..29696e13 --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/BasicGUIComponent.java @@ -0,0 +1,42 @@ +package era.mi.gui.components; + +import era.mi.logic.wires.WireArray; +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 getConnectedWireArraysCount(); + /** + * Returns the n-th wire array connected to this component. + */ + public WireArray getConnectedWireArray(int connectionIndex); + /** + * Returns relative coordinates where the n-th wire array is connected to this component. + */ + public Point getWireArrayConnectionPoint(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 new file mode 100644 index 00000000..8ff6068c --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/GUIAndGate.java @@ -0,0 +1,81 @@ +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.wires.WireArray; +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 connectedWireArrays; + private final List wireArrayConnectionPoints; + + public GUIAndGate(int processTime, WireArray out, WireArray... in) + { + super(processTime, out, in); + + List connectedWireArraysModifiable = new ArrayList<>(); + List wireArrayConnectionPointsModifiable = new ArrayList<>(); + + this.inputCount = in.length; + this.height = inputCount * 10; + + { + connectedWireArraysModifiable.addAll(Arrays.asList(in)); + double inputHeight = 5; + for(int i = 0; i < inputCount; i ++, inputHeight += 10) + wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); + } + + connectedWireArraysModifiable.add(out); + wireArrayConnectionPointsModifiable.add(new Point(20, height / 2)); + + this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); + this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); + } + + @Override + public Rectangle getBounds() + { + return new Rectangle(0, 0, 20, height); + } + @Override + public void render(GeneralGC gc) + { + gc.drawRectangle(0, 0, 17, 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, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true); + gc.setFont(oldFont); + gc.drawOval(17, height / 2 - 1.5, 3, 3); + } + + @Override + public int getConnectedWireArraysCount() + { + return connectedWireArrays.size(); + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return connectedWireArrays.get(connectionIndex); + } + @Override + public Point getWireArrayConnectionPoint(int connectionI) + { + return wireArrayConnectionPoints.get(connectionI); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/GUIManualSwitch.java b/LogicUI/src/era/mi/gui/components/GUIManualSwitch.java new file mode 100644 index 00000000..9d58cac9 --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/GUIManualSwitch.java @@ -0,0 +1,72 @@ +package era.mi.gui.components; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import era.mi.logic.components.ManualSwitch; +import era.mi.logic.wires.WireArray; +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 GUIManualSwitch extends ManualSwitch implements BasicGUIComponent +{ + private final List connectedWireArrays; + private final List wireArrayConnectionPoints; + + public GUIManualSwitch(WireArray output) + { + super(output); + + List connectedWireArraysModifiable = new ArrayList<>(); + List wireArrayConnectionPointsModifiable = new ArrayList<>(); + + connectedWireArraysModifiable.add(output); + wireArrayConnectionPointsModifiable.add(new Point(20, 7.5)); + + this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); + this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); + } + + @Override + public Rectangle getBounds() + { + return new Rectangle(0, 0, 20, 15); + } + @Override + public void render(GeneralGC gc) + { + gc.drawRectangle(0, 0, 20, 15); + String label = isOn() ? "ON" : "OFF"; + Font oldFont = gc.getFont(); + Font labelFont = new Font(oldFont.getName(), 6, oldFont.getStyle()); + gc.setFont(labelFont); + Point textExtent = gc.textExtent(label); + gc.drawText(label, 10 - textExtent.x / 2, 7.5 - textExtent.y / 2, true); + gc.setFont(oldFont); + } + @Override + public boolean clicked(double x, double y) + { + toggle(); + return true; + } + + @Override + public int getConnectedWireArraysCount() + { + return connectedWireArrays.size(); + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return connectedWireArrays.get(connectionIndex); + } + @Override + public Point getWireArrayConnectionPoint(int connectionI) + { + return wireArrayConnectionPoints.get(connectionI); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/GUIMerger.java b/LogicUI/src/era/mi/gui/components/GUIMerger.java new file mode 100644 index 00000000..601b434d --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/GUIMerger.java @@ -0,0 +1,75 @@ +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.Merger; +import era.mi.logic.wires.WireArray; +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 +{ + private final int inputCount; + private final double height; + private final List connectedWireArrays; + private final List wireArrayConnectionPoints; + + public GUIMerger(WireArray union, WireArray... inputs) + { + super(union, inputs); + + List connectedWireArraysModifiable = new ArrayList<>(); + List wireArrayConnectionPointsModifiable = new ArrayList<>(); + + this.inputCount = inputs.length; + this.height = (inputCount - 1) * 10; + + { + connectedWireArraysModifiable.addAll(Arrays.asList(inputs)); + double inputHeight = 0; + for(int i = 0; i < inputCount; i ++, inputHeight += 10) + wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); + } + + connectedWireArraysModifiable.add(union); + wireArrayConnectionPointsModifiable.add(new Point(20, height / 2)); + + this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); + this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); + } + + @Override + public Rectangle getBounds() + { + return new Rectangle(0, 0, 20, height); + } + @Override + public void render(GeneralGC gc) + { + double inputHeight = 0; + for(int i = 0; i < inputCount; i ++, inputHeight += 10) + gc.drawLine(0, inputHeight, 10, inputHeight); + gc.drawLine(10, 0, 10, height); + gc.drawLine(10, height / 2, 20, height / 2); + } + + @Override + public int getConnectedWireArraysCount() + { + return connectedWireArrays.size(); + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return connectedWireArrays.get(connectionIndex); + } + @Override + public Point getWireArrayConnectionPoint(int connectionI) + { + return wireArrayConnectionPoints.get(connectionI); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/GUIMux.java b/LogicUI/src/era/mi/gui/components/GUIMux.java new file mode 100644 index 00000000..0082a768 --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/GUIMux.java @@ -0,0 +1,79 @@ +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.Mux; +import era.mi.logic.wires.WireArray; +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 +{ + private final double height; + private final List connectedWireArrays; + private final List wireArrayConnectionPoints; + + public GUIMux(int processTime, WireArray out, WireArray select, WireArray... inputs) + { + super(processTime, out, select, inputs); + + double height = inputs.length * 5; + if(height < 10) + height = 10; + this.height = height; + + List connectedWireArraysModifiable = new ArrayList<>(); + List wireArrayConnectionPointsModifiable = new ArrayList<>(); + + connectedWireArraysModifiable.add(out); + wireArrayConnectionPointsModifiable.add(new Point(20, 10 + height / 2)); + + connectedWireArraysModifiable.add(select); + wireArrayConnectionPointsModifiable.add(new Point(10, 5)); + + { + connectedWireArraysModifiable.addAll(Arrays.asList(inputs)); + double inputHeightIncrement = (height + 20) / inputs.length; + double inputHeight = inputHeightIncrement / 2; + for(int i = 0; i < inputs.length; i ++, inputHeight += inputHeightIncrement) + wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); + } + + this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); + this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); + } + + @Override + public Rectangle getBounds() + { + return new Rectangle(0, 0, 20, height + 20); + } + @Override + public void render(GeneralGC gc) + { + gc.drawPolygon(new double[] { + 0, 0, + 20, 10, + 20, height + 10, + 0, height + 20}); + } + @Override + public int getConnectedWireArraysCount() + { + return connectedWireArrays.size(); + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return connectedWireArrays.get(connectionIndex); + } + @Override + public Point getWireArrayConnectionPoint(int connectionI) + { + return wireArrayConnectionPoints.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 new file mode 100644 index 00000000..78bed33f --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/GUINotGate.java @@ -0,0 +1,71 @@ +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.wires.WireArray; +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 connectedWireArrays; + private final List wireArrayConnectionPoints; + + public GUINotGate(int processTime, WireArray in, WireArray out) + { + super(processTime, in, out); + + List connectedWireArraysModifiable = new ArrayList<>(); + List wireArrayConnectionPointsModifiable = new ArrayList<>(); + + connectedWireArraysModifiable.add(in); + wireArrayConnectionPointsModifiable.add(new Point(0, 5)); + + connectedWireArraysModifiable.add(out); + wireArrayConnectionPointsModifiable.add(new Point(20, 5)); + + this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); + this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); + } + + @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 getConnectedWireArraysCount() + { + return connectedWireArrays.size(); + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return connectedWireArrays.get(connectionIndex); + } + @Override + public Point getWireArrayConnectionPoint(int connectionI) + { + return wireArrayConnectionPoints.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 new file mode 100644 index 00000000..4ca09f58 --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/GUIOrGate.java @@ -0,0 +1,81 @@ +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.wires.WireArray; +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 connectedWireArrays; + private final List wireArrayConnectionPoints; + + public GUIOrGate(int processTime, WireArray out, WireArray... in) + { + super(processTime, out, in); + + List connectedWireArraysModifiable = new ArrayList<>(); + List wireArrayConnectionPointsModifiable = new ArrayList<>(); + + this.inputCount = in.length; + this.height = inputCount * 10; + + { + connectedWireArraysModifiable.addAll(Arrays.asList(in)); + double inputHeight = 5; + for(int i = 0; i < inputCount; i ++, inputHeight += 10) + wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight)); + } + + connectedWireArraysModifiable.add(out); + wireArrayConnectionPointsModifiable.add(new Point(20, height / 2)); + + this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); + this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); + } + + @Override + public Rectangle getBounds() + { + return new Rectangle(0, 0, 20, height); + } + @Override + public void render(GeneralGC gc) + { + gc.drawRectangle(0, 0, 17, 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, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true); + gc.setFont(oldFont); + gc.drawOval(17, height / 2 - 1.5, 3, 3); + } + + @Override + public int getConnectedWireArraysCount() + { + return connectedWireArrays.size(); + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return connectedWireArrays.get(connectionIndex); + } + @Override + public Point getWireArrayConnectionPoint(int connectionI) + { + return wireArrayConnectionPoints.get(connectionI); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/components/GUISplitter.java b/LogicUI/src/era/mi/gui/components/GUISplitter.java new file mode 100644 index 00000000..8d09cc70 --- /dev/null +++ b/LogicUI/src/era/mi/gui/components/GUISplitter.java @@ -0,0 +1,75 @@ +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.Splitter; +import era.mi.logic.wires.WireArray; +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 +{ + private final int outputCount; + private final double height; + private final List connectedWireArrays; + private final List wireArrayConnectionPoints; + + public GUISplitter(WireArray input, WireArray... outputs) + { + super(input, outputs); + + List connectedWireArraysModifiable = new ArrayList<>(); + List wireArrayConnectionPointsModifiable = new ArrayList<>(); + + this.outputCount = outputs.length; + this.height = (outputCount - 1) * 10; + + connectedWireArraysModifiable.add(input); + wireArrayConnectionPointsModifiable.add(new Point(0, height / 2)); + + { + connectedWireArraysModifiable.addAll(Arrays.asList(outputs)); + double outputHeight = 0; + for(int i = 0; i < outputCount; i ++, outputHeight += 10) + wireArrayConnectionPointsModifiable.add(new Point(20, outputHeight)); + } + + this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable); + this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable); + } + + @Override + public Rectangle getBounds() + { + return new Rectangle(0, 0, 20, height); + } + @Override + public void render(GeneralGC gc) + { + gc.drawLine(0, height / 2, 10, height / 2); + gc.drawLine(10, 0, 10, height); + double outputHeight = 0; + for(int i = 0; i < outputCount; i ++, outputHeight += 10) + gc.drawLine(10, outputHeight, 20, outputHeight); + } + + @Override + public int getConnectedWireArraysCount() + { + return connectedWireArrays.size(); + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return connectedWireArrays.get(connectionIndex); + } + @Override + public Point getWireArrayConnectionPoint(int connectionI) + { + return wireArrayConnectionPoints.get(connectionI); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/gui/examples/LogicUI.java b/LogicUI/src/era/mi/gui/examples/LogicUI.java new file mode 100644 index 00000000..1c39c7c8 --- /dev/null +++ b/LogicUI/src/era/mi/gui/examples/LogicUI.java @@ -0,0 +1,174 @@ +package era.mi.gui.examples; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; + +import era.mi.gui.components.BasicGUIComponent; +import era.mi.gui.components.GUIManualSwitch; +import era.mi.gui.components.GUINotGate; +import era.mi.gui.components.GUIOrGate; +import era.mi.gui.wires.GUIWire; +import era.mi.gui.wires.WireConnectionPoint; +import era.mi.logic.Simulation; +import era.mi.logic.wires.WireArray; +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.zoomablecanvas.ZoomableCanvas; +import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay; +import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput; + +public class LogicUI +{ + private static final int WIRE_DELAY = 40; + private static final int OR_DELAY = 100; + private static final int NOT_DELAY = 100; + private final Display display; + private final Shell shell; + private final ZoomableCanvas canvas; + private final Set components; + private final Map componentPositions; + private final Set wires; + + public LogicUI() + { + display = new Display(); + shell = new Shell(display); + shell.setLayout(new FillLayout()); + canvas = new ZoomableCanvas(shell, SWT.NONE); + + components = new HashSet<>(); + componentPositions = new HashMap<>(); + wires = new HashSet<>(); + initComponents(); + + canvas.addZoomedRenderer(gc -> components.forEach(c -> drawComponent(gc, c))); + canvas.addZoomedRenderer(gc -> wires.forEach(w -> w.render(gc))); + ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(canvas); + userInput.buttonDrag = 3; + userInput.buttonZoom = 2; + userInput.enableUserInput(); + new ZoomableCanvasOverlay(canvas, null).enableScale(); + canvas.addListener(SWT.MouseDown, this::mouseDown); + } + private void initComponents() + { + Simulation.TIMELINE.reset(); + WireArray r = new WireArray(1, WIRE_DELAY); + WireArray s = new WireArray(1, WIRE_DELAY); + WireArray t2 = new WireArray(1, WIRE_DELAY); + WireArray t1 = new WireArray(1, WIRE_DELAY); + WireArray q = new WireArray(1, WIRE_DELAY); + WireArray nq = new WireArray(1, WIRE_DELAY); + + GUIManualSwitch rIn = addComponent(new GUIManualSwitch(r), 100, 100); + GUIManualSwitch sIn = addComponent(new GUIManualSwitch(s), 100, 200); + GUIOrGate or1 = addComponent(new GUIOrGate(OR_DELAY, t1, r, nq), 160, 102.5); + GUIOrGate or2 = addComponent(new GUIOrGate(OR_DELAY, t2, q, s), 160, 192.5); + GUINotGate not1 = addComponent(new GUINotGate(NOT_DELAY, t1, q), 200, 107.5); + GUINotGate not2 = addComponent(new GUINotGate(NOT_DELAY, t2, nq), 200, 197.5); + + WireConnectionPoint p1 = addComponent(new WireConnectionPoint(q, 2), 250, 112.5); + WireConnectionPoint p2 = addComponent(new WireConnectionPoint(nq, 2), 250, 202.5); + + addWire(rIn, 0, or1, 0); + addWire(sIn, 0, or2, 1); + addWire(or1, 2, not1, 0); + addWire(or2, 2, not2, 0); + addWire(not1, 1, p1, 0); + addWire(not2, 1, p2, 0); + addWire(p1, 1, or2, 0, new Point(250, 130), new Point(140, 185), new Point(140, 197.5)); + addWire(p2, 1, or1, 1, new Point(250, 185), new Point(140, 130), new Point(140, 117.5)); + } + /** + * Returns the given component for convenience. + */ + private C addComponent(C component, double x, double y) + { + components.add(component); + componentPositions.put(component, new Point(x, y)); + return component; + } + private void addWire(BasicGUIComponent component1, int component1ConnectionIndex, BasicGUIComponent component2, int component2ConnectionIndex, Point... path) + { + wires.add(new GUIWire(canvas::redrawThreadsafe, component1, component1ConnectionIndex, componentPositions.get(component1), component2, component2ConnectionIndex, componentPositions.get(component2), path)); + } + private void drawComponent(GeneralGC gc, BasicGUIComponent component) + { + TranslatedGC tgc = new TranslatedGC(gc, componentPositions.get(component)); + component.render(tgc); + tgc.setBackground(display.getSystemColor(SWT.COLOR_BLUE)); + for(int i = 0; i < component.getConnectedWireArraysCount(); i ++) + { + Point connectionPoint = component.getWireArrayConnectionPoint(i); + if(connectionPoint != null) + tgc.fillOval(connectionPoint.x - 1, connectionPoint.y - 1, 2, 2); + } + } + private void mouseDown(Event e) + { + if(e.button == 1) + { + Point click = canvas.displayToWorldCoords(e.x, e.y); + for(BasicGUIComponent component : components) + if(component.getBounds().translate(componentPositions.get(component)).contains(click)) + { + if(component.clicked(click.x, click.y)) + canvas.redraw(); + break; + } + } + } + + 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 + Simulation.TIMELINE.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10); + long sleepTime; + if(Simulation.TIMELINE.hasNext()) + { + sleepTime = Simulation.TIMELINE.nextEventTime() - System.currentTimeMillis(); + } else + sleepTime = 100; + try + { + if(sleepTime > 0) + Thread.sleep(sleepTime); + } catch(InterruptedException e) + {} //it is normal execution flow to be interrupted + } + }); + simulationThread.start(); + Simulation.TIMELINE.addEventAddedListener(event -> + { + if(event.getTiming() >= System.currentTimeMillis() / (double) 1) + simulationThread.interrupt(); + }); + + shell.open(); + while(!shell.isDisposed()) + if(!display.readAndDispatch()) + display.sleep(); + running.set(false); + simulationThread.interrupt(); + } + + public static void main(String[] args) + { + new LogicUI().run(); + } +} \ 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 new file mode 100644 index 00000000..3b04fae8 --- /dev/null +++ b/LogicUI/src/era/mi/gui/wires/GUIWire.java @@ -0,0 +1,66 @@ +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.wires.WireArray; +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; + +public class GUIWire +{ + private final WireArray wa; + private final double[] path; + + public GUIWire(Runnable redraw, BasicGUIComponent component1, int component1ConnectionIndex, Point component1Pos, BasicGUIComponent component2, int component2ConnectionIndex, Point component2Pos, Point... path) + { + this.wa = component1.getConnectedWireArray(component1ConnectionIndex); + if(!Objects.equals(wa, component2.getConnectedWireArray(component2ConnectionIndex))) + throw new IllegalArgumentException("Given connection points are not connected!"); + this.path = new double[path.length * 2 + 4]; + Point component1ConnectionPoint = component1.getWireArrayConnectionPoint(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.getWireArrayConnectionPoint(component2ConnectionIndex); + this.path[this.path.length - 2] = component2Pos.x + component2ConnectionPoint.x; + this.path[this.path.length - 1] = component2Pos.y + component2ConnectionPoint.y; + + wa.addObserver((initiator, oldValues) -> redraw.run()); + } + + public void render(GeneralGC gc) + { + Color oldFG = gc.getForeground(); + if(wa.length == 1) + { + int fgColorConstant; + switch(wa.getValue()) + { + case ONE: + fgColorConstant = SWT.COLOR_GREEN; + break; + case ZERO: + fgColorConstant = SWT.COLOR_BLUE; + break; + case U: + case X: + case Z: + fgColorConstant = SWT.COLOR_RED; + break; + default: + throw new IllegalArgumentException("Unknown enum constant: " + wa.getValue()); + } + gc.setForeground(gc.getDevice().getSystemColor(fgColorConstant)); + } + gc.drawPolyline(path); + gc.setForeground(oldFG); + } +} \ 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 new file mode 100644 index 00000000..9c1aae14 --- /dev/null +++ b/LogicUI/src/era/mi/gui/wires/WireConnectionPoint.java @@ -0,0 +1,51 @@ +package era.mi.gui.wires; + +import org.eclipse.swt.graphics.Color; + +import era.mi.gui.components.BasicGUIComponent; +import era.mi.logic.wires.WireArray; +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 WireArray wa; + private final int wiresCrossing; + + public WireConnectionPoint(WireArray wa, int wiresCrossing) + { + this.wa = wa; + this.wiresCrossing = wiresCrossing; + } + + @Override + public void render(GeneralGC gc) + { + Color oldBG = gc.getBackground(); + Color fg = gc.getForeground(); + gc.setBackground(fg); + gc.fillOval(-2, -2, 4, 4); + gc.setBackground(oldBG); + } + @Override + public Rectangle getBounds() + { + return new Rectangle(0, 0, 0, 0); + } + @Override + public int getConnectedWireArraysCount() + { + return wiresCrossing; + } + @Override + public WireArray getConnectedWireArray(int connectionIndex) + { + return wa; + } + @Override + public Point getWireArrayConnectionPoint(int connectionIndex) + { + return new Point(0, 0); + } +} \ No newline at end of file diff --git a/LogicUI/src/era/mi/wires/gui/GUIWire.java b/LogicUI/src/era/mi/wires/gui/GUIWire.java deleted file mode 100644 index 65f82c7e..00000000 --- a/LogicUI/src/era/mi/wires/gui/GUIWire.java +++ /dev/null @@ -1,66 +0,0 @@ -package era.mi.wires.gui; - -import java.util.Objects; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; - -import era.mi.components.gui.BasicGUIComponent; -import era.mi.logic.wires.WireArray; -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; - -public class GUIWire -{ - private final WireArray wa; - private final double[] path; - - public GUIWire(Runnable redraw, BasicGUIComponent component1, int component1ConnectionIndex, Point component1Pos, BasicGUIComponent component2, int component2ConnectionIndex, Point component2Pos, Point... path) - { - this.wa = component1.getConnectedWireArray(component1ConnectionIndex); - if(!Objects.equals(wa, component2.getConnectedWireArray(component2ConnectionIndex))) - throw new IllegalArgumentException("Given connection points are not connected!"); - this.path = new double[path.length * 2 + 4]; - Point component1ConnectionPoint = component1.getWireArrayConnectionPoint(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.getWireArrayConnectionPoint(component2ConnectionIndex); - this.path[this.path.length - 2] = component2Pos.x + component2ConnectionPoint.x; - this.path[this.path.length - 1] = component2Pos.y + component2ConnectionPoint.y; - - wa.addObserver((initiator, oldValues) -> redraw.run()); - } - - public void render(GeneralGC gc) - { - Color oldFG = gc.getForeground(); - if(wa.length == 1) - { - int fgColorConstant; - switch(wa.getValue()) - { - case ONE: - fgColorConstant = SWT.COLOR_GREEN; - break; - case ZERO: - fgColorConstant = SWT.COLOR_BLUE; - break; - case U: - case X: - case Z: - fgColorConstant = SWT.COLOR_RED; - break; - default: - throw new IllegalArgumentException("Unknown enum constant: " + wa.getValue()); - } - gc.setForeground(gc.getDevice().getSystemColor(fgColorConstant)); - } - gc.drawPolyline(path); - gc.setForeground(oldFG); - } -} \ No newline at end of file diff --git a/LogicUI/src/era/mi/wires/gui/WireConnectionPoint.java b/LogicUI/src/era/mi/wires/gui/WireConnectionPoint.java deleted file mode 100644 index 753d61e9..00000000 --- a/LogicUI/src/era/mi/wires/gui/WireConnectionPoint.java +++ /dev/null @@ -1,51 +0,0 @@ -package era.mi.wires.gui; - -import org.eclipse.swt.graphics.Color; - -import era.mi.components.gui.BasicGUIComponent; -import era.mi.logic.wires.WireArray; -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 WireArray wa; - private final int wiresCrossing; - - public WireConnectionPoint(WireArray wa, int wiresCrossing) - { - this.wa = wa; - this.wiresCrossing = wiresCrossing; - } - - @Override - public void render(GeneralGC gc) - { - Color oldBG = gc.getBackground(); - Color fg = gc.getForeground(); - gc.setBackground(fg); - gc.fillOval(-2, -2, 4, 4); - gc.setBackground(oldBG); - } - @Override - public Rectangle getBounds() - { - return new Rectangle(0, 0, 0, 0); - } - @Override - public int getConnectedWireArraysCount() - { - return wiresCrossing; - } - @Override - public WireArray getConnectedWireArray(int connectionIndex) - { - return wa; - } - @Override - public Point getWireArrayConnectionPoint(int connectionIndex) - { - return new Point(0, 0); - } -} \ No newline at end of file