From 7e1cc7da2ee89b683ecb403b94605558092ce95c Mon Sep 17 00:00:00 2001 From: hneemann Date: Sun, 13 Mar 2016 19:56:35 +0100 Subject: [PATCH] first design of gui --- pom.xml | 12 ++-- .../java/de/neemann/digital/gui/Main.java | 39 +++++++++++ .../gui/components/CircuitComponent.java | 27 ++++++++ .../digital/gui/draw/graphics/Graphic.java | 15 +++++ .../gui/draw/graphics/GraphicSwing.java | 40 ++++++++++++ .../gui/draw/graphics/GraphicTransform.java | 44 +++++++++++++ .../digital/gui/draw/graphics/Polygon.java | 46 +++++++++++++ .../digital/gui/draw/graphics/Style.java | 19 ++++++ .../digital/gui/draw/graphics/Vector.java | 51 +++++++++++++++ .../digital/gui/draw/parts/Circuit.java | 32 +++++++++ .../digital/gui/draw/parts/Moveable.java | 10 +++ .../neemann/digital/gui/draw/parts/Part.java | 51 +++++++++++++++ .../neemann/digital/gui/draw/parts/Pin.java | 20 ++++++ .../neemann/digital/gui/draw/parts/Wire.java | 26 ++++++++ .../digital/gui/draw/shapes/Drawable.java | 10 +++ .../digital/gui/draw/shapes/GenericShape.java | 65 +++++++++++++++++++ .../digital/gui/draw/shapes/Shape.java | 12 ++++ 17 files changed, 513 insertions(+), 6 deletions(-) create mode 100644 src/main/java/de/neemann/digital/gui/Main.java create mode 100644 src/main/java/de/neemann/digital/gui/components/CircuitComponent.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/graphics/Graphic.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/graphics/GraphicSwing.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/graphics/GraphicTransform.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/graphics/Polygon.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/graphics/Style.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/graphics/Vector.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/parts/Circuit.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/parts/Moveable.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/parts/Part.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/parts/Pin.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/parts/Wire.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/shapes/Drawable.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/shapes/GenericShape.java create mode 100644 src/main/java/de/neemann/digital/gui/draw/shapes/Shape.java diff --git a/pom.xml b/pom.xml index f91143d0c..58503ddf5 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ - org.apache.maven.plugins @@ -128,7 +128,7 @@ true - de.neemann.assembler.gui.Main + de.neemann.digital.gui.Main ${buildNumber} @@ -182,7 +182,7 @@ - + diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java new file mode 100644 index 000000000..e73d0c24a --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -0,0 +1,39 @@ +package de.neemann.digital.gui; + +import de.neemann.digital.gui.components.CircuitComponent; +import de.neemann.digital.gui.draw.graphics.Vector; +import de.neemann.digital.gui.draw.parts.Circuit; +import de.neemann.digital.gui.draw.parts.Part; +import de.neemann.digital.gui.draw.shapes.GenericShape; + +import javax.swing.*; +import java.awt.*; + +/** + * @author hneemann + */ +public class Main extends JFrame { + private final CircuitComponent cr; + + public Main() { + super("Digital"); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + + cr = new CircuitComponent(createDemoCircuit()); + getContentPane().add(cr); + + setPreferredSize(new Dimension(800, 600)); + pack(); + setLocationRelativeTo(null); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> new Main().setVisible(true)); + } + + private Circuit createDemoCircuit() { + Circuit cr = new Circuit(); + cr.add(new Part(new GenericShape("&", 2, 1)).setPos(new Vector(10, 10))); + return cr; + } +} diff --git a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java new file mode 100644 index 000000000..110595ec1 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -0,0 +1,27 @@ +package de.neemann.digital.gui.components; + +import de.neemann.digital.gui.draw.graphics.GraphicSwing; +import de.neemann.digital.gui.draw.parts.Circuit; + +import javax.swing.*; +import java.awt.*; + +/** + * @author hneemann + */ +public class CircuitComponent extends JComponent { + + private final Circuit circuit; + + public CircuitComponent(Circuit circuit) { + this.circuit = circuit; + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + GraphicSwing gr = new GraphicSwing((Graphics2D) g); + circuit.drawTo(gr); + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/graphics/Graphic.java b/src/main/java/de/neemann/digital/gui/draw/graphics/Graphic.java new file mode 100644 index 000000000..d65f5603b --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/graphics/Graphic.java @@ -0,0 +1,15 @@ +package de.neemann.digital.gui.draw.graphics; + +/** + * @author hneemann + */ +public interface Graphic { + + void drawLine(Vector p1, Vector p2, Style style); + + void drawPolygon(Polygon p, Style style); + + void drawCircle(Vector p1, Vector p2, Style style); + + void drawText(Vector p1, Vector p2, String text); +} diff --git a/src/main/java/de/neemann/digital/gui/draw/graphics/GraphicSwing.java b/src/main/java/de/neemann/digital/gui/draw/graphics/GraphicSwing.java new file mode 100644 index 000000000..3766ae28f --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/graphics/GraphicSwing.java @@ -0,0 +1,40 @@ +package de.neemann.digital.gui.draw.graphics; + +import java.awt.*; + +/** + * @author hneemann + */ +public class GraphicSwing implements Graphic { + + private final Graphics2D gr; + + public GraphicSwing(Graphics2D gr) { + this.gr = gr; + } + + @Override + public void drawLine(Vector p1, Vector p2, Style style) { + gr.drawLine(p1.x, p1.y, p2.x, p2.y); + } + + @Override + public void drawPolygon(Polygon p, Style style) { + java.awt.Polygon poly = new java.awt.Polygon(); + for (Vector v : p.getPoints()) + poly.addPoint(v.x, v.y); + gr.draw(poly); + } + + @Override + public void drawCircle(Vector p1, Vector p2, Style style) { + Vector p = Vector.min(p1, p2); + Vector w = Vector.width(p1, p2); + gr.drawOval(p.x, p.y, w.x, w.y); + } + + @Override + public void drawText(Vector p1, Vector p2, String text) { + gr.drawString(text, p1.x, p1.y); + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/graphics/GraphicTransform.java b/src/main/java/de/neemann/digital/gui/draw/graphics/GraphicTransform.java new file mode 100644 index 000000000..020994691 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/graphics/GraphicTransform.java @@ -0,0 +1,44 @@ +package de.neemann.digital.gui.draw.graphics; + +/** + * @author hneemann + */ +public class GraphicTransform implements Graphic { + + private final Graphic parent; + private final Vector pos; + private final int rotate; + + public GraphicTransform(Graphic parent, Vector pos, int rotate) { + this.parent = parent; + this.pos = pos; + this.rotate = rotate; + } + + @Override + public void drawLine(Vector p1, Vector p2, Style style) { + parent.drawLine(transform(p1), transform(p2), style); + } + + @Override + public void drawPolygon(Polygon p, Style style) { + Polygon pp = new Polygon(p.isClosed()); + for (Vector v : p.getPoints()) + pp.add(transform(v)); + parent.drawPolygon(pp, style); + } + + @Override + public void drawCircle(Vector p1, Vector p2, Style style) { + parent.drawCircle(transform(p1), transform(p2), style); + } + + @Override + public void drawText(Vector p1, Vector p2, String text) { + parent.drawText(transform(p1), transform(p2), text); + } + + public Vector transform(Vector v) { + return v.add(pos); + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/graphics/Polygon.java b/src/main/java/de/neemann/digital/gui/draw/graphics/Polygon.java new file mode 100644 index 000000000..ce6903225 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/graphics/Polygon.java @@ -0,0 +1,46 @@ +package de.neemann.digital.gui.draw.graphics; + +import java.util.ArrayList; + +/** + * @author hneemann + */ +public class Polygon { + + private ArrayList points; + private boolean closed; + + public Polygon() { + this(new ArrayList<>(), true); + } + + public Polygon(boolean closed) { + this(new ArrayList<>(), closed); + } + + public Polygon(ArrayList points, boolean closed) { + this.points = points; + this.closed = closed; + } + + public boolean isClosed() { + return closed; + } + + public void setClosed(boolean closed) { + this.closed = closed; + } + + public Polygon add(int x, int y) { + return add(new Vector(x, y)); + } + + public Polygon add(Vector p) { + points.add(p); + return this; + } + + public ArrayList getPoints() { + return points; + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/graphics/Style.java b/src/main/java/de/neemann/digital/gui/draw/graphics/Style.java new file mode 100644 index 000000000..c8b595005 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/graphics/Style.java @@ -0,0 +1,19 @@ +package de.neemann.digital.gui.draw.graphics; + +/** + * @author hneemann + */ +public class Style { + public static final Style NORMAL = new Style(1); + public static final Style WIRE = new Style(2); + + private final int thickness; + + private Style(int thickness) { + this.thickness = thickness; + } + + public int getThickness() { + return thickness; + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/graphics/Vector.java b/src/main/java/de/neemann/digital/gui/draw/graphics/Vector.java new file mode 100644 index 000000000..c6a10c79f --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/graphics/Vector.java @@ -0,0 +1,51 @@ +package de.neemann.digital.gui.draw.graphics; + +/** + * @author hneemann + */ +public class Vector { + + public final int x; + public final int y; + + public Vector(int x, int y) { + this.x = x; + this.y = y; + } + + public static Vector min(Vector... p) { + int x = p[0].x; + int y = p[0].y; + for (int i = 1; i < p.length; i++) { + if (p[i].x < x) x = p[i].x; + if (p[i].y < y) y = p[i].y; + } + return new Vector(x, y); + } + + public static Vector width(Vector... p) { + int x1 = p[0].x; + int y1 = p[0].y; + int x2 = x1; + int y2 = y1; + for (int i = 1; i < p.length; i++) { + if (p[i].x < x1) x1 = p[i].x; + if (p[i].y < y1) y1 = p[i].y; + if (p[i].x > x2) x2 = p[i].x; + if (p[i].y > y2) y2 = p[i].y; + } + return new Vector(x2 - x1, y2 - y1); + } + + public Vector add(Vector a) { + return new Vector(x + a.x, y + a.y); + } + + public Vector add(int x, int y) { + return new Vector(this.x + x, this.y + y); + } + + public Vector sub(Vector a) { + return new Vector(x - a.x, y - a.y); + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/parts/Circuit.java b/src/main/java/de/neemann/digital/gui/draw/parts/Circuit.java new file mode 100644 index 000000000..10f0d102c --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/parts/Circuit.java @@ -0,0 +1,32 @@ +package de.neemann.digital.gui.draw.parts; + +import de.neemann.digital.gui.draw.graphics.Graphic; +import de.neemann.digital.gui.draw.shapes.Drawable; + +import java.util.ArrayList; + +/** + * @author hneemann + */ +public class Circuit implements Drawable { + + private final ArrayList parts; + private final ArrayList wires; + + public Circuit() { + parts = new ArrayList<>(); + wires = new ArrayList<>(); + } + + @Override + public void drawTo(Graphic graphic) { + for (Wire w : wires) + w.drawTo(graphic); + for (Part p : parts) + p.drawTo(graphic); + } + + public void add(Part part) { + parts.add(part); + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/parts/Moveable.java b/src/main/java/de/neemann/digital/gui/draw/parts/Moveable.java new file mode 100644 index 000000000..58ad67c88 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/parts/Moveable.java @@ -0,0 +1,10 @@ +package de.neemann.digital.gui.draw.parts; + +import de.neemann.digital.gui.draw.graphics.Vector; + +/** + * @author hneemann + */ +public interface Moveable { + void move(Vector delta); +} diff --git a/src/main/java/de/neemann/digital/gui/draw/parts/Part.java b/src/main/java/de/neemann/digital/gui/draw/parts/Part.java new file mode 100644 index 000000000..0ea342cc7 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/parts/Part.java @@ -0,0 +1,51 @@ +package de.neemann.digital.gui.draw.parts; + +import de.neemann.digital.gui.draw.graphics.Graphic; +import de.neemann.digital.gui.draw.graphics.GraphicTransform; +import de.neemann.digital.gui.draw.graphics.Style; +import de.neemann.digital.gui.draw.graphics.Vector; +import de.neemann.digital.gui.draw.shapes.Drawable; +import de.neemann.digital.gui.draw.shapes.Shape; + +/** + * @author hneemann + */ +public class Part implements Drawable, Moveable { + private Shape shape; + private Vector pos; + private int rotate; + + public Part(Shape shape) { + this.shape = shape; + } + + public Vector getPos() { + return pos; + } + + public Part setPos(Vector pos) { + this.pos = pos; + return this; + } + + public int getRotate() { + return rotate; + } + + public void setRotate(int rotate) { + this.rotate = rotate; + } + + @Override + public void drawTo(Graphic graphic) { + Graphic gr = new GraphicTransform(graphic, pos, rotate); + shape.drawTo(gr); + for (Pin p : shape.getPins()) + gr.drawCircle(p.getPos().add(-1, -1), p.getPos().add(1, 1), Style.NORMAL); + } + + @Override + public void move(Vector delta) { + pos = pos.add(delta); + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/parts/Pin.java b/src/main/java/de/neemann/digital/gui/draw/parts/Pin.java new file mode 100644 index 000000000..2f4fd7a70 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/parts/Pin.java @@ -0,0 +1,20 @@ +package de.neemann.digital.gui.draw.parts; + +import de.neemann.digital.gui.draw.graphics.Vector; + +/** + * @author hneemann + */ +public class Pin { + private Vector pos; + private String name; + + public Pin(Vector pos, String name) { + this.pos = pos; + this.name = name; + } + + public Vector getPos() { + return pos; + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/parts/Wire.java b/src/main/java/de/neemann/digital/gui/draw/parts/Wire.java new file mode 100644 index 000000000..c99fc0326 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/parts/Wire.java @@ -0,0 +1,26 @@ +package de.neemann.digital.gui.draw.parts; + +import de.neemann.digital.gui.draw.graphics.Graphic; +import de.neemann.digital.gui.draw.graphics.Style; +import de.neemann.digital.gui.draw.graphics.Vector; +import de.neemann.digital.gui.draw.shapes.Drawable; + +/** + * @author hneemann + */ +public class Wire implements Drawable, Moveable { + + private Vector p1; + private Vector p2; + + @Override + public void drawTo(Graphic graphic) { + graphic.drawLine(p1, p2, Style.WIRE); + } + + @Override + public void move(Vector delta) { + p1 = p1.add(delta); + p2 = p2.add(delta); + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/shapes/Drawable.java b/src/main/java/de/neemann/digital/gui/draw/shapes/Drawable.java new file mode 100644 index 000000000..41272000b --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/shapes/Drawable.java @@ -0,0 +1,10 @@ +package de.neemann.digital.gui.draw.shapes; + +import de.neemann.digital.gui.draw.graphics.Graphic; + +/** + * @author hneemann + */ +public interface Drawable { + void drawTo(Graphic graphic); +} diff --git a/src/main/java/de/neemann/digital/gui/draw/shapes/GenericShape.java b/src/main/java/de/neemann/digital/gui/draw/shapes/GenericShape.java new file mode 100644 index 000000000..47155d5b6 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/shapes/GenericShape.java @@ -0,0 +1,65 @@ +package de.neemann.digital.gui.draw.shapes; + +import de.neemann.digital.gui.draw.graphics.Graphic; +import de.neemann.digital.gui.draw.graphics.Polygon; +import de.neemann.digital.gui.draw.graphics.Style; +import de.neemann.digital.gui.draw.graphics.Vector; +import de.neemann.digital.gui.draw.parts.Pin; + +import java.util.ArrayList; + +/** + * @author hneemann + */ +public class GenericShape implements Shape { + + private final String name; + private int inputs; + private int outputs; + private ArrayList pins; + + public GenericShape(String name, int inputs, int outputs) { + this.name = name; + this.inputs = inputs; + this.outputs = outputs; + } + + @Override + public Iterable getPins() { + if (pins == null) { + pins = new ArrayList<>(inputs + outputs); + for (int i = 0; i < inputs; i++) + pins.add(new Pin(new Vector(0, i * 5), "i" + i)); + for (int i = 0; i < outputs; i++) + pins.add(new Pin(new Vector(15, i * 5), "o" + i)); + + } + return pins; + } + + @Override + public void drawTo(Graphic graphic) { + int max = Math.max(inputs, outputs); + int height = (max - 1) * 5 + 2; + graphic.drawPolygon(new Polygon(true).add(1, -2).add(14, -2).add(14, height).add(1, height), Style.NORMAL); + graphic.drawText(new Vector(3, 5), new Vector(4, 5), name); + } + + public int getInputs() { + return inputs; + } + + public void setInputs(int inputs) { + pins = null; + this.inputs = inputs; + } + + public int getOutputs() { + return outputs; + } + + public void setOutputs(int outputs) { + pins = null; + this.outputs = outputs; + } +} diff --git a/src/main/java/de/neemann/digital/gui/draw/shapes/Shape.java b/src/main/java/de/neemann/digital/gui/draw/shapes/Shape.java new file mode 100644 index 000000000..76b217cc0 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/draw/shapes/Shape.java @@ -0,0 +1,12 @@ +package de.neemann.digital.gui.draw.shapes; + +import de.neemann.digital.gui.draw.parts.Pin; + +/** + * @author hneemann + */ +public interface Shape extends Drawable { + + Iterable getPins(); + +}