diff --git a/src/main/java/de/neemann/digital/core/basic/And.java b/src/main/java/de/neemann/digital/core/basic/And.java index b93dfbb8f..de58ff690 100644 --- a/src/main/java/de/neemann/digital/core/basic/And.java +++ b/src/main/java/de/neemann/digital/core/basic/And.java @@ -21,7 +21,7 @@ public class And extends Function { /** * The And description */ - public static final ElementTypeDescription DESCRIPTION = new FanInDescription(And.class); + public static final ElementTypeDescription DESCRIPTION = new FanInDescription(And.class).addAttribute(Keys.WIDE_SHAPE); /** * Creates a new instance diff --git a/src/main/java/de/neemann/digital/core/basic/NAnd.java b/src/main/java/de/neemann/digital/core/basic/NAnd.java index 101d35913..840b09706 100644 --- a/src/main/java/de/neemann/digital/core/basic/NAnd.java +++ b/src/main/java/de/neemann/digital/core/basic/NAnd.java @@ -9,6 +9,7 @@ import de.neemann.digital.core.NodeException; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementTypeDescription; +import de.neemann.digital.core.element.Keys; import java.util.ArrayList; @@ -20,7 +21,7 @@ public class NAnd extends And { /** * The NAnd description */ - public static final ElementTypeDescription DESCRIPTION = new FanInDescription(NAnd.class); + public static final ElementTypeDescription DESCRIPTION = new FanInDescription(NAnd.class).addAttribute(Keys.WIDE_SHAPE); /** * Creates a new instance diff --git a/src/main/java/de/neemann/digital/core/basic/NOr.java b/src/main/java/de/neemann/digital/core/basic/NOr.java index 110d7e055..168e35c98 100644 --- a/src/main/java/de/neemann/digital/core/basic/NOr.java +++ b/src/main/java/de/neemann/digital/core/basic/NOr.java @@ -9,6 +9,7 @@ import de.neemann.digital.core.NodeException; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementTypeDescription; +import de.neemann.digital.core.element.Keys; import java.util.ArrayList; @@ -20,7 +21,7 @@ public class NOr extends Or { /** * The NOr description */ - public static final ElementTypeDescription DESCRIPTION = new FanInDescription(NOr.class); + public static final ElementTypeDescription DESCRIPTION = new FanInDescription(NOr.class).addAttribute(Keys.WIDE_SHAPE); /** * Creates a new instance diff --git a/src/main/java/de/neemann/digital/core/basic/Not.java b/src/main/java/de/neemann/digital/core/basic/Not.java index 763bac608..6f93453dc 100644 --- a/src/main/java/de/neemann/digital/core/basic/Not.java +++ b/src/main/java/de/neemann/digital/core/basic/Not.java @@ -26,6 +26,7 @@ public class Not extends Node implements Element { */ public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Not.class, input("in")) .addAttribute(Keys.ROTATE) + .addAttribute(Keys.WIDE_SHAPE) .addAttribute(Keys.BITS); private final ObservableValue output; diff --git a/src/main/java/de/neemann/digital/core/basic/Or.java b/src/main/java/de/neemann/digital/core/basic/Or.java index 768ed06cc..88b04e430 100644 --- a/src/main/java/de/neemann/digital/core/basic/Or.java +++ b/src/main/java/de/neemann/digital/core/basic/Or.java @@ -21,7 +21,7 @@ public class Or extends Function { /** * The And description */ - public static final ElementTypeDescription DESCRIPTION = new FanInDescription(Or.class); + public static final ElementTypeDescription DESCRIPTION = new FanInDescription(Or.class).addAttribute(Keys.WIDE_SHAPE); /** * Creates a new instance diff --git a/src/main/java/de/neemann/digital/core/basic/XNOr.java b/src/main/java/de/neemann/digital/core/basic/XNOr.java index be5a743da..1faeb0a97 100644 --- a/src/main/java/de/neemann/digital/core/basic/XNOr.java +++ b/src/main/java/de/neemann/digital/core/basic/XNOr.java @@ -9,6 +9,7 @@ import de.neemann.digital.core.NodeException; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementTypeDescription; +import de.neemann.digital.core.element.Keys; import java.util.ArrayList; @@ -20,7 +21,7 @@ public class XNOr extends XOr { /** * The XNOr description */ - public static final ElementTypeDescription DESCRIPTION = new FanInDescription(XNOr.class); + public static final ElementTypeDescription DESCRIPTION = new FanInDescription(XNOr.class).addAttribute(Keys.WIDE_SHAPE); /** * Creates a new instance diff --git a/src/main/java/de/neemann/digital/core/basic/XOr.java b/src/main/java/de/neemann/digital/core/basic/XOr.java index 5b6047432..fe069c59d 100644 --- a/src/main/java/de/neemann/digital/core/basic/XOr.java +++ b/src/main/java/de/neemann/digital/core/basic/XOr.java @@ -21,7 +21,7 @@ public class XOr extends Function { /** * The And description */ - public static final ElementTypeDescription DESCRIPTION = new FanInDescription(XOr.class); + public static final ElementTypeDescription DESCRIPTION = new FanInDescription(XOr.class).addAttribute(Keys.WIDE_SHAPE); /** * Creates a new instance diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java index 1d6b98a71..34d723451 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -668,7 +668,7 @@ public final class Keys { * True if a program is loaded to the simulator at startup */ public static final Key PRELOAD_PROGRAM - = new Key("preloadProgram", false).setSecondary(); + = new Key<>("preloadProgram", false).setSecondary(); /** * The file to preload as a program at startup @@ -676,4 +676,10 @@ public final class Keys { public static final Key PROGRAM_TO_PRELOAD = new Key.KeyFile("preloadProgramFile", new File("")).setSecondary().setDependsOn(PRELOAD_PROGRAM); + /** + * Selects a wide shape + */ + public static final Key WIDE_SHAPE + = new Key<>("wideShape", false).setSecondary().allowGroupEdit(); + } diff --git a/src/main/java/de/neemann/digital/draw/shapes/GenericShape.java b/src/main/java/de/neemann/digital/draw/shapes/GenericShape.java index 834f97b39..81de63ead 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/GenericShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/GenericShape.java @@ -33,7 +33,7 @@ public class GenericShape implements Shape { private final String name; private final PinDescriptions inputs; private final PinDescriptions outputs; - private final int width; + private int width; private final boolean symmetric; private final String label; @@ -125,14 +125,15 @@ public class GenericShape implements Shape { /** * Creates pins * - * @param inputs the inputs - * @param outputs the outputs - * @param invert true if invert output - * @param ic iput inverter configuration + * @param inputs the inputs + * @param outputs the outputs + * @param invert true if invert output + * @param ic input inverter configuration + * @param wideShape true if a wide shape is selected * @return the pins */ - public static Pins createPins(PinDescriptions inputs, PinDescriptions outputs, boolean invert, InverterConfig ic) { - return createPins(inputs, outputs, invert, 3, true, ic); + public static Pins createPins(PinDescriptions inputs, PinDescriptions outputs, boolean invert, InverterConfig ic, boolean wideShape) { + return createPins(inputs, outputs, invert, wideShape ? 4 : 3, true, ic); } /** @@ -280,4 +281,16 @@ public class GenericShape implements Shape { this.inverterConfig = inverterConfig; return this; } + + /** + * Selects a wide shape. + * + * @param wideShape true is a wide shape is selected + * @return this for chained calls + */ + public GenericShape setWide(boolean wideShape) { + if (wideShape) + width += 1; + return this; + } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java index dfc440837..aabe3db03 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java @@ -65,7 +65,7 @@ public final class ShapeFactory { map.put(NOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEOrShape(inputs, outputs, true, attributes)); map.put(XOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEXOrShape(inputs, outputs, false, attributes)); map.put(XNOr.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEEXOrShape(inputs, outputs, true, attributes)); - map.put(Not.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEENotShape(inputs, outputs)); + map.put(Not.DESCRIPTION.getName(), (attributes, inputs, outputs) -> new IEEENotShape(inputs, outputs, attributes)); } else { map.put(And.DESCRIPTION.getName(), new CreatorSimple("&", false)); map.put(Or.DESCRIPTION.getName(), new CreatorSimple("\u22651", false)); @@ -259,6 +259,7 @@ public final class ShapeFactory { public Shape create(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) { return new GenericShape(name, inputs, outputs) .invert(invers) + .setWide(attributes.get(Keys.WIDE_SHAPE)) .setInverterConfig(attributes.get(Keys.INVERTER_CONFIG)); } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEAndShape.java b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEAndShape.java index 822d1586b..a7702732d 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEAndShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEAndShape.java @@ -21,6 +21,7 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE2; public class IEEEAndShape extends IEEEGenericShape { private static final Polygon POLYGON = createPoly(); + private static final Polygon POLYGON_WIDE = createPolyWide(); private static Polygon createPoly() { return new Polygon(true) @@ -32,6 +33,16 @@ public class IEEEAndShape extends IEEEGenericShape { .add(new Vector(SIZE * 3 - 1, SIZE * 2), new Vector(SIZE * 2, SIZE * 2 + SIZE2), new Vector(SIZE + SIZE2, SIZE * 2 + SIZE2)); } + private static Polygon createPolyWide() { + return new Polygon(true) + .add(SIZE * 2 + SIZE2, SIZE * 2 + SIZE2) + .add(1, SIZE * 2 + SIZE2) + .add(1, -SIZE2) + .add(SIZE * 2 + SIZE2, -SIZE2) + .add(new Vector(SIZE * 3, -SIZE2), new Vector(SIZE * 4, 0), new Vector(SIZE * 4 - 1, SIZE)) + .add(new Vector(SIZE * 4 - 1, SIZE * 2), new Vector(SIZE * 3, SIZE * 2 + SIZE2), new Vector(SIZE * 2 + SIZE2, SIZE * 2 + SIZE2)); + } + /** * Creates a new instance * @@ -46,7 +57,10 @@ public class IEEEAndShape extends IEEEGenericShape { @Override protected void drawIEEE(Graphic graphic) { - graphic.drawPolygon(POLYGON, Style.NORMAL); + if (isWideShape()) + graphic.drawPolygon(POLYGON_WIDE, Style.NORMAL); + else + graphic.drawPolygon(POLYGON, Style.NORMAL); } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java index 9c079f1ed..6377acc19 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEGenericShape.java @@ -29,6 +29,7 @@ public abstract class IEEEGenericShape implements Shape { private final PinDescriptions outputs; private final boolean invert; private final InverterConfig inverterConfig; + private final boolean wideShape; private Pins pins; @@ -44,13 +45,14 @@ public abstract class IEEEGenericShape implements Shape { this.inputs = inputs; this.outputs = outputs; this.invert = invert; + this.wideShape = attr.get(Keys.WIDE_SHAPE); inverterConfig = attr.get(Keys.INVERTER_CONFIG); } @Override public Pins getPins() { if (pins == null) - pins = GenericShape.createPins(inputs, outputs, invert, inverterConfig); + pins = GenericShape.createPins(inputs, outputs, invert, inverterConfig, wideShape); return pins; } @@ -74,9 +76,12 @@ public abstract class IEEEGenericShape implements Shape { if (invert) { int o = inputs.size() / 2 * SIZE; + int pos = 3; + if (wideShape) + pos++; for (int i = 0; i < outputs.size(); i++) - graphic.drawCircle(new Vector(SIZE * 3 + 1, i * SIZE - SIZE2 + 1 + o), - new Vector(SIZE * 4 - 1, i * SIZE + SIZE2 - 1 + o), Style.NORMAL); + graphic.drawCircle(new Vector(SIZE * pos + 1, i * SIZE - SIZE2 + 1 + o), + new Vector(SIZE * (pos + 1) - 1, i * SIZE + SIZE2 - 1 + o), Style.NORMAL); } } @@ -87,4 +92,10 @@ public abstract class IEEEGenericShape implements Shape { */ protected abstract void drawIEEE(Graphic graphic); + /** + * @return true is a wide shape is selected + */ + public boolean isWideShape() { + return wideShape; + } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEENotShape.java b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEENotShape.java index 079579e86..c4cfa7171 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEENotShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEENotShape.java @@ -6,6 +6,8 @@ package de.neemann.digital.draw.shapes.ieee; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.ElementAttributes; +import de.neemann.digital.core.element.Keys; import de.neemann.digital.core.element.PinDescriptions; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; @@ -26,17 +28,20 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE2; public class IEEENotShape implements Shape { private final PinDescriptions inputs; private final PinDescriptions outputs; + private final boolean wideShape; private Pins pins; /** * Creates a new instance * - * @param inputs the inputs - * @param outputs the outputs + * @param inputs the inputs + * @param outputs the outputs + * @param attributes the elements attributes */ - public IEEENotShape(PinDescriptions inputs, PinDescriptions outputs) { + public IEEENotShape(PinDescriptions inputs, PinDescriptions outputs, ElementAttributes attributes) { this.inputs = inputs; this.outputs = outputs; + wideShape = attributes.get(Keys.WIDE_SHAPE); } @Override @@ -44,7 +49,10 @@ public class IEEENotShape implements Shape { if (pins == null) { pins = new Pins(); pins.add(new Pin(new Vector(0, 0), inputs.get(0))); - pins.add(new Pin(new Vector(SIZE * 2, 0), outputs.get(0))); + int width = SIZE * 2; + if (wideShape) + width += SIZE; + pins.add(new Pin(new Vector(width, 0), outputs.get(0))); } return pins; } @@ -56,13 +64,24 @@ public class IEEENotShape implements Shape { @Override public void drawTo(Graphic graphic, Style highLight) { - graphic.drawPolygon( - new Polygon(true) - .add(1, -SIZE2 - 2) - .add(SIZE - 1, 0) - .add(1, SIZE2 + 2), Style.NORMAL - ); - graphic.drawCircle(new Vector(SIZE + 1, -SIZE2 + 1), - new Vector(SIZE * 2 - 1, SIZE2 - 1), Style.NORMAL); + if (wideShape) { + graphic.drawPolygon( + new Polygon(true) + .add(1, -SIZE - 2) + .add(SIZE * 2 - 1, 0) + .add(1, SIZE + 2), Style.NORMAL + ); + graphic.drawCircle(new Vector(SIZE * 2 + 1, -SIZE2 + 1), + new Vector(SIZE * 3 - 1, SIZE2 - 1), Style.NORMAL); + } else { + graphic.drawPolygon( + new Polygon(true) + .add(1, -SIZE2 - 2) + .add(SIZE - 1, 0) + .add(1, SIZE2 + 2), Style.NORMAL + ); + graphic.drawCircle(new Vector(SIZE + 1, -SIZE2 + 1), + new Vector(SIZE * 2 - 1, SIZE2 - 1), Style.NORMAL); + } } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEOrShape.java b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEOrShape.java index e07935bf6..6b6e596a1 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEOrShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEOrShape.java @@ -21,6 +21,7 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE2; public class IEEEOrShape extends IEEEGenericShape { private static final Polygon POLYGON = createPoly(); + private static final Polygon POLYGON_WIDE = createPolyWide(); private static Polygon createPoly() { return new Polygon(true) @@ -38,6 +39,22 @@ public class IEEEOrShape extends IEEEGenericShape { new Vector(SIZE2, SIZE * 2 + SIZE2)); } + private static Polygon createPolyWide() { + return new Polygon(true) + .add(SIZE + SIZE2, SIZE * 2 + SIZE2) + .add(0, SIZE * 2 + SIZE2) + .add(new Vector(SIZE2, SIZE2 * 3 + 4), + new Vector(SIZE2, 6), + new Vector(0, -SIZE2)) + .add(SIZE, -SIZE2) + .add(new Vector(SIZE * 2 + SIZE2, -SIZE2), + new Vector(SIZE * 3 + SIZE2, 0), + new Vector(SIZE * 4, SIZE)) + .add(new Vector(SIZE * 3 + SIZE2, SIZE * 2), + new Vector(SIZE * 2 + SIZE2, SIZE * 2 + SIZE2), + new Vector(SIZE + SIZE2, SIZE * 2 + SIZE2)); + } + private final boolean center; /** @@ -59,6 +76,9 @@ public class IEEEOrShape extends IEEEGenericShape { graphic.drawLine(new Vector(0, SIZE * 2), new Vector(4, SIZE * 2), Style.WIRE); if (center) graphic.drawLine(new Vector(0, SIZE), new Vector(7, SIZE), Style.WIRE); - graphic.drawPolygon(POLYGON, Style.NORMAL); + if (isWideShape()) + graphic.drawPolygon(POLYGON_WIDE, Style.NORMAL); + else + graphic.drawPolygon(POLYGON, Style.NORMAL); } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEXOrShape.java b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEXOrShape.java index 4de97073c..2f65d6ee6 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEXOrShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ieee/IEEEXOrShape.java @@ -22,6 +22,7 @@ public class IEEEXOrShape extends IEEEGenericShape { private static final Polygon POLYGON = createPoly(); private static final Polygon POLYGON2 = createPoly2(); + private static final Polygon POLYGON_WIDE = createPolyWide(); private static Polygon createPoly() { return new Polygon(true) @@ -37,6 +38,22 @@ public class IEEEXOrShape extends IEEEGenericShape { new Vector(SIZE2 + 1, SIZE * 2 + SIZE2)); } + private static Polygon createPolyWide() { + return new Polygon(true) + .add(SIZE + SIZE2, SIZE * 2 + SIZE2) + .add(SIZE2, SIZE * 2 + SIZE2) + .add(new Vector(SIZE2 + SIZE2, SIZE2 * 3 + 4), + new Vector(SIZE2 + SIZE2, 6), + new Vector(SIZE2, -SIZE2)) + .add(SIZE + SIZE2, -SIZE2) + .add(new Vector(SIZE * 2 + SIZE2, -SIZE2), + new Vector(SIZE * 3 + SIZE2, 0), + new Vector(SIZE * 4, SIZE)) + .add(new Vector(SIZE * 3 + SIZE2, SIZE * 2), + new Vector(SIZE * 2 + SIZE2, SIZE * 2 + SIZE2), + new Vector(SIZE + SIZE2, SIZE * 2 + SIZE2)); + } + private static Polygon createPoly2() { return new Polygon(false) .add(0, SIZE * 2 + SIZE2) @@ -62,11 +79,14 @@ public class IEEEXOrShape extends IEEEGenericShape { @Override protected void drawIEEE(Graphic graphic) { - graphic.drawLine(new Vector(0, 0), new Vector(5 + SIZE2, 0), Style.WIRE); - graphic.drawLine(new Vector(0, SIZE * 2), new Vector(5 + SIZE2, SIZE * 2), Style.WIRE); + graphic.drawLine(new Vector(0, 0), new Vector(4 + SIZE2, 0), Style.WIRE); + graphic.drawLine(new Vector(0, SIZE * 2), new Vector(4 + SIZE2, SIZE * 2), Style.WIRE); if (center) graphic.drawLine(new Vector(0, SIZE), new Vector(7 + SIZE2, SIZE), Style.WIRE); - graphic.drawPolygon(POLYGON, Style.NORMAL); + if (isWideShape()) + graphic.drawPolygon(POLYGON_WIDE, Style.NORMAL); + else + graphic.drawPolygon(POLYGON, Style.NORMAL); graphic.drawPolygon(POLYGON2, Style.NORMAL); } } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index cea5cc39a..bfa89d8af 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -1194,6 +1194,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Datei welche beim Start der Simulation in den Programspeicher geladen werden soll. + Breites Symbol + Verwendet ein breiteres Symbol zur Darstellung des Gatters. + Form Die Form, welche für die Repräsentation der Schaltung in einer einbettenden diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 2bc4935a6..93b853b27 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -1186,6 +1186,8 @@ File which should be loaded into the program memory at the start of the simulation. + Wide Shape + Uses a wider shape to visualize the gate. Shape The shape to be used for the representation of the circuit in an embedding circuit.