mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 15:26:52 -04:00
interaction is possible
This commit is contained in:
parent
5b9de1b763
commit
fab4d99cc8
@ -3,9 +3,9 @@ package de.neemann.digital.core;
|
|||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class HighZException extends NodeException {
|
public class HighZException extends RuntimeException {
|
||||||
|
|
||||||
public HighZException(ObservableValue... causedObservable) {
|
public HighZException(ObservableValue... causedObservable) {
|
||||||
super("readOfHighZ", causedObservable);
|
super("readOfHighZ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class ObservableValue extends Value {
|
|||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getValue() throws NodeException {
|
public long getValue() {
|
||||||
if (highZ)
|
if (highZ)
|
||||||
throw new HighZException(this);
|
throw new HighZException(this);
|
||||||
return value;
|
return value;
|
||||||
@ -52,7 +52,7 @@ public class ObservableValue extends Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getValueBits() throws NodeException {
|
public long getValueBits() {
|
||||||
return getValueBits(getValue());
|
return getValueBits(getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +68,9 @@ public class Main extends JFrame {
|
|||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
try {
|
try {
|
||||||
ModelDescription m = new ModelDescription(cr);
|
ModelDescription m = new ModelDescription(cr);
|
||||||
Model model = m.create();
|
Model model = m.create(circuitComponent);
|
||||||
System.out.println(model);
|
model.init(true);
|
||||||
|
circuitComponent.setMode(CircuitComponent.Mode.running);
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
new ErrorMessage("error creating model").addCause(e1).show(Main.this);
|
new ErrorMessage("error creating model").addCause(e1).show(Main.this);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.gui.components;
|
package de.neemann.digital.gui.components;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Listener;
|
||||||
import de.neemann.digital.gui.draw.graphics.*;
|
import de.neemann.digital.gui.draw.graphics.*;
|
||||||
import de.neemann.digital.gui.draw.graphics.Polygon;
|
import de.neemann.digital.gui.draw.graphics.Polygon;
|
||||||
import de.neemann.digital.gui.draw.parts.Circuit;
|
import de.neemann.digital.gui.draw.parts.Circuit;
|
||||||
@ -19,7 +20,7 @@ import java.util.ArrayList;
|
|||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class CircuitComponent extends JComponent {
|
public class CircuitComponent extends JComponent implements Listener {
|
||||||
|
|
||||||
private static final String delAction = "myDelAction";
|
private static final String delAction = "myDelAction";
|
||||||
private final Circuit circuit;
|
private final Circuit circuit;
|
||||||
@ -57,7 +58,7 @@ public class CircuitComponent extends JComponent {
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case part:
|
case part:
|
||||||
listener = new PartMouseListener();
|
listener = new PartMouseListener();
|
||||||
setCursor(new Cursor(Cursor.HAND_CURSOR));
|
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
||||||
break;
|
break;
|
||||||
case wire:
|
case wire:
|
||||||
listener = new WireMouseListener();
|
listener = new WireMouseListener();
|
||||||
@ -67,6 +68,10 @@ public class CircuitComponent extends JComponent {
|
|||||||
listener = new SelectMouseListener();
|
listener = new SelectMouseListener();
|
||||||
setCursor(new Cursor(Cursor.MOVE_CURSOR));
|
setCursor(new Cursor(Cursor.MOVE_CURSOR));
|
||||||
break;
|
break;
|
||||||
|
case running:
|
||||||
|
listener = new RunningMouseListener();
|
||||||
|
setCursor(new Cursor(Cursor.HAND_CURSOR));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
addMouseMotionListener(listener);
|
addMouseMotionListener(listener);
|
||||||
addMouseListener(listener);
|
addMouseListener(listener);
|
||||||
@ -86,7 +91,7 @@ public class CircuitComponent extends JComponent {
|
|||||||
g.fillRect(0, 0, getWidth(), getHeight());
|
g.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
|
||||||
GraphicSwing gr = new GraphicSwing((Graphics2D) g);
|
GraphicSwing gr = new GraphicSwing((Graphics2D) g);
|
||||||
circuit.drawTo(gr);
|
circuit.drawTo(gr, null);
|
||||||
|
|
||||||
listener.drawTo(gr);
|
listener.drawTo(gr);
|
||||||
}
|
}
|
||||||
@ -96,7 +101,12 @@ public class CircuitComponent extends JComponent {
|
|||||||
((pos.y + GenericShape.SIZE2) / GenericShape.SIZE) * GenericShape.SIZE);
|
((pos.y + GenericShape.SIZE2) / GenericShape.SIZE) * GenericShape.SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Mode {part, wire, select}
|
@Override
|
||||||
|
public void needsUpdate() {
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Mode {part, wire, running, select}
|
||||||
|
|
||||||
private interface Mouse extends MouseMotionListener, MouseListener {
|
private interface Mouse extends MouseMotionListener, MouseListener {
|
||||||
void drawTo(Graphic gr);
|
void drawTo(Graphic gr);
|
||||||
@ -156,7 +166,7 @@ public class CircuitComponent extends JComponent {
|
|||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic gr) {
|
public void drawTo(Graphic gr) {
|
||||||
if (wire != null)
|
if (wire != null)
|
||||||
wire.drawTo(gr);
|
wire.drawTo(gr, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +242,7 @@ public class CircuitComponent extends JComponent {
|
|||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic gr) {
|
public void drawTo(Graphic gr) {
|
||||||
if (partToInsert != null)
|
if (partToInsert != null)
|
||||||
partToInsert.drawTo(gr);
|
partToInsert.drawTo(gr, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,4 +330,50 @@ public class CircuitComponent extends JComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RunningMouseListener implements Mouse {
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic gr) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
Vector pos = new Vector(e.getX(), e.getY());
|
||||||
|
for (VisualPart vp : circuit.getParts())
|
||||||
|
if (vp.matches(pos)) {
|
||||||
|
vp.clicked(CircuitComponent.this, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ import java.awt.*;
|
|||||||
public class Style {
|
public class Style {
|
||||||
public static final Style NORMAL = new Style(2, false, Color.BLACK);
|
public static final Style NORMAL = new Style(2, false, Color.BLACK);
|
||||||
public static final Style WIRE = new Style(2, true, Color.BLUE);
|
public static final Style WIRE = new Style(2, true, Color.BLUE);
|
||||||
|
public static final Style WIRE_HIGH = new Style(2, true, new Color(0, 153, 255));
|
||||||
public static final Style FILLED = new Style(2, true, Color.BLACK);
|
public static final Style FILLED = new Style(2, true, Color.BLACK);
|
||||||
public static final Style THIN = new Style(1, false, Color.BLACK);
|
public static final Style THIN = new Style(1, false, Color.BLACK);
|
||||||
;
|
|
||||||
|
|
||||||
private final int thickness;
|
private final int thickness;
|
||||||
private final boolean filled;
|
private final boolean filled;
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package de.neemann.digital.gui.draw.model;
|
package de.neemann.digital.gui.draw.model;
|
||||||
|
|
||||||
import de.neemann.digital.core.Model;
|
import de.neemann.digital.core.*;
|
||||||
import de.neemann.digital.core.NodeException;
|
|
||||||
import de.neemann.digital.core.Part;
|
|
||||||
import de.neemann.digital.core.PartDescription;
|
|
||||||
import de.neemann.digital.gui.draw.parts.*;
|
import de.neemann.digital.gui.draw.parts.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -27,20 +24,21 @@ public class ModelDescription {
|
|||||||
Part part = partDescription.create();
|
Part part = partDescription.create();
|
||||||
pins.setOutputs(part.getOutputs());
|
pins.setOutputs(part.getOutputs());
|
||||||
|
|
||||||
entries.add(new ModelEntry(part, pins, partDescription.getInputNames()));
|
entries.add(new ModelEntry(part, pins, vp));
|
||||||
for (Pin p : pins)
|
for (Pin p : pins)
|
||||||
netList.add(p);
|
netList.add(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Model create() throws PinException, NodeException {
|
public Model create(Listener listener) throws PinException, NodeException {
|
||||||
for (Net n : netList)
|
for (Net n : netList)
|
||||||
n.interconnect();
|
n.interconnect();
|
||||||
|
|
||||||
for (ModelEntry e : entries)
|
|
||||||
e.applyInputs();
|
|
||||||
|
|
||||||
Model m = new Model();
|
Model m = new Model();
|
||||||
|
|
||||||
|
for (ModelEntry e : entries)
|
||||||
|
e.applyInputs(listener, m);
|
||||||
|
|
||||||
for (ModelEntry e : entries)
|
for (ModelEntry e : entries)
|
||||||
e.getPart().registerNodes(m);
|
e.getPart().registerNodes(m);
|
||||||
|
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
package de.neemann.digital.gui.draw.model;
|
package de.neemann.digital.gui.draw.model;
|
||||||
|
|
||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.*;
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.gui.draw.parts.*;
|
||||||
import de.neemann.digital.core.Part;
|
|
||||||
import de.neemann.digital.gui.draw.parts.Pin;
|
|
||||||
import de.neemann.digital.gui.draw.parts.PinException;
|
|
||||||
import de.neemann.digital.gui.draw.parts.Pins;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@ -16,18 +12,20 @@ public class ModelEntry {
|
|||||||
private final Part part;
|
private final Part part;
|
||||||
private final Pins pins;
|
private final Pins pins;
|
||||||
private final String[] names;
|
private final String[] names;
|
||||||
|
private final VisualPart visualPart;
|
||||||
|
|
||||||
public ModelEntry(Part part, Pins pins, String[] names) {
|
public ModelEntry(Part part, Pins pins, VisualPart visualPart) {
|
||||||
this.part = part;
|
this.part = part;
|
||||||
this.pins = pins;
|
this.pins = pins;
|
||||||
this.names = names;
|
this.visualPart = visualPart;
|
||||||
|
this.names = visualPart.getPartDescription().getInputNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyInputs() throws PinException, NodeException {
|
public void applyInputs(Listener listener, Model model) throws PinException, NodeException {
|
||||||
HashMap<String, Pin> ins = pins.getInputs();
|
HashMap<String, Pin> ins = pins.getInputs();
|
||||||
|
|
||||||
if (names.length > 0) {
|
|
||||||
ObservableValue[] inputs = new ObservableValue[names.length];
|
ObservableValue[] inputs = new ObservableValue[names.length];
|
||||||
|
if (names.length > 0) {
|
||||||
for (int i = 0; i < names.length; i++) {
|
for (int i = 0; i < names.length; i++) {
|
||||||
Pin pin = ins.get(names[i]);
|
Pin pin = ins.get(names[i]);
|
||||||
if (pin == null)
|
if (pin == null)
|
||||||
@ -41,6 +39,7 @@ public class ModelEntry {
|
|||||||
}
|
}
|
||||||
part.setInputs(inputs);
|
part.setInputs(inputs);
|
||||||
}
|
}
|
||||||
|
visualPart.setState(new State(inputs, part.getOutputs()), listener, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Part getPart() {
|
public Part getPart() {
|
||||||
|
@ -24,13 +24,13 @@ public class Circuit implements Drawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic graphic) {
|
public void drawTo(Graphic graphic, State state) {
|
||||||
for (Wire w : wires)
|
for (Wire w : wires)
|
||||||
w.drawTo(graphic);
|
w.drawTo(graphic, state);
|
||||||
for (Vector d : dots)
|
for (Vector d : dots)
|
||||||
graphic.drawCircle(d.sub(RAD), d.add(RAD), Style.WIRE);
|
graphic.drawCircle(d.sub(RAD), d.add(RAD), Style.WIRE);
|
||||||
for (VisualPart p : visualParts)
|
for (VisualPart p : visualParts)
|
||||||
p.drawTo(graphic);
|
p.drawTo(graphic, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(VisualPart visualPart) {
|
public void add(VisualPart visualPart) {
|
||||||
|
24
src/main/java/de/neemann/digital/gui/draw/parts/State.java
Normal file
24
src/main/java/de/neemann/digital/gui/draw/parts/State.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package de.neemann.digital.gui.draw.parts;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.ObservableValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class State {
|
||||||
|
private final ObservableValue[] inputs;
|
||||||
|
private final ObservableValue[] outputs;
|
||||||
|
|
||||||
|
public State(ObservableValue[] inputs, ObservableValue[] outputs) {
|
||||||
|
this.inputs = inputs;
|
||||||
|
this.outputs = outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue getInput(int i) {
|
||||||
|
return inputs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue getOutput(int i) {
|
||||||
|
return outputs[i];
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,12 @@
|
|||||||
package de.neemann.digital.gui.draw.parts;
|
package de.neemann.digital.gui.draw.parts;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Listener;
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.PartDescription;
|
import de.neemann.digital.core.PartDescription;
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
import de.neemann.digital.gui.draw.graphics.*;
|
import de.neemann.digital.gui.draw.graphics.*;
|
||||||
import de.neemann.digital.gui.draw.shapes.Drawable;
|
import de.neemann.digital.gui.draw.shapes.Drawable;
|
||||||
|
import de.neemann.digital.gui.draw.shapes.Interactor;
|
||||||
import de.neemann.digital.gui.draw.shapes.Shape;
|
import de.neemann.digital.gui.draw.shapes.Shape;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@ -18,6 +22,8 @@ public class VisualPart implements Drawable, Moveable {
|
|||||||
private transient GraphicMinMax minMax;
|
private transient GraphicMinMax minMax;
|
||||||
private Vector pos;
|
private Vector pos;
|
||||||
private int rotate;
|
private int rotate;
|
||||||
|
private State state;
|
||||||
|
private Interactor interactor;
|
||||||
|
|
||||||
public VisualPart(PartDescription partDescription) {
|
public VisualPart(PartDescription partDescription) {
|
||||||
this.partDescription = partDescription;
|
this.partDescription = partDescription;
|
||||||
@ -61,10 +67,10 @@ public class VisualPart implements Drawable, Moveable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic graphic) {
|
public void drawTo(Graphic graphic, State state) {
|
||||||
Graphic gr = new GraphicTransform(graphic, createTransform());
|
Graphic gr = new GraphicTransform(graphic, createTransform());
|
||||||
Shape shape = partDescription.getShape();
|
Shape shape = partDescription.getShape();
|
||||||
shape.drawTo(gr);
|
shape.drawTo(gr, this.state);
|
||||||
for (Pin p : shape.getPins(partDescription))
|
for (Pin p : shape.getPins(partDescription))
|
||||||
gr.drawCircle(p.getPos().add(-PIN, -PIN), p.getPos().add(PIN, PIN), p.getDirection() == Pin.Direction.input ? Style.NORMAL : Style.FILLED);
|
gr.drawCircle(p.getPos().add(-PIN, -PIN), p.getPos().add(PIN, PIN), p.getDirection() == Pin.Direction.input ? Style.NORMAL : Style.FILLED);
|
||||||
}
|
}
|
||||||
@ -76,7 +82,7 @@ public class VisualPart implements Drawable, Moveable {
|
|||||||
public GraphicMinMax getMinMax() {
|
public GraphicMinMax getMinMax() {
|
||||||
if (minMax == null) {
|
if (minMax == null) {
|
||||||
minMax = new GraphicMinMax();
|
minMax = new GraphicMinMax();
|
||||||
drawTo(minMax);
|
drawTo(minMax, state);
|
||||||
}
|
}
|
||||||
return minMax;
|
return minMax;
|
||||||
}
|
}
|
||||||
@ -99,7 +105,7 @@ public class VisualPart implements Drawable, Moveable {
|
|||||||
gr.fillRect(0, 0, bi.getWidth(), bi.getHeight());
|
gr.fillRect(0, 0, bi.getWidth(), bi.getHeight());
|
||||||
gr.translate(-mm.getMin().x, -mm.getMin().y);
|
gr.translate(-mm.getMin().x, -mm.getMin().y);
|
||||||
GraphicSwing grs = new GraphicSwing(gr);
|
GraphicSwing grs = new GraphicSwing(gr);
|
||||||
drawTo(grs);
|
drawTo(grs, state);
|
||||||
return new ImageIcon(bi);
|
return new ImageIcon(bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,4 +122,21 @@ public class VisualPart implements Drawable, Moveable {
|
|||||||
transformed.add(new Pin(tr.transform(p.getPos()), p));
|
transformed.add(new Pin(tr.transform(p.getPos()), p));
|
||||||
return transformed;
|
return transformed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of the parts inputs and outputs
|
||||||
|
*
|
||||||
|
* @param state actual state
|
||||||
|
* @param listener
|
||||||
|
* @param model
|
||||||
|
*/
|
||||||
|
public void setState(State state, Listener listener, Model model) {
|
||||||
|
this.state = state;
|
||||||
|
interactor = partDescription.getShape().applyStateMonitor(state, listener, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clicked(CircuitComponent cc, Vector pos) {
|
||||||
|
if (interactor != null)
|
||||||
|
interactor.interact(cc, pos, state);
|
||||||
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ public class Wire implements Drawable, Moveable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic graphic) {
|
public void drawTo(Graphic graphic, State state) {
|
||||||
graphic.drawLine(p1, p2, Style.WIRE);
|
graphic.drawLine(p1, p2, Style.WIRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
package de.neemann.digital.gui.draw.shapes;
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
import de.neemann.digital.gui.draw.graphics.Graphic;
|
import de.neemann.digital.gui.draw.graphics.Graphic;
|
||||||
|
import de.neemann.digital.gui.draw.parts.State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public interface Drawable {
|
public interface Drawable {
|
||||||
void drawTo(Graphic graphic);
|
/**
|
||||||
|
* Draws a part depending on its state
|
||||||
|
*
|
||||||
|
* @param graphic
|
||||||
|
* @param state maybe null
|
||||||
|
*/
|
||||||
|
void drawTo(Graphic graphic, State state);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package de.neemann.digital.gui.draw.shapes;
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Listener;
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.core.ObservableValue;
|
||||||
import de.neemann.digital.core.PartDescription;
|
import de.neemann.digital.core.PartDescription;
|
||||||
import de.neemann.digital.gui.draw.graphics.Graphic;
|
import de.neemann.digital.gui.draw.graphics.Graphic;
|
||||||
@ -8,6 +10,7 @@ import de.neemann.digital.gui.draw.graphics.Style;
|
|||||||
import de.neemann.digital.gui.draw.graphics.Vector;
|
import de.neemann.digital.gui.draw.graphics.Vector;
|
||||||
import de.neemann.digital.gui.draw.parts.Pin;
|
import de.neemann.digital.gui.draw.parts.Pin;
|
||||||
import de.neemann.digital.gui.draw.parts.Pins;
|
import de.neemann.digital.gui.draw.parts.Pins;
|
||||||
|
import de.neemann.digital.gui.draw.parts.State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
@ -72,7 +75,12 @@ public class GenericShape implements Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic graphic) {
|
public Interactor applyStateMonitor(State state, Listener listener, Model model) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic graphic, State state) {
|
||||||
int max = Math.max(inputs, outputs);
|
int max = Math.max(inputs, outputs);
|
||||||
int height = (max - 1) * SIZE + SIZE2;
|
int height = (max - 1) * SIZE + SIZE2;
|
||||||
|
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
package de.neemann.digital.gui.draw.shapes;
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Listener;
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
|
import de.neemann.digital.core.NodeException;
|
||||||
import de.neemann.digital.core.PartDescription;
|
import de.neemann.digital.core.PartDescription;
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
import de.neemann.digital.gui.draw.graphics.Graphic;
|
import de.neemann.digital.gui.draw.graphics.Graphic;
|
||||||
import de.neemann.digital.gui.draw.graphics.Polygon;
|
import de.neemann.digital.gui.draw.graphics.Polygon;
|
||||||
import de.neemann.digital.gui.draw.graphics.Style;
|
import de.neemann.digital.gui.draw.graphics.Style;
|
||||||
import de.neemann.digital.gui.draw.graphics.Vector;
|
import de.neemann.digital.gui.draw.graphics.Vector;
|
||||||
import de.neemann.digital.gui.draw.parts.Pin;
|
import de.neemann.digital.gui.draw.parts.Pin;
|
||||||
import de.neemann.digital.gui.draw.parts.Pins;
|
import de.neemann.digital.gui.draw.parts.Pins;
|
||||||
|
import de.neemann.digital.gui.draw.parts.State;
|
||||||
|
|
||||||
import static de.neemann.digital.gui.draw.shapes.OutputShape.SIZE;
|
import static de.neemann.digital.gui.draw.shapes.OutputShape.SIZE;
|
||||||
|
|
||||||
@ -16,6 +21,7 @@ import static de.neemann.digital.gui.draw.shapes.OutputShape.SIZE;
|
|||||||
public class InputShape implements Shape {
|
public class InputShape implements Shape {
|
||||||
|
|
||||||
private final int bits;
|
private final int bits;
|
||||||
|
private long lastValue = 0;
|
||||||
|
|
||||||
public InputShape(int bits) {
|
public InputShape(int bits) {
|
||||||
this.bits = bits;
|
this.bits = bits;
|
||||||
@ -27,7 +33,37 @@ public class InputShape implements Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic graphic) {
|
public Interactor applyStateMonitor(State state, Listener listener, Model model) {
|
||||||
graphic.drawPolygon(new Polygon(true).add(-SIZE * 2 - 2, -SIZE).add(-2, -SIZE).add(-2, SIZE).add(-SIZE * 2 - 2, SIZE), Style.NORMAL);
|
state.getOutput(0).addListener(new Listener() {
|
||||||
|
@Override
|
||||||
|
public void needsUpdate() {
|
||||||
|
long value = state.getOutput(0).getValue();
|
||||||
|
if (lastValue != value) {
|
||||||
|
lastValue = value;
|
||||||
|
listener.needsUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new Interactor() {
|
||||||
|
@Override
|
||||||
|
public void interact(CircuitComponent cc, Vector pos, State state) {
|
||||||
|
long v = state.getOutput(0).getValue();
|
||||||
|
state.getOutput(0).setValue(1 - v);
|
||||||
|
try {
|
||||||
|
model.doStep();
|
||||||
|
} catch (NodeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic graphic, State state) {
|
||||||
|
Style style = Style.WIRE;
|
||||||
|
if (state != null && state.getOutput(0).getValue() != 0)
|
||||||
|
style = Style.WIRE_HIGH;
|
||||||
|
|
||||||
|
graphic.drawPolygon(new Polygon(true).add(-SIZE * 2 - 2, -SIZE).add(-2, -SIZE).add(-2, SIZE).add(-SIZE * 2 - 2, SIZE), style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Vector;
|
||||||
|
import de.neemann.digital.gui.draw.parts.State;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public interface Interactor {
|
||||||
|
void interact(CircuitComponent cc, Vector pos, State state);
|
||||||
|
}
|
@ -1,11 +1,14 @@
|
|||||||
package de.neemann.digital.gui.draw.shapes;
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Listener;
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.PartDescription;
|
import de.neemann.digital.core.PartDescription;
|
||||||
import de.neemann.digital.gui.draw.graphics.Graphic;
|
import de.neemann.digital.gui.draw.graphics.Graphic;
|
||||||
import de.neemann.digital.gui.draw.graphics.Style;
|
import de.neemann.digital.gui.draw.graphics.Style;
|
||||||
import de.neemann.digital.gui.draw.graphics.Vector;
|
import de.neemann.digital.gui.draw.graphics.Vector;
|
||||||
import de.neemann.digital.gui.draw.parts.Pin;
|
import de.neemann.digital.gui.draw.parts.Pin;
|
||||||
import de.neemann.digital.gui.draw.parts.Pins;
|
import de.neemann.digital.gui.draw.parts.Pins;
|
||||||
|
import de.neemann.digital.gui.draw.parts.State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
@ -24,7 +27,28 @@ public class OutputShape implements Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic graphic) {
|
public Interactor applyStateMonitor(State state, Listener listener, Model model) {
|
||||||
graphic.drawCircle(new Vector(2 + SIZE * 2, -SIZE), new Vector(2, SIZE), Style.NORMAL);
|
state.getInput(0).addListener(new Listener() {
|
||||||
|
public long lastValue = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void needsUpdate() {
|
||||||
|
long value = state.getInput(0).getValue();
|
||||||
|
if (lastValue != value) {
|
||||||
|
lastValue = value;
|
||||||
|
listener.needsUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic graphic, State state) {
|
||||||
|
Style style = Style.WIRE;
|
||||||
|
if (state != null && state.getInput(0).getValue() != 0)
|
||||||
|
style = Style.WIRE_HIGH;
|
||||||
|
|
||||||
|
graphic.drawCircle(new Vector(2 + SIZE * 2, -SIZE), new Vector(2, SIZE), style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package de.neemann.digital.gui.draw.shapes;
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Listener;
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.PartDescription;
|
import de.neemann.digital.core.PartDescription;
|
||||||
import de.neemann.digital.gui.draw.parts.Pins;
|
import de.neemann.digital.gui.draw.parts.Pins;
|
||||||
|
import de.neemann.digital.gui.draw.parts.State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
@ -11,9 +14,19 @@ public interface Shape extends Drawable {
|
|||||||
/**
|
/**
|
||||||
* Puts the pins name and the pins x-y-position together!
|
* Puts the pins name and the pins x-y-position together!
|
||||||
*
|
*
|
||||||
* @param partDescription
|
* @param partDescription the description of the part
|
||||||
* @return the pins
|
* @return the pins
|
||||||
*/
|
*/
|
||||||
Pins getPins(PartDescription partDescription);
|
Pins getPins(PartDescription partDescription);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the look of the shape depends on an input or output state, the
|
||||||
|
* shape can register a state monitor to the state.
|
||||||
|
* If the monitor decides to update the GUI it can call listener.needsUpdate.
|
||||||
|
* Caution: Don't store state in the shape itself!
|
||||||
|
*
|
||||||
|
* @param state the state
|
||||||
|
*/
|
||||||
|
Interactor applyStateMonitor(State state, Listener listener, Model model);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public interface StateMonitor {
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user