mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 06:49:36 -04:00
Merge branch 'defaultBug'
This commit is contained in:
commit
f15e41c9a2
@ -28,9 +28,9 @@
|
||||
<sodipodi:namedview
|
||||
showgrid="true"
|
||||
id="namedview4"
|
||||
inkscape:zoom="3.5454545"
|
||||
inkscape:cx="71.064102"
|
||||
inkscape:cy="87.435899"
|
||||
inkscape:zoom="3.5090909"
|
||||
inkscape:cx="100.47927"
|
||||
inkscape:cy="110"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="993"
|
||||
inkscape:window-x="0"
|
||||
@ -45,7 +45,7 @@
|
||||
id="grid2" />
|
||||
</sodipodi:namedview>
|
||||
<path
|
||||
style="fill:#ffffb4;fill-opacity:0.78431373;stroke:#000000;stroke-width:3"
|
||||
style="fill:#ffffb4;fill-opacity:0.78431373;stroke:#000000;stroke-width:4"
|
||||
d="M 0,-30 80,10 V 90 L 0,130 V 60 L 30,50 0,40 Z"
|
||||
id="rect6"
|
||||
inkscape:connector-curvature="0"
|
||||
@ -59,7 +59,7 @@
|
||||
<circle
|
||||
style="fill:#0000b2"
|
||||
r="3"
|
||||
cy="100.10256"
|
||||
cy="79.794868"
|
||||
cx="0.28205127"
|
||||
id="pin+:B" />
|
||||
<circle
|
||||
@ -71,7 +71,7 @@
|
||||
<circle
|
||||
style="fill:#0000b2"
|
||||
r="3"
|
||||
cy="120.07693"
|
||||
cy="99.769234"
|
||||
cx="-0.2820513"
|
||||
id="pin+:Ci" />
|
||||
<circle
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
@ -16,31 +16,45 @@ import java.io.File;
|
||||
*/
|
||||
public class Key<VALUE> {
|
||||
private final String key;
|
||||
private final VALUE def;
|
||||
private final DefaultFactory<VALUE> defFactory;
|
||||
private final String langKey;
|
||||
private boolean groupEditAllowed = false;
|
||||
private Key dependsOn;
|
||||
private CheckEnabled checkEnabled;
|
||||
private boolean isSecondary;
|
||||
private boolean requiresRestart = false;
|
||||
|
||||
// Both values are always null in digital.
|
||||
// Both are only used within a custom implemented component.
|
||||
private String name;
|
||||
private String description;
|
||||
private boolean isSecondary;
|
||||
private boolean requiresRestart = false;
|
||||
|
||||
/**
|
||||
* Creates a new Key
|
||||
* Creates a new Key.
|
||||
* Use this constructor only if the def value is not mutable!
|
||||
*
|
||||
* @param key the key
|
||||
* @param def the default value
|
||||
*/
|
||||
public Key(String key, VALUE def) {
|
||||
this.key = key;
|
||||
langKey = "key_" + key.replace(" ", "");
|
||||
this(key, () -> def);
|
||||
if (def == null)
|
||||
throw new NullPointerException();
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Key.
|
||||
* Use this constructor if the def value is mutable!
|
||||
*
|
||||
* @param key the key
|
||||
* @param defFactory the factory to create a default value
|
||||
*/
|
||||
public Key(String key, DefaultFactory<VALUE> defFactory) {
|
||||
this.key = key;
|
||||
langKey = "key_" + key.replace(" ", "");
|
||||
if (defFactory == null)
|
||||
throw new NullPointerException();
|
||||
this.defFactory = defFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,14 +82,14 @@ public class Key<VALUE> {
|
||||
* @return the default value of this key
|
||||
*/
|
||||
public VALUE getDefault() {
|
||||
return def;
|
||||
return defFactory.createDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The values class
|
||||
*/
|
||||
public Class getValueClass() {
|
||||
return def.getClass();
|
||||
return getDefault().getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -490,4 +504,18 @@ public class Key<VALUE> {
|
||||
*/
|
||||
boolean isEnabled(T t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to provide a default value if the value is mutable.
|
||||
*
|
||||
* @param <VALUE> the type of the value
|
||||
*/
|
||||
public interface DefaultFactory<VALUE> {
|
||||
/**
|
||||
* Called to create a new default value.
|
||||
*
|
||||
* @return the default value
|
||||
*/
|
||||
VALUE createDefault();
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ public final class Keys {
|
||||
* the data key for memory
|
||||
*/
|
||||
public static final Key<DataField> DATA
|
||||
= new Key<>("Data", DataField.DEFAULT);
|
||||
= new Key<>("Data", DataField::new);
|
||||
|
||||
/**
|
||||
* flag for flipping selector pos in muxers, decoders and drivers
|
||||
@ -602,7 +602,7 @@ public final class Keys {
|
||||
* contains the input inverter config
|
||||
*/
|
||||
public static final Key<InverterConfig> INVERTER_CONFIG
|
||||
= new Key<>("inverterConfig", new InverterConfig());
|
||||
= new Key<>("inverterConfig", new InverterConfig.Builder().build());
|
||||
|
||||
/**
|
||||
* Background Color of nested circuits
|
||||
@ -661,7 +661,7 @@ public final class Keys {
|
||||
* The manager which contains all the roms data
|
||||
*/
|
||||
public static final Key<ROMManger> ROMMANAGER
|
||||
= new Key<>("romContent", ROMManger.EMPTY).setSecondary();
|
||||
= new Key<>("romContent", ROMManger::new).setSecondary();
|
||||
|
||||
|
||||
/**
|
||||
@ -707,7 +707,7 @@ public final class Keys {
|
||||
* Shape used to represent a visual element
|
||||
*/
|
||||
public static final Key<CustomShapeDescription> CUSTOM_SHAPE
|
||||
= new Key<>("customShape", CustomShapeDescription.EMPTY)
|
||||
= new Key<>("customShape", new CustomShapeDescription.Builder().build())
|
||||
.setSecondary()
|
||||
.setDependsOn(SHAPE_TYPE, st -> st.equals(CustomCircuitShapeType.CUSTOM));
|
||||
|
||||
|
@ -17,15 +17,17 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class DataField implements HGSArray {
|
||||
|
||||
/***
|
||||
* Simple default data field
|
||||
*/
|
||||
public static final DataField DEFAULT = new DataField(0);
|
||||
|
||||
private long[] data;
|
||||
|
||||
private final transient ArrayList<DataListener> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a new DataField of size 0
|
||||
*/
|
||||
public DataField() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DataField
|
||||
*
|
||||
@ -174,6 +176,13 @@ public class DataField implements HGSArray {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the data field is empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return trim() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to this DataField
|
||||
*
|
||||
@ -247,4 +256,17 @@ public class DataField implements HGSArray {
|
||||
public long[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DataField dataField = (DataField) o;
|
||||
return Arrays.equals(data, dataField.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(data);
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,7 @@
|
||||
*/
|
||||
package de.neemann.digital.core.memory;
|
||||
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.ObservableValues;
|
||||
import de.neemann.digital.core.*;
|
||||
import de.neemann.digital.core.element.Element;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||
@ -40,6 +37,7 @@ public class EEPROM extends Node implements Element, RAMInterface, ROMInterface
|
||||
|
||||
private final int bits;
|
||||
private final int addrBits;
|
||||
private final ElementAttributes attr;
|
||||
private final int size;
|
||||
private final String label;
|
||||
private final ObservableValue dataOut;
|
||||
@ -65,6 +63,7 @@ public class EEPROM extends Node implements Element, RAMInterface, ROMInterface
|
||||
*/
|
||||
public EEPROM(ElementAttributes attr) {
|
||||
super(true);
|
||||
this.attr = attr;
|
||||
bits = attr.get(Keys.BITS);
|
||||
addrBits = attr.get(Keys.ADDR_BITS);
|
||||
size = 1 << addrBits;
|
||||
@ -77,6 +76,14 @@ public class EEPROM extends Node implements Element, RAMInterface, ROMInterface
|
||||
isProgramMemory = attr.get(Keys.IS_PROGRAM_MEMORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
super.registerNodes(model);
|
||||
|
||||
if (memory.isEmpty())
|
||||
model.addObserver(event -> attr.set(Keys.DATA, memory), ModelEvent.STOPPED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputs(ObservableValues inputs) throws NodeException {
|
||||
addrIn = inputs.get(0).checkBits(addrBits, this).addObserverToValue(this);
|
||||
|
@ -5,6 +5,8 @@
|
||||
*/
|
||||
package de.neemann.digital.core.memory;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.ModelEvent;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
@ -33,6 +35,9 @@ public class EEPROMDualPort extends RAMDualPort implements ROMInterface {
|
||||
.addAttribute(Keys.LABEL)
|
||||
.addAttribute(Keys.DATA);
|
||||
|
||||
private final ElementAttributes attr;
|
||||
private DataField memory;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
@ -40,11 +45,21 @@ public class EEPROMDualPort extends RAMDualPort implements ROMInterface {
|
||||
*/
|
||||
public EEPROMDualPort(ElementAttributes attr) {
|
||||
super(attr);
|
||||
this.attr = attr;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataField createDataField(ElementAttributes attr, int size) {
|
||||
return attr.get(Keys.DATA);
|
||||
memory = attr.get(Keys.DATA);
|
||||
return memory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
super.registerNodes(model);
|
||||
|
||||
if (memory.isEmpty())
|
||||
model.addObserver(event -> attr.set(Keys.DATA, memory), ModelEvent.STOPPED);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,15 +10,12 @@ import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.memory.DataField;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The Manager to manage all necessary rom images
|
||||
*/
|
||||
public class ROMManger {
|
||||
/**
|
||||
* The empty instance
|
||||
*/
|
||||
public static final ROMManger EMPTY = new ROMManger();
|
||||
|
||||
private final HashMap<String, DataField> roms;
|
||||
|
||||
@ -35,6 +32,8 @@ public class ROMManger {
|
||||
* @param model the mode to use
|
||||
*/
|
||||
public void applyTo(Model model) {
|
||||
if (roms == null)
|
||||
return;
|
||||
for (Node n : model.findNode(n -> n instanceof ROMInterface)) {
|
||||
ROMInterface rom = (ROMInterface) n;
|
||||
DataField data = roms.get(rom.getLabel());
|
||||
@ -65,19 +64,23 @@ public class ROMManger {
|
||||
roms.put(label, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns EMPTY it this ROMManager is empty, this otherwise
|
||||
*/
|
||||
public ROMManger getMinimized() {
|
||||
if (roms.isEmpty())
|
||||
return EMPTY;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if no ROM's are stored
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return roms.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ROMManger romManger = (ROMManger) o;
|
||||
return Objects.equals(roms, romManger.roms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(roms);
|
||||
}
|
||||
}
|
||||
|
@ -15,29 +15,12 @@ import java.util.Objects;
|
||||
/**
|
||||
* Manages the input inverting of a component
|
||||
*/
|
||||
public class InverterConfig implements HGSMap {
|
||||
public final class InverterConfig implements HGSMap {
|
||||
|
||||
private HashSet<String> inputs;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* No input is inverted.
|
||||
*/
|
||||
public InverterConfig() {
|
||||
inputs = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a signal to invert
|
||||
*
|
||||
* @param name the signale
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public InverterConfig add(String name) {
|
||||
if (inputs == null)
|
||||
inputs = new HashSet<>();
|
||||
inputs.add(name);
|
||||
return this;
|
||||
private InverterConfig(HashSet<String> inputs) {
|
||||
this.inputs = inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,4 +112,35 @@ public class InverterConfig implements HGSMap {
|
||||
|
||||
return inputs.contains(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder to create InverterConfig instances
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private HashSet<String> inputs;
|
||||
|
||||
/**
|
||||
* Adds a signal to invert
|
||||
*
|
||||
* @param name the signale
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Builder add(String name) {
|
||||
if (inputs == null)
|
||||
inputs = new HashSet<>();
|
||||
inputs.add(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creats the instance
|
||||
*
|
||||
* @return the created instance
|
||||
*/
|
||||
public InverterConfig build() {
|
||||
return new InverterConfig(inputs);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ public final class ShapeFactory {
|
||||
return new LayoutShape(customDescr, elementAttributes);
|
||||
case CUSTOM:
|
||||
final CustomShapeDescription customShapeDescription = customDescr.getAttributes().get(Keys.CUSTOM_SHAPE);
|
||||
if (customShapeDescription != CustomShapeDescription.EMPTY)
|
||||
if (!customShapeDescription.isEmpty())
|
||||
return new CustomShape(customShapeDescription, elementAttributes.getLabel(),
|
||||
pt.getInputDescription(elementAttributes),
|
||||
pt.getOutputDescriptions(elementAttributes));
|
||||
|
@ -24,95 +24,19 @@ import java.util.Iterator;
|
||||
/**
|
||||
* Is intended to be stored in a file.
|
||||
*/
|
||||
public class CustomShapeDescription implements Iterable<CustomShapeDescription.Holder> {
|
||||
/**
|
||||
* The default empty shape instance
|
||||
*/
|
||||
public static final CustomShapeDescription EMPTY = new CustomShapeDescription();
|
||||
public final class CustomShapeDescription implements Iterable<CustomShapeDescription.Holder> {
|
||||
|
||||
private HashMap<String, Pin> pins;
|
||||
private ArrayList<Holder> drawables;
|
||||
private TextHolder label;
|
||||
private final HashMap<String, Pin> pins;
|
||||
private final ArrayList<Holder> drawables;
|
||||
private final TextHolder label;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public CustomShapeDescription() {
|
||||
pins = new HashMap<>();
|
||||
drawables = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pin to this shape description
|
||||
*
|
||||
* @param name the name of the pin
|
||||
* @param pos the pins position
|
||||
* @param showLabel if true the label of the pin is shown
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public CustomShapeDescription addPin(String name, Vector pos, boolean showLabel) {
|
||||
pins.put(name, new Pin(pos, showLabel));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a polygon to the shape
|
||||
*
|
||||
* @param p1 starting point of the line
|
||||
* @param p2 ending point of the line
|
||||
* @param thickness the line thickness
|
||||
* @param color the color to use
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public CustomShapeDescription addLine(Vector p1, Vector p2, int thickness, Color color) {
|
||||
drawables.add(new LineHolder(p1, p2, thickness, color));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a circle to the shape
|
||||
*
|
||||
* @param p1 upper left corner of the circles bounding box
|
||||
* @param p2 lower right corner of the circles bounding box
|
||||
* @param thickness the line thickness
|
||||
* @param color the color to use
|
||||
* @param filled true if filled
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public CustomShapeDescription addCircle(Vector p1, Vector p2, int thickness, Color color, boolean filled) {
|
||||
drawables.add(new CircleHolder(p1, p2, thickness, color, filled));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a polygon to the shape
|
||||
*
|
||||
* @param poly the polygon to add
|
||||
* @param thickness the line thickness
|
||||
* @param color the color to use
|
||||
* @param filled true if filled
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public CustomShapeDescription addPolygon(Polygon poly, int thickness, Color color, boolean filled) {
|
||||
drawables.add(new PolygonHolder(poly, thickness, filled, color));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a text to the shape
|
||||
*
|
||||
* @param p1 position
|
||||
* @param p2 second position to determin the base line orientation
|
||||
* @param text the text to draw
|
||||
* @param orientation the orientation of the text
|
||||
* @param size the font size
|
||||
* @param color the text color
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public CustomShapeDescription addText(Vector p1, Vector p2, String text, Orientation orientation, int size, Color color) {
|
||||
drawables.add(new TextHolder(p1, p2, text, orientation, size, color));
|
||||
return this;
|
||||
private CustomShapeDescription(HashMap<String, Pin> pins, ArrayList<Holder> drawables, TextHolder label) {
|
||||
this.pins = pins;
|
||||
this.drawables = drawables;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,19 +79,6 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
|
||||
return pins.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the label positioning info.
|
||||
*
|
||||
* @param pos0 pos0
|
||||
* @param pos1 pos1
|
||||
* @param textOrientation textOrientation
|
||||
* @param fontSize fontSize
|
||||
* @param filled filled
|
||||
*/
|
||||
public void setLabel(Vector pos0, Vector pos1, Orientation textOrientation, int fontSize, Color filled) {
|
||||
label = new TextHolder(pos0, pos1, "", textOrientation, fontSize, filled);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the TextHolder used to draw the label, maybe null
|
||||
*/
|
||||
@ -182,6 +93,13 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
|
||||
return pins.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if shape is empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return drawables.isEmpty() && pins.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the compatibility of this shape to the given circuit
|
||||
*
|
||||
@ -201,6 +119,26 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
|
||||
throw new PinException(Lang.get("err_morePinsDefinedInSVGAsNeeded"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Two CustomShapeDescriptions are equal if and only if they are both empty!
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
CustomShapeDescription customShapeDescription = (CustomShapeDescription) o;
|
||||
|
||||
return customShapeDescription.isEmpty() && isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (isEmpty())
|
||||
return 0;
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
private interface Transformable {
|
||||
void transform(Transform tr);
|
||||
}
|
||||
@ -423,4 +361,117 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
|
||||
pos = pos.transform(tr).round();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to build a custom shape description
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final HashMap<String, Pin> pins;
|
||||
private final ArrayList<Holder> drawables;
|
||||
private TextHolder label;
|
||||
|
||||
/**
|
||||
* Creates a new builder
|
||||
*/
|
||||
public Builder() {
|
||||
pins = new HashMap<>();
|
||||
drawables = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the label positioning info.
|
||||
*
|
||||
* @param pos0 pos0
|
||||
* @param pos1 pos1
|
||||
* @param textOrientation textOrientation
|
||||
* @param fontSize fontSize
|
||||
* @param filled filled
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Builder setLabel(Vector pos0, Vector pos1, Orientation textOrientation, int fontSize, Color filled) {
|
||||
label = new TextHolder(pos0, pos1, "", textOrientation, fontSize, filled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pin to this shape description
|
||||
*
|
||||
* @param name the name of the pin
|
||||
* @param pos the pins position
|
||||
* @param showLabel if true the label of the pin is shown
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Builder addPin(String name, Vector pos, boolean showLabel) {
|
||||
pins.put(name, new Pin(pos, showLabel));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a polygon to the shape
|
||||
*
|
||||
* @param p1 starting point of the line
|
||||
* @param p2 ending point of the line
|
||||
* @param thickness the line thickness
|
||||
* @param color the color to use
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Builder addLine(Vector p1, Vector p2, int thickness, Color color) {
|
||||
drawables.add(new LineHolder(p1, p2, thickness, color));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a circle to the shape
|
||||
*
|
||||
* @param p1 upper left corner of the circles bounding box
|
||||
* @param p2 lower right corner of the circles bounding box
|
||||
* @param thickness the line thickness
|
||||
* @param color the color to use
|
||||
* @param filled true if filled
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Builder addCircle(Vector p1, Vector p2, int thickness, Color color, boolean filled) {
|
||||
drawables.add(new CircleHolder(p1, p2, thickness, color, filled));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a polygon to the shape
|
||||
*
|
||||
* @param poly the polygon to add
|
||||
* @param thickness the line thickness
|
||||
* @param color the color to use
|
||||
* @param filled true if filled
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Builder addPolygon(Polygon poly, int thickness, Color color, boolean filled) {
|
||||
drawables.add(new PolygonHolder(poly, thickness, filled, color));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a text to the shape
|
||||
*
|
||||
* @param p1 position
|
||||
* @param p2 second position to determin the base line orientation
|
||||
* @param text the text to draw
|
||||
* @param orientation the orientation of the text
|
||||
* @param size the font size
|
||||
* @param color the text color
|
||||
* @return this for chained calls
|
||||
*/
|
||||
public Builder addText(Vector p1, Vector p2, String text, Orientation orientation, int size, Color color) {
|
||||
drawables.add(new TextHolder(p1, p2, text, orientation, size, color));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link CustomShapeDescription}
|
||||
*/
|
||||
public CustomShapeDescription build() {
|
||||
return new CustomShapeDescription(pins, drawables, label);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -67,9 +67,10 @@ public class SvgImporter {
|
||||
NodeList gList = svg.getElementsByTagName("svg").item(0).getChildNodes();
|
||||
Context c = new Context();
|
||||
try {
|
||||
CustomShapeDescription csd = new CustomShapeDescription();
|
||||
create(csd, gList, c);
|
||||
CustomShapeDescription.Builder builder = new CustomShapeDescription.Builder();
|
||||
create(builder, gList, c);
|
||||
|
||||
CustomShapeDescription csd = builder.build();
|
||||
if (csd.getPinCount() > 0) {
|
||||
float xMin = Float.MAX_VALUE;
|
||||
float yMin = Float.MAX_VALUE;
|
||||
@ -86,7 +87,7 @@ public class SvgImporter {
|
||||
}
|
||||
}
|
||||
|
||||
private void create(CustomShapeDescription csd, NodeList gList, Context c) throws SvgException {
|
||||
private void create(CustomShapeDescription.Builder csd, NodeList gList, Context c) throws SvgException {
|
||||
for (int i = 0; i < gList.getLength(); i++) {
|
||||
final Node node = gList.item(i);
|
||||
if (node instanceof Element) {
|
||||
@ -99,7 +100,7 @@ public class SvgImporter {
|
||||
}
|
||||
}
|
||||
|
||||
private void create(CustomShapeDescription csd, Element element, Context parent) throws SvgException {
|
||||
private void create(CustomShapeDescription.Builder csd, Element element, Context parent) throws SvgException {
|
||||
Context c = new Context(parent, element);
|
||||
switch (element.getNodeName()) {
|
||||
case "a":
|
||||
@ -150,19 +151,19 @@ public class SvgImporter {
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTransformedPolygon(CustomShapeDescription csd, Context c, Polygon polygon) {
|
||||
private void drawTransformedPolygon(CustomShapeDescription.Builder csd, Context c, Polygon polygon) {
|
||||
if (polygon != null)
|
||||
drawPolygon(csd, c, polygon.transform(c.getTransform()));
|
||||
}
|
||||
|
||||
private void drawPolygon(CustomShapeDescription csd, Context c, Polygon polygon) {
|
||||
private void drawPolygon(CustomShapeDescription.Builder csd, Context c, Polygon polygon) {
|
||||
if (c.getFilled() != null && polygon.isClosed())
|
||||
csd.addPolygon(polygon, c.getThickness(), c.getFilled(), true);
|
||||
if (c.getStroke() != null)
|
||||
csd.addPolygon(polygon, c.getThickness(), c.getStroke(), false);
|
||||
}
|
||||
|
||||
private void drawRect(CustomShapeDescription csd, Element element, Context c) {
|
||||
private void drawRect(CustomShapeDescription.Builder csd, Element element, Context c) {
|
||||
VectorInterface size = new VectorFloat(c.getLength(element.getAttribute("width")), c.getLength(element.getAttribute("height")));
|
||||
VectorInterface pos = new VectorFloat(c.getLength(element.getAttribute("x")), c.getLength(element.getAttribute("y")));
|
||||
String rxStr = element.getAttribute("rx");
|
||||
@ -213,7 +214,7 @@ public class SvgImporter {
|
||||
drawPolygon(csd, c, polygon);
|
||||
}
|
||||
|
||||
private void drawCircle(CustomShapeDescription csd, Element element, Context c) {
|
||||
private void drawCircle(CustomShapeDescription.Builder csd, Element element, Context c) {
|
||||
if (element.hasAttribute("id")) {
|
||||
VectorInterface pos = c.v(c.getLength(element.getAttribute("cx")), c.getLength(element.getAttribute("cy")));
|
||||
String id = element.getAttribute("id");
|
||||
@ -279,7 +280,7 @@ public class SvgImporter {
|
||||
return new Vector(Math.round(pos.getXFloat() / SIZE) * SIZE, Math.round(pos.getYFloat() / SIZE) * SIZE);
|
||||
}
|
||||
|
||||
private void drawText(CustomShapeDescription csd, Context c, Element element) throws SvgException {
|
||||
private void drawText(CustomShapeDescription.Builder csd, Context c, Element element) throws SvgException {
|
||||
VectorFloat p = new VectorFloat(c.getLength(element.getAttribute("x")), c.getLength(element.getAttribute("y")));
|
||||
VectorInterface pos0 = p.transform(c.getTransform());
|
||||
VectorInterface pos1 = p.add(new VectorFloat(1, 0)).transform(c.getTransform());
|
||||
@ -290,7 +291,7 @@ public class SvgImporter {
|
||||
drawTextElement(csd, c, element, pos0, pos1);
|
||||
}
|
||||
|
||||
private void drawTextElement(CustomShapeDescription csd, Context c, Element element, VectorInterface pos0, VectorInterface pos1) throws SvgException {
|
||||
private void drawTextElement(CustomShapeDescription.Builder csd, Context c, Element element, VectorInterface pos0, VectorInterface pos1) throws SvgException {
|
||||
NodeList nodes = element.getElementsByTagName("*");
|
||||
if (nodes.getLength() == 0) {
|
||||
String text = element.getTextContent();
|
||||
|
@ -52,7 +52,7 @@ public class CustomShapeEditor extends EditorFactory.LabelEditor<CustomShapeDesc
|
||||
clear = new ToolTipAction(Lang.get("btn_clearData")) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
customShapeDescription = CustomShapeDescription.EMPTY;
|
||||
customShapeDescription = new CustomShapeDescription.Builder().build();
|
||||
}
|
||||
};
|
||||
panel.add(clear.createJButton());
|
||||
|
@ -1010,12 +1010,12 @@ public final class EditorFactory {
|
||||
}
|
||||
|
||||
private InverterConfig getInverterConfig() {
|
||||
InverterConfig ic = new InverterConfig();
|
||||
InverterConfig.Builder ic = new InverterConfig.Builder();
|
||||
for (JCheckBox cb : boxes) {
|
||||
if (cb.isSelected())
|
||||
ic.add(cb.getText());
|
||||
}
|
||||
return ic;
|
||||
return ic.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ public class ROMEditorDialog extends JDialog {
|
||||
for (RomHolder rh : romlist)
|
||||
rm.addRom(rh.ri.getLabel(), rh.data);
|
||||
|
||||
return rm.getMinimized();
|
||||
return rm;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,6 @@ import java.util.ArrayList;
|
||||
* The test data.
|
||||
*/
|
||||
public class TestCaseDescription {
|
||||
|
||||
/**
|
||||
* the default instance
|
||||
*/
|
||||
public static final TestCaseDescription DEFAULT = new TestCaseDescription("");
|
||||
|
||||
private String dataString;
|
||||
private transient LineEmitter lines;
|
||||
private transient ArrayList<String> names;
|
||||
|
@ -18,7 +18,7 @@ public class TestCaseElement implements Element {
|
||||
/**
|
||||
* the used {@link ElementAttributes} key
|
||||
*/
|
||||
public static final Key<TestCaseDescription> TESTDATA = new Key<>("Testdata", TestCaseDescription.DEFAULT);
|
||||
public static final Key<TestCaseDescription> TESTDATA = new Key<>("Testdata", () -> new TestCaseDescription(""));
|
||||
|
||||
/**
|
||||
* The TestCaseElement description
|
||||
|
Loading…
x
Reference in New Issue
Block a user