+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public interface BasicGUIComponent\r
-{\r
- /**\r
- * Render this component to the given gc, at coordinates (0, 0).\r
- */\r
- public void render(GeneralGC gc);\r
- /**\r
- * Returns the bounds of this component.\r
- * Used for calculating which component is clicked.\r
- */\r
- public Rectangle getBounds();\r
- /**\r
- * Called when this component is clicked. Relative coordinates of the click are given.\r
- * Returns true if this component has to be redrawn.\r
- */\r
- public default boolean clicked(double x, double y)\r
- {\r
- return false;\r
- }\r
-\r
- //TODO this code will be replaced by code in BasicComponent.\r
- /**\r
- * Returns how many wire arrays are connected to this component.\r
- * (Connections are static - they can't be removed and no new ones can be added)\r
- */\r
- public int getConnectedWireArraysCount();\r
- /**\r
- * Returns the n-th wire array connected to this component.\r
- */\r
- public WireArray getConnectedWireArray(int connectionIndex);\r
- /**\r
- * Returns relative coordinates where the n-th wire array is connected to this component.\r
- */\r
- public Point getWireArrayConnectionPoint(int connectionIndex);\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import era.mi.logic.components.gates.AndGate;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class GUIAndGate extends AndGate implements BasicGUIComponent\r
-{\r
- private static final String LABEL = "&";\r
-\r
- private final int inputCount;\r
- private final double height;\r
- private final List<WireArray> connectedWireArrays;\r
- private final List<Point> wireArrayConnectionPoints;\r
-\r
- public GUIAndGate(int processTime, WireArray out, WireArray... in)\r
- {\r
- super(processTime, out, in);\r
-\r
- List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
- List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
-\r
- this.inputCount = in.length;\r
- this.height = inputCount * 10;\r
-\r
- {\r
- connectedWireArraysModifiable.addAll(Arrays.asList(in));\r
- double inputHeight = 5;\r
- for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
- wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
- }\r
-\r
- connectedWireArraysModifiable.add(out);\r
- wireArrayConnectionPointsModifiable.add(new Point(20, height / 2));\r
-\r
- this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
- this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
- }\r
-\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 20, height);\r
- }\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- gc.drawRectangle(0, 0, 17, height);\r
- Font oldFont = gc.getFont();\r
- Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle());\r
- gc.setFont(labelFont);\r
- Point textExtent = gc.textExtent(LABEL);\r
- gc.drawText(LABEL, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true);\r
- gc.setFont(oldFont);\r
- gc.drawOval(17, height / 2 - 1.5, 3, 3);\r
- }\r
-\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return connectedWireArrays.size();\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return connectedWireArrays.get(connectionIndex);\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionI)\r
- {\r
- return wireArrayConnectionPoints.get(connectionI);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import era.mi.logic.components.ManualSwitch;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class GUIManualSwitch extends ManualSwitch implements BasicGUIComponent\r
-{\r
- private final List<WireArray> connectedWireArrays;\r
- private final List<Point> wireArrayConnectionPoints;\r
-\r
- public GUIManualSwitch(WireArray output)\r
- {\r
- super(output);\r
-\r
- List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
- List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
-\r
- connectedWireArraysModifiable.add(output);\r
- wireArrayConnectionPointsModifiable.add(new Point(20, 7.5));\r
-\r
- this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
- this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
- }\r
-\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 20, 15);\r
- }\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- gc.drawRectangle(0, 0, 20, 15);\r
- String label = isOn() ? "ON" : "OFF";\r
- Font oldFont = gc.getFont();\r
- Font labelFont = new Font(oldFont.getName(), 6, oldFont.getStyle());\r
- gc.setFont(labelFont);\r
- Point textExtent = gc.textExtent(label);\r
- gc.drawText(label, 10 - textExtent.x / 2, 7.5 - textExtent.y / 2, true);\r
- gc.setFont(oldFont);\r
- }\r
- @Override\r
- public boolean clicked(double x, double y)\r
- {\r
- toggle();\r
- return true;\r
- }\r
-\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return connectedWireArrays.size();\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return connectedWireArrays.get(connectionIndex);\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionI)\r
- {\r
- return wireArrayConnectionPoints.get(connectionI);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import era.mi.logic.components.Merger;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class GUIMerger extends Merger implements BasicGUIComponent\r
-{\r
- private final int inputCount;\r
- private final double height;\r
- private final List<WireArray> connectedWireArrays;\r
- private final List<Point> wireArrayConnectionPoints;\r
-\r
- public GUIMerger(WireArray union, WireArray... inputs)\r
- {\r
- super(union, inputs);\r
-\r
- List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
- List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
-\r
- this.inputCount = inputs.length;\r
- this.height = (inputCount - 1) * 10;\r
-\r
- {\r
- connectedWireArraysModifiable.addAll(Arrays.asList(inputs));\r
- double inputHeight = 0;\r
- for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
- wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
- }\r
-\r
- connectedWireArraysModifiable.add(union);\r
- wireArrayConnectionPointsModifiable.add(new Point(20, height / 2));\r
-\r
- this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
- this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
- }\r
-\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 20, height);\r
- }\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- double inputHeight = 0;\r
- for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
- gc.drawLine(0, inputHeight, 10, inputHeight);\r
- gc.drawLine(10, 0, 10, height);\r
- gc.drawLine(10, height / 2, 20, height / 2);\r
- }\r
-\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return connectedWireArrays.size();\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return connectedWireArrays.get(connectionIndex);\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionI)\r
- {\r
- return wireArrayConnectionPoints.get(connectionI);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import era.mi.logic.components.Mux;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class GUIMux extends Mux implements BasicGUIComponent\r
-{\r
- private final double height;\r
- private final List<WireArray> connectedWireArrays;\r
- private final List<Point> wireArrayConnectionPoints;\r
-\r
- public GUIMux(int processTime, WireArray out, WireArray select, WireArray... inputs)\r
- {\r
- super(processTime, out, select, inputs);\r
-\r
- double height = inputs.length * 5;\r
- if(height < 10)\r
- height = 10;\r
- this.height = height;\r
-\r
- List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
- List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
-\r
- connectedWireArraysModifiable.add(out);\r
- wireArrayConnectionPointsModifiable.add(new Point(20, 10 + height / 2));\r
-\r
- connectedWireArraysModifiable.add(select);\r
- wireArrayConnectionPointsModifiable.add(new Point(10, 5));\r
-\r
- {\r
- connectedWireArraysModifiable.addAll(Arrays.asList(inputs));\r
- double inputHeightIncrement = (height + 20) / inputs.length;\r
- double inputHeight = inputHeightIncrement / 2;\r
- for(int i = 0; i < inputs.length; i ++, inputHeight += inputHeightIncrement)\r
- wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
- }\r
-\r
- this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
- this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
- }\r
-\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 20, height + 20);\r
- }\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- gc.drawPolygon(new double[] {\r
- 0, 0,\r
- 20, 10,\r
- 20, height + 10,\r
- 0, height + 20});\r
- }\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return connectedWireArrays.size();\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return connectedWireArrays.get(connectionIndex);\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionI)\r
- {\r
- return wireArrayConnectionPoints.get(connectionI);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import era.mi.logic.components.gates.NotGate;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class GUINotGate extends NotGate implements BasicGUIComponent\r
-{\r
- private static final String LABEL = "\u22651";//>=1\r
-\r
- private final List<WireArray> connectedWireArrays;\r
- private final List<Point> wireArrayConnectionPoints;\r
-\r
- public GUINotGate(int processTime, WireArray in, WireArray out)\r
- {\r
- super(processTime, in, out);\r
-\r
- List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
- List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
-\r
- connectedWireArraysModifiable.add(in);\r
- wireArrayConnectionPointsModifiable.add(new Point(0, 5));\r
-\r
- connectedWireArraysModifiable.add(out);\r
- wireArrayConnectionPointsModifiable.add(new Point(20, 5));\r
-\r
- this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
- this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
- }\r
-\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 20, 10);\r
- }\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- gc.drawRectangle(0, 0, 17, 10);\r
- Font oldFont = gc.getFont();\r
- Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle());\r
- gc.setFont(labelFont);\r
- Point textExtent = gc.textExtent(LABEL);\r
- gc.drawText(LABEL, 8.5 - textExtent.x / 2, 5 - textExtent.y / 2, true);\r
- gc.setFont(oldFont);\r
- gc.drawOval(17, 3.5, 3, 3);\r
- }\r
-\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return connectedWireArrays.size();\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return connectedWireArrays.get(connectionIndex);\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionI)\r
- {\r
- return wireArrayConnectionPoints.get(connectionI);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import era.mi.logic.components.gates.OrGate;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class GUIOrGate extends OrGate implements BasicGUIComponent\r
-{\r
- private static final String LABEL = "\u22651";//>=1\r
-\r
- private final int inputCount;\r
- private final double height;\r
- private final List<WireArray> connectedWireArrays;\r
- private final List<Point> wireArrayConnectionPoints;\r
-\r
- public GUIOrGate(int processTime, WireArray out, WireArray... in)\r
- {\r
- super(processTime, out, in);\r
-\r
- List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
- List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
-\r
- this.inputCount = in.length;\r
- this.height = inputCount * 10;\r
-\r
- {\r
- connectedWireArraysModifiable.addAll(Arrays.asList(in));\r
- double inputHeight = 5;\r
- for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
- wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
- }\r
-\r
- connectedWireArraysModifiable.add(out);\r
- wireArrayConnectionPointsModifiable.add(new Point(20, height / 2));\r
-\r
- this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
- this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
- }\r
-\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 20, height);\r
- }\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- gc.drawRectangle(0, 0, 17, height);\r
- Font oldFont = gc.getFont();\r
- Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle());\r
- gc.setFont(labelFont);\r
- Point textExtent = gc.textExtent(LABEL);\r
- gc.drawText(LABEL, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true);\r
- gc.setFont(oldFont);\r
- gc.drawOval(17, height / 2 - 1.5, 3, 3);\r
- }\r
-\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return connectedWireArrays.size();\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return connectedWireArrays.get(connectionIndex);\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionI)\r
- {\r
- return wireArrayConnectionPoints.get(connectionI);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.components.gui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import era.mi.logic.components.Splitter;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class GUISplitter extends Splitter implements BasicGUIComponent\r
-{\r
- private final int outputCount;\r
- private final double height;\r
- private final List<WireArray> connectedWireArrays;\r
- private final List<Point> wireArrayConnectionPoints;\r
-\r
- public GUISplitter(WireArray input, WireArray... outputs)\r
- {\r
- super(input, outputs);\r
-\r
- List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
- List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
-\r
- this.outputCount = outputs.length;\r
- this.height = (outputCount - 1) * 10;\r
-\r
- connectedWireArraysModifiable.add(input);\r
- wireArrayConnectionPointsModifiable.add(new Point(0, height / 2));\r
-\r
- {\r
- connectedWireArraysModifiable.addAll(Arrays.asList(outputs));\r
- double outputHeight = 0;\r
- for(int i = 0; i < outputCount; i ++, outputHeight += 10)\r
- wireArrayConnectionPointsModifiable.add(new Point(20, outputHeight));\r
- }\r
-\r
- this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
- this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
- }\r
-\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 20, height);\r
- }\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- gc.drawLine(0, height / 2, 10, height / 2);\r
- gc.drawLine(10, 0, 10, height);\r
- double outputHeight = 0;\r
- for(int i = 0; i < outputCount; i ++, outputHeight += 10)\r
- gc.drawLine(10, outputHeight, 20, outputHeight);\r
- }\r
-\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return connectedWireArrays.size();\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return connectedWireArrays.get(connectionIndex);\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionI)\r
- {\r
- return wireArrayConnectionPoints.get(connectionI);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.examples.gui;\r
-\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.concurrent.atomic.AtomicBoolean;\r
-\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.layout.FillLayout;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Event;\r
-import org.eclipse.swt.widgets.Shell;\r
-\r
-import era.mi.components.gui.BasicGUIComponent;\r
-import era.mi.components.gui.GUIManualSwitch;\r
-import era.mi.components.gui.GUINotGate;\r
-import era.mi.components.gui.GUIOrGate;\r
-import era.mi.logic.Simulation;\r
-import era.mi.logic.wires.WireArray;\r
-import era.mi.wires.gui.GUIWire;\r
-import era.mi.wires.gui.WireConnectionPoint;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.gcs.TranslatedGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas;\r
-import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay;\r
-import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput;\r
-\r
-public class LogicUI\r
-{\r
- private static final int WIRE_DELAY = 40;\r
- private static final int OR_DELAY = 100;\r
- private static final int NOT_DELAY = 100;\r
- private final Display display;\r
- private final Shell shell;\r
- private final ZoomableCanvas canvas;\r
- private final Set<BasicGUIComponent> components;\r
- private final Map<BasicGUIComponent, Point> componentPositions;\r
- private final Set<GUIWire> wires;\r
-\r
- public LogicUI()\r
- {\r
- display = new Display();\r
- shell = new Shell(display);\r
- shell.setLayout(new FillLayout());\r
- canvas = new ZoomableCanvas(shell, SWT.NONE);\r
-\r
- components = new HashSet<>();\r
- componentPositions = new HashMap<>();\r
- wires = new HashSet<>();\r
- initComponents();\r
-\r
- canvas.addZoomedRenderer(gc -> components.forEach(c -> drawComponent(gc, c)));\r
- canvas.addZoomedRenderer(gc -> wires.forEach(w -> w.render(gc)));\r
- ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(canvas);\r
- userInput.buttonDrag = 3;\r
- userInput.buttonZoom = 2;\r
- userInput.enableUserInput();\r
- new ZoomableCanvasOverlay(canvas, null).enableScale();\r
- canvas.addListener(SWT.MouseDown, this::mouseDown);\r
- }\r
- private void initComponents()\r
- {\r
- Simulation.TIMELINE.reset();\r
- WireArray r = new WireArray(1, WIRE_DELAY);\r
- WireArray s = new WireArray(1, WIRE_DELAY);\r
- WireArray t2 = new WireArray(1, WIRE_DELAY);\r
- WireArray t1 = new WireArray(1, WIRE_DELAY);\r
- WireArray q = new WireArray(1, WIRE_DELAY);\r
- WireArray nq = new WireArray(1, WIRE_DELAY);\r
-\r
- GUIManualSwitch rIn = addComponent(new GUIManualSwitch(r), 100, 100);\r
- GUIManualSwitch sIn = addComponent(new GUIManualSwitch(s), 100, 200);\r
- GUIOrGate or1 = addComponent(new GUIOrGate(OR_DELAY, t1, r, nq), 160, 102.5);\r
- GUIOrGate or2 = addComponent(new GUIOrGate(OR_DELAY, t2, q, s), 160, 192.5);\r
- GUINotGate not1 = addComponent(new GUINotGate(NOT_DELAY, t1, q), 200, 107.5);\r
- GUINotGate not2 = addComponent(new GUINotGate(NOT_DELAY, t2, nq), 200, 197.5);\r
-\r
- WireConnectionPoint p1 = addComponent(new WireConnectionPoint(q, 2), 250, 112.5);\r
- WireConnectionPoint p2 = addComponent(new WireConnectionPoint(nq, 2), 250, 202.5);\r
-\r
- addWire(rIn, 0, or1, 0);\r
- addWire(sIn, 0, or2, 1);\r
- addWire(or1, 2, not1, 0);\r
- addWire(or2, 2, not2, 0);\r
- addWire(not1, 1, p1, 0);\r
- addWire(not2, 1, p2, 0);\r
- addWire(p1, 1, or2, 0, new Point(250, 130), new Point(140, 185), new Point(140, 197.5));\r
- addWire(p2, 1, or1, 1, new Point(250, 185), new Point(140, 130), new Point(140, 117.5));\r
- }\r
- /**\r
- * Returns the given component for convenience.\r
- */\r
- private <C extends BasicGUIComponent> C addComponent(C component, double x, double y)\r
- {\r
- components.add(component);\r
- componentPositions.put(component, new Point(x, y));\r
- return component;\r
- }\r
- private void addWire(BasicGUIComponent component1, int component1ConnectionIndex, BasicGUIComponent component2, int component2ConnectionIndex, Point... path)\r
- {\r
- wires.add(new GUIWire(canvas::redrawThreadsafe, component1, component1ConnectionIndex, componentPositions.get(component1), component2, component2ConnectionIndex, componentPositions.get(component2), path));\r
- }\r
- private void drawComponent(GeneralGC gc, BasicGUIComponent component)\r
- {\r
- TranslatedGC tgc = new TranslatedGC(gc, componentPositions.get(component));\r
- component.render(tgc);\r
- tgc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));\r
- for(int i = 0; i < component.getConnectedWireArraysCount(); i ++)\r
- {\r
- Point connectionPoint = component.getWireArrayConnectionPoint(i);\r
- if(connectionPoint != null)\r
- tgc.fillOval(connectionPoint.x - 1, connectionPoint.y - 1, 2, 2);\r
- }\r
- }\r
- private void mouseDown(Event e)\r
- {\r
- if(e.button == 1)\r
- {\r
- Point click = canvas.displayToWorldCoords(e.x, e.y);\r
- for(BasicGUIComponent component : components)\r
- if(component.getBounds().translate(componentPositions.get(component)).contains(click))\r
- {\r
- if(component.clicked(click.x, click.y))\r
- canvas.redraw();\r
- break;\r
- }\r
- }\r
- }\r
-\r
- public void run()\r
- {\r
- AtomicBoolean running = new AtomicBoolean(true);\r
- Thread simulationThread = new Thread(() ->\r
- {\r
- while(running.get())\r
- {\r
- //always execute to keep timeline from "hanging behind" for too long\r
- Simulation.TIMELINE.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10);\r
- long sleepTime;\r
- if(Simulation.TIMELINE.hasNext())\r
- {\r
- sleepTime = Simulation.TIMELINE.nextEventTime() - System.currentTimeMillis();\r
- } else\r
- sleepTime = 100;\r
- try\r
- {\r
- if(sleepTime > 0)\r
- Thread.sleep(sleepTime);\r
- } catch(InterruptedException e)\r
- {} //it is normal execution flow to be interrupted\r
- }\r
- });\r
- simulationThread.start();\r
- Simulation.TIMELINE.addEventAddedListener(event ->\r
- {\r
- if(event.getTiming() >= System.currentTimeMillis() / (double) 1)\r
- simulationThread.interrupt();\r
- });\r
-\r
- shell.open();\r
- while(!shell.isDisposed())\r
- if(!display.readAndDispatch())\r
- display.sleep();\r
- running.set(false);\r
- simulationThread.interrupt();\r
- }\r
-\r
- public static void main(String[] args)\r
- {\r
- new LogicUI().run();\r
- }\r
-}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public interface BasicGUIComponent\r
+{\r
+ /**\r
+ * Render this component to the given gc, at coordinates (0, 0).\r
+ */\r
+ public void render(GeneralGC gc);\r
+ /**\r
+ * Returns the bounds of this component.\r
+ * Used for calculating which component is clicked.\r
+ */\r
+ public Rectangle getBounds();\r
+ /**\r
+ * Called when this component is clicked. Relative coordinates of the click are given.\r
+ * Returns true if this component has to be redrawn.\r
+ */\r
+ public default boolean clicked(double x, double y)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ //TODO this code will be replaced by code in BasicComponent.\r
+ /**\r
+ * Returns how many wire arrays are connected to this component.\r
+ * (Connections are static - they can't be removed and no new ones can be added)\r
+ */\r
+ public int getConnectedWireArraysCount();\r
+ /**\r
+ * Returns the n-th wire array connected to this component.\r
+ */\r
+ public WireArray getConnectedWireArray(int connectionIndex);\r
+ /**\r
+ * Returns relative coordinates where the n-th wire array is connected to this component.\r
+ */\r
+ public Point getWireArrayConnectionPoint(int connectionIndex);\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.components.gates.AndGate;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class GUIAndGate extends AndGate implements BasicGUIComponent\r
+{\r
+ private static final String LABEL = "&";\r
+\r
+ private final int inputCount;\r
+ private final double height;\r
+ private final List<WireArray> connectedWireArrays;\r
+ private final List<Point> wireArrayConnectionPoints;\r
+\r
+ public GUIAndGate(int processTime, WireArray out, WireArray... in)\r
+ {\r
+ super(processTime, out, in);\r
+\r
+ List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
+ List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
+\r
+ this.inputCount = in.length;\r
+ this.height = inputCount * 10;\r
+\r
+ {\r
+ connectedWireArraysModifiable.addAll(Arrays.asList(in));\r
+ double inputHeight = 5;\r
+ for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
+ wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
+ }\r
+\r
+ connectedWireArraysModifiable.add(out);\r
+ wireArrayConnectionPointsModifiable.add(new Point(20, height / 2));\r
+\r
+ this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
+ this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 20, height);\r
+ }\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ gc.drawRectangle(0, 0, 17, height);\r
+ Font oldFont = gc.getFont();\r
+ Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle());\r
+ gc.setFont(labelFont);\r
+ Point textExtent = gc.textExtent(LABEL);\r
+ gc.drawText(LABEL, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true);\r
+ gc.setFont(oldFont);\r
+ gc.drawOval(17, height / 2 - 1.5, 3, 3);\r
+ }\r
+\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return connectedWireArrays.size();\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return connectedWireArrays.get(connectionIndex);\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionI)\r
+ {\r
+ return wireArrayConnectionPoints.get(connectionI);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.components.ManualSwitch;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class GUIManualSwitch extends ManualSwitch implements BasicGUIComponent\r
+{\r
+ private final List<WireArray> connectedWireArrays;\r
+ private final List<Point> wireArrayConnectionPoints;\r
+\r
+ public GUIManualSwitch(WireArray output)\r
+ {\r
+ super(output);\r
+\r
+ List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
+ List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
+\r
+ connectedWireArraysModifiable.add(output);\r
+ wireArrayConnectionPointsModifiable.add(new Point(20, 7.5));\r
+\r
+ this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
+ this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 20, 15);\r
+ }\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ gc.drawRectangle(0, 0, 20, 15);\r
+ String label = isOn() ? "ON" : "OFF";\r
+ Font oldFont = gc.getFont();\r
+ Font labelFont = new Font(oldFont.getName(), 6, oldFont.getStyle());\r
+ gc.setFont(labelFont);\r
+ Point textExtent = gc.textExtent(label);\r
+ gc.drawText(label, 10 - textExtent.x / 2, 7.5 - textExtent.y / 2, true);\r
+ gc.setFont(oldFont);\r
+ }\r
+ @Override\r
+ public boolean clicked(double x, double y)\r
+ {\r
+ toggle();\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return connectedWireArrays.size();\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return connectedWireArrays.get(connectionIndex);\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionI)\r
+ {\r
+ return wireArrayConnectionPoints.get(connectionI);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.components.Merger;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class GUIMerger extends Merger implements BasicGUIComponent\r
+{\r
+ private final int inputCount;\r
+ private final double height;\r
+ private final List<WireArray> connectedWireArrays;\r
+ private final List<Point> wireArrayConnectionPoints;\r
+\r
+ public GUIMerger(WireArray union, WireArray... inputs)\r
+ {\r
+ super(union, inputs);\r
+\r
+ List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
+ List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
+\r
+ this.inputCount = inputs.length;\r
+ this.height = (inputCount - 1) * 10;\r
+\r
+ {\r
+ connectedWireArraysModifiable.addAll(Arrays.asList(inputs));\r
+ double inputHeight = 0;\r
+ for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
+ wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
+ }\r
+\r
+ connectedWireArraysModifiable.add(union);\r
+ wireArrayConnectionPointsModifiable.add(new Point(20, height / 2));\r
+\r
+ this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
+ this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 20, height);\r
+ }\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ double inputHeight = 0;\r
+ for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
+ gc.drawLine(0, inputHeight, 10, inputHeight);\r
+ gc.drawLine(10, 0, 10, height);\r
+ gc.drawLine(10, height / 2, 20, height / 2);\r
+ }\r
+\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return connectedWireArrays.size();\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return connectedWireArrays.get(connectionIndex);\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionI)\r
+ {\r
+ return wireArrayConnectionPoints.get(connectionI);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.components.Mux;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class GUIMux extends Mux implements BasicGUIComponent\r
+{\r
+ private final double height;\r
+ private final List<WireArray> connectedWireArrays;\r
+ private final List<Point> wireArrayConnectionPoints;\r
+\r
+ public GUIMux(int processTime, WireArray out, WireArray select, WireArray... inputs)\r
+ {\r
+ super(processTime, out, select, inputs);\r
+\r
+ double height = inputs.length * 5;\r
+ if(height < 10)\r
+ height = 10;\r
+ this.height = height;\r
+\r
+ List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
+ List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
+\r
+ connectedWireArraysModifiable.add(out);\r
+ wireArrayConnectionPointsModifiable.add(new Point(20, 10 + height / 2));\r
+\r
+ connectedWireArraysModifiable.add(select);\r
+ wireArrayConnectionPointsModifiable.add(new Point(10, 5));\r
+\r
+ {\r
+ connectedWireArraysModifiable.addAll(Arrays.asList(inputs));\r
+ double inputHeightIncrement = (height + 20) / inputs.length;\r
+ double inputHeight = inputHeightIncrement / 2;\r
+ for(int i = 0; i < inputs.length; i ++, inputHeight += inputHeightIncrement)\r
+ wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
+ }\r
+\r
+ this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
+ this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 20, height + 20);\r
+ }\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ gc.drawPolygon(new double[] {\r
+ 0, 0,\r
+ 20, 10,\r
+ 20, height + 10,\r
+ 0, height + 20});\r
+ }\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return connectedWireArrays.size();\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return connectedWireArrays.get(connectionIndex);\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionI)\r
+ {\r
+ return wireArrayConnectionPoints.get(connectionI);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.components.gates.NotGate;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class GUINotGate extends NotGate implements BasicGUIComponent\r
+{\r
+ private static final String LABEL = "\u22651";//>=1\r
+\r
+ private final List<WireArray> connectedWireArrays;\r
+ private final List<Point> wireArrayConnectionPoints;\r
+\r
+ public GUINotGate(int processTime, WireArray in, WireArray out)\r
+ {\r
+ super(processTime, in, out);\r
+\r
+ List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
+ List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
+\r
+ connectedWireArraysModifiable.add(in);\r
+ wireArrayConnectionPointsModifiable.add(new Point(0, 5));\r
+\r
+ connectedWireArraysModifiable.add(out);\r
+ wireArrayConnectionPointsModifiable.add(new Point(20, 5));\r
+\r
+ this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
+ this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 20, 10);\r
+ }\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ gc.drawRectangle(0, 0, 17, 10);\r
+ Font oldFont = gc.getFont();\r
+ Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle());\r
+ gc.setFont(labelFont);\r
+ Point textExtent = gc.textExtent(LABEL);\r
+ gc.drawText(LABEL, 8.5 - textExtent.x / 2, 5 - textExtent.y / 2, true);\r
+ gc.setFont(oldFont);\r
+ gc.drawOval(17, 3.5, 3, 3);\r
+ }\r
+\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return connectedWireArrays.size();\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return connectedWireArrays.get(connectionIndex);\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionI)\r
+ {\r
+ return wireArrayConnectionPoints.get(connectionI);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.components.gates.OrGate;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class GUIOrGate extends OrGate implements BasicGUIComponent\r
+{\r
+ private static final String LABEL = "\u22651";//>=1\r
+\r
+ private final int inputCount;\r
+ private final double height;\r
+ private final List<WireArray> connectedWireArrays;\r
+ private final List<Point> wireArrayConnectionPoints;\r
+\r
+ public GUIOrGate(int processTime, WireArray out, WireArray... in)\r
+ {\r
+ super(processTime, out, in);\r
+\r
+ List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
+ List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
+\r
+ this.inputCount = in.length;\r
+ this.height = inputCount * 10;\r
+\r
+ {\r
+ connectedWireArraysModifiable.addAll(Arrays.asList(in));\r
+ double inputHeight = 5;\r
+ for(int i = 0; i < inputCount; i ++, inputHeight += 10)\r
+ wireArrayConnectionPointsModifiable.add(new Point(0, inputHeight));\r
+ }\r
+\r
+ connectedWireArraysModifiable.add(out);\r
+ wireArrayConnectionPointsModifiable.add(new Point(20, height / 2));\r
+\r
+ this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
+ this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 20, height);\r
+ }\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ gc.drawRectangle(0, 0, 17, height);\r
+ Font oldFont = gc.getFont();\r
+ Font labelFont = new Font(oldFont.getName(), 5, oldFont.getStyle());\r
+ gc.setFont(labelFont);\r
+ Point textExtent = gc.textExtent(LABEL);\r
+ gc.drawText(LABEL, 8.5 - textExtent.x / 2, (height - textExtent.y) / 2, true);\r
+ gc.setFont(oldFont);\r
+ gc.drawOval(17, height / 2 - 1.5, 3, 3);\r
+ }\r
+\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return connectedWireArrays.size();\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return connectedWireArrays.get(connectionIndex);\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionI)\r
+ {\r
+ return wireArrayConnectionPoints.get(connectionI);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.components;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.components.Splitter;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class GUISplitter extends Splitter implements BasicGUIComponent\r
+{\r
+ private final int outputCount;\r
+ private final double height;\r
+ private final List<WireArray> connectedWireArrays;\r
+ private final List<Point> wireArrayConnectionPoints;\r
+\r
+ public GUISplitter(WireArray input, WireArray... outputs)\r
+ {\r
+ super(input, outputs);\r
+\r
+ List<WireArray> connectedWireArraysModifiable = new ArrayList<>();\r
+ List<Point> wireArrayConnectionPointsModifiable = new ArrayList<>();\r
+\r
+ this.outputCount = outputs.length;\r
+ this.height = (outputCount - 1) * 10;\r
+\r
+ connectedWireArraysModifiable.add(input);\r
+ wireArrayConnectionPointsModifiable.add(new Point(0, height / 2));\r
+\r
+ {\r
+ connectedWireArraysModifiable.addAll(Arrays.asList(outputs));\r
+ double outputHeight = 0;\r
+ for(int i = 0; i < outputCount; i ++, outputHeight += 10)\r
+ wireArrayConnectionPointsModifiable.add(new Point(20, outputHeight));\r
+ }\r
+\r
+ this.connectedWireArrays = Collections.unmodifiableList(connectedWireArraysModifiable);\r
+ this.wireArrayConnectionPoints = Collections.unmodifiableList(wireArrayConnectionPointsModifiable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 20, height);\r
+ }\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ gc.drawLine(0, height / 2, 10, height / 2);\r
+ gc.drawLine(10, 0, 10, height);\r
+ double outputHeight = 0;\r
+ for(int i = 0; i < outputCount; i ++, outputHeight += 10)\r
+ gc.drawLine(10, outputHeight, 20, outputHeight);\r
+ }\r
+\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return connectedWireArrays.size();\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return connectedWireArrays.get(connectionIndex);\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionI)\r
+ {\r
+ return wireArrayConnectionPoints.get(connectionI);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.examples;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Shell;\r
+\r
+import era.mi.gui.components.BasicGUIComponent;\r
+import era.mi.gui.components.GUIManualSwitch;\r
+import era.mi.gui.components.GUINotGate;\r
+import era.mi.gui.components.GUIOrGate;\r
+import era.mi.gui.wires.GUIWire;\r
+import era.mi.gui.wires.WireConnectionPoint;\r
+import era.mi.logic.Simulation;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.gcs.TranslatedGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas;\r
+import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay;\r
+import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput;\r
+\r
+public class LogicUI\r
+{\r
+ private static final int WIRE_DELAY = 40;\r
+ private static final int OR_DELAY = 100;\r
+ private static final int NOT_DELAY = 100;\r
+ private final Display display;\r
+ private final Shell shell;\r
+ private final ZoomableCanvas canvas;\r
+ private final Set<BasicGUIComponent> components;\r
+ private final Map<BasicGUIComponent, Point> componentPositions;\r
+ private final Set<GUIWire> wires;\r
+\r
+ public LogicUI()\r
+ {\r
+ display = new Display();\r
+ shell = new Shell(display);\r
+ shell.setLayout(new FillLayout());\r
+ canvas = new ZoomableCanvas(shell, SWT.NONE);\r
+\r
+ components = new HashSet<>();\r
+ componentPositions = new HashMap<>();\r
+ wires = new HashSet<>();\r
+ initComponents();\r
+\r
+ canvas.addZoomedRenderer(gc -> components.forEach(c -> drawComponent(gc, c)));\r
+ canvas.addZoomedRenderer(gc -> wires.forEach(w -> w.render(gc)));\r
+ ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(canvas);\r
+ userInput.buttonDrag = 3;\r
+ userInput.buttonZoom = 2;\r
+ userInput.enableUserInput();\r
+ new ZoomableCanvasOverlay(canvas, null).enableScale();\r
+ canvas.addListener(SWT.MouseDown, this::mouseDown);\r
+ }\r
+ private void initComponents()\r
+ {\r
+ Simulation.TIMELINE.reset();\r
+ WireArray r = new WireArray(1, WIRE_DELAY);\r
+ WireArray s = new WireArray(1, WIRE_DELAY);\r
+ WireArray t2 = new WireArray(1, WIRE_DELAY);\r
+ WireArray t1 = new WireArray(1, WIRE_DELAY);\r
+ WireArray q = new WireArray(1, WIRE_DELAY);\r
+ WireArray nq = new WireArray(1, WIRE_DELAY);\r
+\r
+ GUIManualSwitch rIn = addComponent(new GUIManualSwitch(r), 100, 100);\r
+ GUIManualSwitch sIn = addComponent(new GUIManualSwitch(s), 100, 200);\r
+ GUIOrGate or1 = addComponent(new GUIOrGate(OR_DELAY, t1, r, nq), 160, 102.5);\r
+ GUIOrGate or2 = addComponent(new GUIOrGate(OR_DELAY, t2, q, s), 160, 192.5);\r
+ GUINotGate not1 = addComponent(new GUINotGate(NOT_DELAY, t1, q), 200, 107.5);\r
+ GUINotGate not2 = addComponent(new GUINotGate(NOT_DELAY, t2, nq), 200, 197.5);\r
+\r
+ WireConnectionPoint p1 = addComponent(new WireConnectionPoint(q, 2), 250, 112.5);\r
+ WireConnectionPoint p2 = addComponent(new WireConnectionPoint(nq, 2), 250, 202.5);\r
+\r
+ addWire(rIn, 0, or1, 0);\r
+ addWire(sIn, 0, or2, 1);\r
+ addWire(or1, 2, not1, 0);\r
+ addWire(or2, 2, not2, 0);\r
+ addWire(not1, 1, p1, 0);\r
+ addWire(not2, 1, p2, 0);\r
+ addWire(p1, 1, or2, 0, new Point(250, 130), new Point(140, 185), new Point(140, 197.5));\r
+ addWire(p2, 1, or1, 1, new Point(250, 185), new Point(140, 130), new Point(140, 117.5));\r
+ }\r
+ /**\r
+ * Returns the given component for convenience.\r
+ */\r
+ private <C extends BasicGUIComponent> C addComponent(C component, double x, double y)\r
+ {\r
+ components.add(component);\r
+ componentPositions.put(component, new Point(x, y));\r
+ return component;\r
+ }\r
+ private void addWire(BasicGUIComponent component1, int component1ConnectionIndex, BasicGUIComponent component2, int component2ConnectionIndex, Point... path)\r
+ {\r
+ wires.add(new GUIWire(canvas::redrawThreadsafe, component1, component1ConnectionIndex, componentPositions.get(component1), component2, component2ConnectionIndex, componentPositions.get(component2), path));\r
+ }\r
+ private void drawComponent(GeneralGC gc, BasicGUIComponent component)\r
+ {\r
+ TranslatedGC tgc = new TranslatedGC(gc, componentPositions.get(component));\r
+ component.render(tgc);\r
+ tgc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));\r
+ for(int i = 0; i < component.getConnectedWireArraysCount(); i ++)\r
+ {\r
+ Point connectionPoint = component.getWireArrayConnectionPoint(i);\r
+ if(connectionPoint != null)\r
+ tgc.fillOval(connectionPoint.x - 1, connectionPoint.y - 1, 2, 2);\r
+ }\r
+ }\r
+ private void mouseDown(Event e)\r
+ {\r
+ if(e.button == 1)\r
+ {\r
+ Point click = canvas.displayToWorldCoords(e.x, e.y);\r
+ for(BasicGUIComponent component : components)\r
+ if(component.getBounds().translate(componentPositions.get(component)).contains(click))\r
+ {\r
+ if(component.clicked(click.x, click.y))\r
+ canvas.redraw();\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ public void run()\r
+ {\r
+ AtomicBoolean running = new AtomicBoolean(true);\r
+ Thread simulationThread = new Thread(() ->\r
+ {\r
+ while(running.get())\r
+ {\r
+ //always execute to keep timeline from "hanging behind" for too long\r
+ Simulation.TIMELINE.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10);\r
+ long sleepTime;\r
+ if(Simulation.TIMELINE.hasNext())\r
+ {\r
+ sleepTime = Simulation.TIMELINE.nextEventTime() - System.currentTimeMillis();\r
+ } else\r
+ sleepTime = 100;\r
+ try\r
+ {\r
+ if(sleepTime > 0)\r
+ Thread.sleep(sleepTime);\r
+ } catch(InterruptedException e)\r
+ {} //it is normal execution flow to be interrupted\r
+ }\r
+ });\r
+ simulationThread.start();\r
+ Simulation.TIMELINE.addEventAddedListener(event ->\r
+ {\r
+ if(event.getTiming() >= System.currentTimeMillis() / (double) 1)\r
+ simulationThread.interrupt();\r
+ });\r
+\r
+ shell.open();\r
+ while(!shell.isDisposed())\r
+ if(!display.readAndDispatch())\r
+ display.sleep();\r
+ running.set(false);\r
+ simulationThread.interrupt();\r
+ }\r
+\r
+ public static void main(String[] args)\r
+ {\r
+ new LogicUI().run();\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.wires;\r
+\r
+import java.util.Objects;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Color;\r
+\r
+import era.mi.gui.components.BasicGUIComponent;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+\r
+public class GUIWire\r
+{\r
+ private final WireArray wa;\r
+ private final double[] path;\r
+\r
+ public GUIWire(Runnable redraw, BasicGUIComponent component1, int component1ConnectionIndex, Point component1Pos, BasicGUIComponent component2, int component2ConnectionIndex, Point component2Pos, Point... path)\r
+ {\r
+ this.wa = component1.getConnectedWireArray(component1ConnectionIndex);\r
+ if(!Objects.equals(wa, component2.getConnectedWireArray(component2ConnectionIndex)))\r
+ throw new IllegalArgumentException("Given connection points are not connected!");\r
+ this.path = new double[path.length * 2 + 4];\r
+ Point component1ConnectionPoint = component1.getWireArrayConnectionPoint(component1ConnectionIndex);\r
+ this.path[0] = component1Pos.x + component1ConnectionPoint.x;\r
+ this.path[1] = component1Pos.y + component1ConnectionPoint.y;\r
+ for(int srcI = 0, dstI = 2; srcI < path.length; srcI ++, dstI += 2)\r
+ {\r
+ this.path[dstI + 0] = path[srcI].x;\r
+ this.path[dstI + 1] = path[srcI].y;\r
+ }\r
+ Point component2ConnectionPoint = component2.getWireArrayConnectionPoint(component2ConnectionIndex);\r
+ this.path[this.path.length - 2] = component2Pos.x + component2ConnectionPoint.x;\r
+ this.path[this.path.length - 1] = component2Pos.y + component2ConnectionPoint.y;\r
+\r
+ wa.addObserver((initiator, oldValues) -> redraw.run());\r
+ }\r
+\r
+ public void render(GeneralGC gc)\r
+ {\r
+ Color oldFG = gc.getForeground();\r
+ if(wa.length == 1)\r
+ {\r
+ int fgColorConstant;\r
+ switch(wa.getValue())\r
+ {\r
+ case ONE:\r
+ fgColorConstant = SWT.COLOR_GREEN;\r
+ break;\r
+ case ZERO:\r
+ fgColorConstant = SWT.COLOR_BLUE;\r
+ break;\r
+ case U:\r
+ case X:\r
+ case Z:\r
+ fgColorConstant = SWT.COLOR_RED;\r
+ break;\r
+ default:\r
+ throw new IllegalArgumentException("Unknown enum constant: " + wa.getValue());\r
+ }\r
+ gc.setForeground(gc.getDevice().getSystemColor(fgColorConstant));\r
+ }\r
+ gc.drawPolyline(path);\r
+ gc.setForeground(oldFG);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package era.mi.gui.wires;\r
+\r
+import org.eclipse.swt.graphics.Color;\r
+\r
+import era.mi.gui.components.BasicGUIComponent;\r
+import era.mi.logic.wires.WireArray;\r
+import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+\r
+public class WireConnectionPoint implements BasicGUIComponent\r
+{\r
+ private final WireArray wa;\r
+ private final int wiresCrossing;\r
+\r
+ public WireConnectionPoint(WireArray wa, int wiresCrossing)\r
+ {\r
+ this.wa = wa;\r
+ this.wiresCrossing = wiresCrossing;\r
+ }\r
+\r
+ @Override\r
+ public void render(GeneralGC gc)\r
+ {\r
+ Color oldBG = gc.getBackground();\r
+ Color fg = gc.getForeground();\r
+ gc.setBackground(fg);\r
+ gc.fillOval(-2, -2, 4, 4);\r
+ gc.setBackground(oldBG);\r
+ }\r
+ @Override\r
+ public Rectangle getBounds()\r
+ {\r
+ return new Rectangle(0, 0, 0, 0);\r
+ }\r
+ @Override\r
+ public int getConnectedWireArraysCount()\r
+ {\r
+ return wiresCrossing;\r
+ }\r
+ @Override\r
+ public WireArray getConnectedWireArray(int connectionIndex)\r
+ {\r
+ return wa;\r
+ }\r
+ @Override\r
+ public Point getWireArrayConnectionPoint(int connectionIndex)\r
+ {\r
+ return new Point(0, 0);\r
+ }\r
+}
\ No newline at end of file
+++ /dev/null
-package era.mi.wires.gui;\r
-\r
-import java.util.Objects;\r
-\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.graphics.Color;\r
-\r
-import era.mi.components.gui.BasicGUIComponent;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-\r
-public class GUIWire\r
-{\r
- private final WireArray wa;\r
- private final double[] path;\r
-\r
- public GUIWire(Runnable redraw, BasicGUIComponent component1, int component1ConnectionIndex, Point component1Pos, BasicGUIComponent component2, int component2ConnectionIndex, Point component2Pos, Point... path)\r
- {\r
- this.wa = component1.getConnectedWireArray(component1ConnectionIndex);\r
- if(!Objects.equals(wa, component2.getConnectedWireArray(component2ConnectionIndex)))\r
- throw new IllegalArgumentException("Given connection points are not connected!");\r
- this.path = new double[path.length * 2 + 4];\r
- Point component1ConnectionPoint = component1.getWireArrayConnectionPoint(component1ConnectionIndex);\r
- this.path[0] = component1Pos.x + component1ConnectionPoint.x;\r
- this.path[1] = component1Pos.y + component1ConnectionPoint.y;\r
- for(int srcI = 0, dstI = 2; srcI < path.length; srcI ++, dstI += 2)\r
- {\r
- this.path[dstI + 0] = path[srcI].x;\r
- this.path[dstI + 1] = path[srcI].y;\r
- }\r
- Point component2ConnectionPoint = component2.getWireArrayConnectionPoint(component2ConnectionIndex);\r
- this.path[this.path.length - 2] = component2Pos.x + component2ConnectionPoint.x;\r
- this.path[this.path.length - 1] = component2Pos.y + component2ConnectionPoint.y;\r
-\r
- wa.addObserver((initiator, oldValues) -> redraw.run());\r
- }\r
-\r
- public void render(GeneralGC gc)\r
- {\r
- Color oldFG = gc.getForeground();\r
- if(wa.length == 1)\r
- {\r
- int fgColorConstant;\r
- switch(wa.getValue())\r
- {\r
- case ONE:\r
- fgColorConstant = SWT.COLOR_GREEN;\r
- break;\r
- case ZERO:\r
- fgColorConstant = SWT.COLOR_BLUE;\r
- break;\r
- case U:\r
- case X:\r
- case Z:\r
- fgColorConstant = SWT.COLOR_RED;\r
- break;\r
- default:\r
- throw new IllegalArgumentException("Unknown enum constant: " + wa.getValue());\r
- }\r
- gc.setForeground(gc.getDevice().getSystemColor(fgColorConstant));\r
- }\r
- gc.drawPolyline(path);\r
- gc.setForeground(oldFG);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-package era.mi.wires.gui;\r
-\r
-import org.eclipse.swt.graphics.Color;\r
-\r
-import era.mi.components.gui.BasicGUIComponent;\r
-import era.mi.logic.wires.WireArray;\r
-import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
-\r
-public class WireConnectionPoint implements BasicGUIComponent\r
-{\r
- private final WireArray wa;\r
- private final int wiresCrossing;\r
-\r
- public WireConnectionPoint(WireArray wa, int wiresCrossing)\r
- {\r
- this.wa = wa;\r
- this.wiresCrossing = wiresCrossing;\r
- }\r
-\r
- @Override\r
- public void render(GeneralGC gc)\r
- {\r
- Color oldBG = gc.getBackground();\r
- Color fg = gc.getForeground();\r
- gc.setBackground(fg);\r
- gc.fillOval(-2, -2, 4, 4);\r
- gc.setBackground(oldBG);\r
- }\r
- @Override\r
- public Rectangle getBounds()\r
- {\r
- return new Rectangle(0, 0, 0, 0);\r
- }\r
- @Override\r
- public int getConnectedWireArraysCount()\r
- {\r
- return wiresCrossing;\r
- }\r
- @Override\r
- public WireArray getConnectedWireArray(int connectionIndex)\r
- {\r
- return wa;\r
- }\r
- @Override\r
- public Point getWireArrayConnectionPoint(int connectionIndex)\r
- {\r
- return new Point(0, 0);\r
- }\r
-}
\ No newline at end of file