mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 17:04:42 -04:00
Interactor allows reactions on mouse pressed and mouse released.
Added a button
This commit is contained in:
parent
48b7ced179
commit
3aecf4150f
43
src/main/java/de/neemann/digital/core/io/Button.java
Normal file
43
src/main/java/de/neemann/digital/core/io/Button.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package de.neemann.digital.core.io;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
|
import de.neemann.digital.core.NodeException;
|
||||||
|
import de.neemann.digital.core.ObservableValue;
|
||||||
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Button implements Element {
|
||||||
|
|
||||||
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Button.class)
|
||||||
|
.addAttribute(AttributeKey.Rotate)
|
||||||
|
.addAttribute(AttributeKey.Label);
|
||||||
|
|
||||||
|
private final ObservableValue output;
|
||||||
|
private final String label;
|
||||||
|
|
||||||
|
public Button(ElementAttributes attributes) {
|
||||||
|
output = new ObservableValue("out", 1);
|
||||||
|
label = attributes.get(AttributeKey.Label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInputs(ObservableValue... inputs) throws NodeException {
|
||||||
|
throw new NodeException(Lang.get("err_noInputsAvailable"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableValue[] getOutputs() {
|
||||||
|
return new ObservableValue[]{output};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerNodes(Model model) {
|
||||||
|
model.addSignal(label, output);
|
||||||
|
}
|
||||||
|
}
|
@ -6,10 +6,8 @@ import de.neemann.digital.core.element.AttributeListener;
|
|||||||
import de.neemann.digital.core.element.Element;
|
import de.neemann.digital.core.element.Element;
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.draw.graphics.*;
|
import de.neemann.digital.draw.graphics.*;
|
||||||
import de.neemann.digital.draw.shapes.Drawable;
|
import de.neemann.digital.draw.shapes.*;
|
||||||
import de.neemann.digital.draw.shapes.Interactor;
|
|
||||||
import de.neemann.digital.draw.shapes.Shape;
|
import de.neemann.digital.draw.shapes.Shape;
|
||||||
import de.neemann.digital.draw.shapes.ShapeFactory;
|
|
||||||
import de.neemann.digital.gui.components.CircuitComponent;
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@ -29,7 +27,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
|
|||||||
private transient GraphicMinMax minMax;
|
private transient GraphicMinMax minMax;
|
||||||
private transient Shape shape;
|
private transient Shape shape;
|
||||||
private transient IOState ioState;
|
private transient IOState ioState;
|
||||||
private transient Interactor interactor;
|
private transient InteractorInterface interactor;
|
||||||
private transient Element element;
|
private transient Element element;
|
||||||
private transient ShapeFactory shapeFactory;
|
private transient ShapeFactory shapeFactory;
|
||||||
private Vector pos;
|
private Vector pos;
|
||||||
@ -267,20 +265,51 @@ public class VisualElement implements Drawable, Moveable, AttributeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is called if this element is clicked by the mouse.
|
* Is called if this element is clicked with the mouse.
|
||||||
* the call is delegated to the {@link Interactor} of the {@link Shape}
|
* The call is delegated to the {@link Interactor} of the {@link Shape}
|
||||||
*
|
*
|
||||||
* @param cc the calling {@link CircuitComponent}
|
* @param cc the calling {@link CircuitComponent}
|
||||||
* @param pos the position
|
* @param pos the position
|
||||||
* @return true if model is changed
|
* @return true if model is changed
|
||||||
*/
|
*/
|
||||||
public boolean clicked(CircuitComponent cc, Point pos) {
|
public boolean elementClicked(CircuitComponent cc, Point pos) {
|
||||||
if (interactor != null)
|
if (interactor != null)
|
||||||
return interactor.clicked(cc, pos, ioState, element);
|
return interactor.clicked(cc, pos, ioState, element);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is called if this element is clicked with the mouse.
|
||||||
|
* The call is delegated to the {@link Interactor} of the {@link Shape}
|
||||||
|
*
|
||||||
|
* @param cc the calling {@link CircuitComponent}
|
||||||
|
* @param pos the position
|
||||||
|
* @return true if model is changed
|
||||||
|
*/
|
||||||
|
public boolean elementPressed(CircuitComponent cc, Point pos) {
|
||||||
|
if (interactor != null)
|
||||||
|
return interactor.pressed(cc, pos, ioState, element);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is called if this element is clicked with the mouse.
|
||||||
|
* The call is delegated to the {@link Interactor} of the {@link Shape}
|
||||||
|
*
|
||||||
|
* @param cc the calling {@link CircuitComponent}
|
||||||
|
* @param pos the position
|
||||||
|
* @return true if model is changed
|
||||||
|
*/
|
||||||
|
public boolean elementReleased(CircuitComponent cc, Point pos) {
|
||||||
|
if (interactor != null)
|
||||||
|
return interactor.released(cc, pos, ioState, element);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attributeChanged(AttributeKey key) {
|
public void attributeChanged(AttributeKey key) {
|
||||||
shape = null;
|
shape = null;
|
||||||
|
@ -2,6 +2,8 @@ package de.neemann.digital.draw.graphics;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.GeneralPath;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to draw on a {@link Graphics2D} instance.
|
* Used to draw on a {@link Graphics2D} instance.
|
||||||
@ -32,13 +34,18 @@ public class GraphicSwing implements Graphic {
|
|||||||
@Override
|
@Override
|
||||||
public void drawPolygon(Polygon p, Style style) {
|
public void drawPolygon(Polygon p, Style style) {
|
||||||
applyStyle(style);
|
applyStyle(style);
|
||||||
java.awt.Polygon poly = new java.awt.Polygon();
|
Path2D path = new GeneralPath();
|
||||||
|
boolean first = true;
|
||||||
for (Vector v : p)
|
for (Vector v : p)
|
||||||
poly.addPoint(v.x, v.y);
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
path.moveTo(v.x, v.y);
|
||||||
|
} else
|
||||||
|
path.lineTo(v.x, v.y);
|
||||||
|
|
||||||
if (style.isFilled())
|
if (p.isClosed())
|
||||||
gr.fill(poly);
|
path.closePath();
|
||||||
gr.draw(poly);
|
gr.draw(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,10 +10,7 @@ import de.neemann.digital.core.flipflops.D_FF;
|
|||||||
import de.neemann.digital.core.flipflops.JK_FF;
|
import de.neemann.digital.core.flipflops.JK_FF;
|
||||||
import de.neemann.digital.core.flipflops.RS_FF;
|
import de.neemann.digital.core.flipflops.RS_FF;
|
||||||
import de.neemann.digital.core.flipflops.T_FF;
|
import de.neemann.digital.core.flipflops.T_FF;
|
||||||
import de.neemann.digital.core.io.Const;
|
import de.neemann.digital.core.io.*;
|
||||||
import de.neemann.digital.core.io.In;
|
|
||||||
import de.neemann.digital.core.io.Out;
|
|
||||||
import de.neemann.digital.core.io.Probe;
|
|
||||||
import de.neemann.digital.core.memory.*;
|
import de.neemann.digital.core.memory.*;
|
||||||
import de.neemann.digital.core.wiring.*;
|
import de.neemann.digital.core.wiring.*;
|
||||||
import de.neemann.digital.gui.components.data.DummyElement;
|
import de.neemann.digital.gui.components.data.DummyElement;
|
||||||
@ -51,6 +48,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
|||||||
add(In.DESCRIPTION, menu);
|
add(In.DESCRIPTION, menu);
|
||||||
add(Out.DESCRIPTION, menu);
|
add(Out.DESCRIPTION, menu);
|
||||||
add(Out.LEDDESCRIPTION, menu);
|
add(Out.LEDDESCRIPTION, menu);
|
||||||
|
add(Button.DESCRIPTION, menu);
|
||||||
add(Probe.DESCRIPTION, menu);
|
add(Probe.DESCRIPTION, menu);
|
||||||
add(Clock.DESCRIPTION, menu);
|
add(Clock.DESCRIPTION, menu);
|
||||||
add(Reset.DESCRIPTION, menu);
|
add(Reset.DESCRIPTION, menu);
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
package de.neemann.digital.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.ObservableValue;
|
||||||
|
import de.neemann.digital.core.Observer;
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
import de.neemann.digital.draw.elements.IOState;
|
||||||
|
import de.neemann.digital.draw.elements.Pin;
|
||||||
|
import de.neemann.digital.draw.elements.Pins;
|
||||||
|
import de.neemann.digital.draw.graphics.*;
|
||||||
|
import de.neemann.digital.draw.graphics.Polygon;
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
import static de.neemann.digital.draw.shapes.OutputShape.SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class ButtonShape implements Shape {
|
||||||
|
|
||||||
|
private static final int HEIGHT = SIZE / 2;
|
||||||
|
|
||||||
|
private final String label;
|
||||||
|
private IOState ioState;
|
||||||
|
|
||||||
|
public ButtonShape(ElementAttributes attr) {
|
||||||
|
this.label = attr.getLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pins getPins() {
|
||||||
|
return new Pins().add(new Pin(new Vector(0, 0), "out", Pin.Direction.output));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) {
|
||||||
|
this.ioState = ioState;
|
||||||
|
ioState.getOutput(0).addObserverToValue(guiObserver);
|
||||||
|
return new InteractorInterface() {
|
||||||
|
@Override
|
||||||
|
public boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean pressed(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
|
ObservableValue value = ioState.getOutput(0);
|
||||||
|
value.setValue(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean released(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
|
ObservableValue value = ioState.getOutput(0);
|
||||||
|
value.setValue(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic graphic, boolean heighLight) {
|
||||||
|
boolean down = false;
|
||||||
|
if (ioState != null) down = ioState.getOutput(0).getBool();
|
||||||
|
|
||||||
|
if (down) {
|
||||||
|
graphic.drawPolygon(new Polygon(true)
|
||||||
|
.add(-SIZE * 2 - 1, -SIZE)
|
||||||
|
.add(-1, -SIZE)
|
||||||
|
.add(-1, SIZE)
|
||||||
|
.add(-SIZE * 2 - 1, SIZE), Style.NORMAL);
|
||||||
|
} else {
|
||||||
|
int t = Style.NORMAL.getThickness() / 4;
|
||||||
|
graphic.drawPolygon(new Polygon(true)
|
||||||
|
.add(-SIZE * 2 - 1 - HEIGHT, -SIZE - HEIGHT)
|
||||||
|
.add(-1 - HEIGHT, -SIZE - HEIGHT)
|
||||||
|
.add(-1, -SIZE)
|
||||||
|
.add(-1, SIZE)
|
||||||
|
.add(-SIZE * 2 - 1, SIZE)
|
||||||
|
.add(-SIZE * 2 - 1 - HEIGHT, SIZE - HEIGHT), Style.NORMAL);
|
||||||
|
graphic.drawPolygon(new Polygon(false)
|
||||||
|
.add(-1 - HEIGHT, -SIZE + t - HEIGHT)
|
||||||
|
.add(-1 - HEIGHT, SIZE - HEIGHT)
|
||||||
|
.add(t - SIZE * 2 - 1 - HEIGHT, SIZE - HEIGHT), Style.NORMAL);
|
||||||
|
graphic.drawLine(new Vector(-1 - HEIGHT, SIZE - HEIGHT), new Vector(-1 - t, SIZE - t), Style.NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector textPos = new Vector(-SIZE * 3, -4);
|
||||||
|
graphic.drawText(textPos, textPos.add(1, 0), label, Orientation.RIGHTCENTER, Style.NORMAL);
|
||||||
|
}
|
||||||
|
}
|
@ -4,16 +4,19 @@ import de.neemann.digital.core.Model;
|
|||||||
import de.neemann.digital.core.ModelEvent;
|
import de.neemann.digital.core.ModelEvent;
|
||||||
import de.neemann.digital.core.Observer;
|
import de.neemann.digital.core.Observer;
|
||||||
import de.neemann.digital.core.element.AttributeKey;
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.draw.elements.IOState;
|
import de.neemann.digital.draw.elements.IOState;
|
||||||
import de.neemann.digital.draw.elements.Pins;
|
import de.neemann.digital.draw.elements.Pins;
|
||||||
import de.neemann.digital.draw.graphics.Graphic;
|
import de.neemann.digital.draw.graphics.Graphic;
|
||||||
import de.neemann.digital.draw.model.ModelDescription;
|
import de.neemann.digital.draw.model.ModelDescription;
|
||||||
import de.neemann.digital.draw.model.ModelEntry;
|
import de.neemann.digital.draw.model.ModelEntry;
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
import de.neemann.digital.gui.components.OrderMerger;
|
import de.neemann.digital.gui.components.OrderMerger;
|
||||||
import de.neemann.digital.gui.components.data.DataSet;
|
import de.neemann.digital.gui.components.data.DataSet;
|
||||||
import de.neemann.digital.gui.components.data.DataSetObserver;
|
import de.neemann.digital.gui.components.data.DataSetObserver;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,9 +43,12 @@ public class DataShape implements Shape {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Interactor applyStateMonitor(IOState ioState, Observer guiObserver) {
|
public Interactor applyStateMonitor(IOState ioState, Observer guiObserver) {
|
||||||
return (cc, pos, ioState1, element) -> {
|
return new Interactor() {
|
||||||
|
@Override
|
||||||
|
public boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
dataSet.clear();
|
dataSet.clear();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,15 +14,15 @@ import java.awt.*;
|
|||||||
* @author hneemann
|
* @author hneemann
|
||||||
* @see InputShape
|
* @see InputShape
|
||||||
*/
|
*/
|
||||||
public interface Interactor {
|
public abstract class Interactor implements InteractorInterface {
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Called if clicked on running model
|
public boolean pressed(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
*
|
return false;
|
||||||
* @param cc the CircuitComponent
|
}
|
||||||
* @param pos the popuplocation on screen
|
|
||||||
* @param ioState the state of the element
|
@Override
|
||||||
* @return true if model is changed
|
public boolean released(CircuitComponent cc, Point pos, IOState ioState, Element element) {
|
||||||
*/
|
return false;
|
||||||
boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element);
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package de.neemann.digital.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
|
import de.neemann.digital.draw.elements.IOState;
|
||||||
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The VisualParts InteractorInterface instance is called if the element is clicked
|
||||||
|
* during execution. So the User can interact with the element during execution.
|
||||||
|
* Used at the InputShape to let the user toggle the inputs state.
|
||||||
|
*
|
||||||
|
* @author hneemann
|
||||||
|
* @see InputShape
|
||||||
|
*/
|
||||||
|
public interface InteractorInterface {
|
||||||
|
/**
|
||||||
|
* Called if clicked on running model
|
||||||
|
*
|
||||||
|
* @param cc the CircuitComponent
|
||||||
|
* @param pos the popuplocation on screen
|
||||||
|
* @param ioState the state of the element
|
||||||
|
* @return true if model is changed
|
||||||
|
*/
|
||||||
|
boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called mouse is pressed on running model
|
||||||
|
*
|
||||||
|
* @param cc the CircuitComponent
|
||||||
|
* @param pos the popuplocation on screen
|
||||||
|
* @param ioState the state of the element
|
||||||
|
* @return true if model is changed
|
||||||
|
*/
|
||||||
|
boolean pressed(CircuitComponent cc, Point pos, IOState ioState, Element element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called mouse is released on running model
|
||||||
|
*
|
||||||
|
* @param cc the CircuitComponent
|
||||||
|
* @param pos the popuplocation on screen
|
||||||
|
* @param ioState the state of the element
|
||||||
|
* @return true if model is changed
|
||||||
|
*/
|
||||||
|
boolean released(CircuitComponent cc, Point pos, IOState ioState, Element element);
|
||||||
|
}
|
@ -34,7 +34,7 @@ public interface Shape extends Drawable {
|
|||||||
* @param guiObserver can be used to update the GUI by calling hasChanged, maybe null
|
* @param guiObserver can be used to update the GUI by calling hasChanged, maybe null
|
||||||
* @return the interactor is called if the shape is clicked during running mode, maybe null
|
* @return the interactor is called if the shape is clicked during running mode, maybe null
|
||||||
*/
|
*/
|
||||||
Interactor applyStateMonitor(IOState ioState, Observer guiObserver);
|
InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the shape to make its drawing dependent of the model.
|
* Allows the shape to make its drawing dependent of the model.
|
||||||
|
@ -6,10 +6,7 @@ import de.neemann.digital.core.basic.*;
|
|||||||
import de.neemann.digital.core.element.AttributeKey;
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
import de.neemann.digital.core.io.Const;
|
import de.neemann.digital.core.io.*;
|
||||||
import de.neemann.digital.core.io.In;
|
|
||||||
import de.neemann.digital.core.io.Out;
|
|
||||||
import de.neemann.digital.core.io.Probe;
|
|
||||||
import de.neemann.digital.core.memory.RAMDualPort;
|
import de.neemann.digital.core.memory.RAMDualPort;
|
||||||
import de.neemann.digital.core.memory.RAMSinglePort;
|
import de.neemann.digital.core.memory.RAMSinglePort;
|
||||||
import de.neemann.digital.core.wiring.*;
|
import de.neemann.digital.core.wiring.*;
|
||||||
@ -48,6 +45,7 @@ public final class ShapeFactory {
|
|||||||
map.put(Const.DESCRIPTION.getName(), ConstShape::new);
|
map.put(Const.DESCRIPTION.getName(), ConstShape::new);
|
||||||
map.put(Out.DESCRIPTION.getName(), OutputShape::new);
|
map.put(Out.DESCRIPTION.getName(), OutputShape::new);
|
||||||
map.put(Out.LEDDESCRIPTION.getName(), LEDShape::new);
|
map.put(Out.LEDDESCRIPTION.getName(), LEDShape::new);
|
||||||
|
map.put(Button.DESCRIPTION.getName(), ButtonShape::new);
|
||||||
map.put(Probe.DESCRIPTION.getName(), ProbeShape::new);
|
map.put(Probe.DESCRIPTION.getName(), ProbeShape::new);
|
||||||
map.put(Clock.DESCRIPTION.getName(), ClockShape::new);
|
map.put(Clock.DESCRIPTION.getName(), ClockShape::new);
|
||||||
map.put(Out.SEVENDESCRIPTION.getName(), SevenSegShape::new);
|
map.put(Out.SEVENDESCRIPTION.getName(), SevenSegShape::new);
|
||||||
|
@ -242,6 +242,7 @@ public class CircuitComponent extends JComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a circuit to this component
|
* Sets a circuit to this component
|
||||||
|
*
|
||||||
* @param circuit the circuit
|
* @param circuit the circuit
|
||||||
*/
|
*/
|
||||||
public void setCircuit(Circuit circuit) {
|
public void setCircuit(Circuit circuit) {
|
||||||
@ -709,19 +710,42 @@ public class CircuitComponent extends JComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface Actor {
|
||||||
|
boolean interact(CircuitComponent cc, Point p);
|
||||||
|
}
|
||||||
|
|
||||||
private final class MouseControllerRun extends MouseController {
|
private final class MouseControllerRun extends MouseController {
|
||||||
|
|
||||||
private MouseControllerRun(Cursor cursor) {
|
private MouseControllerRun(Cursor cursor) {
|
||||||
super(cursor);
|
super(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void pressed(MouseEvent e) {
|
||||||
|
VisualElement ve = circuit.getElementAt(getPosVector(e));
|
||||||
|
if (ve != null)
|
||||||
|
interact(e, ve::elementPressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void released(MouseEvent e) {
|
||||||
|
VisualElement ve = circuit.getElementAt(getPosVector(e));
|
||||||
|
if (ve != null)
|
||||||
|
interact(e, ve::elementReleased);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void clicked(MouseEvent e) {
|
void clicked(MouseEvent e) {
|
||||||
VisualElement ve = circuit.getElementAt(getPosVector(e));
|
VisualElement ve = circuit.getElementAt(getPosVector(e));
|
||||||
if (ve != null) {
|
if (ve != null)
|
||||||
|
interact(e, ve::elementClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void interact(MouseEvent e, Actor actor) {
|
||||||
Point p = new Point(e.getX(), e.getY());
|
Point p = new Point(e.getX(), e.getY());
|
||||||
SwingUtilities.convertPointToScreen(p, CircuitComponent.this);
|
SwingUtilities.convertPointToScreen(p, CircuitComponent.this);
|
||||||
boolean modelHasChanged = ve.clicked(CircuitComponent.this, p);
|
boolean modelHasChanged = actor.interact(CircuitComponent.this, p);
|
||||||
if (modelHasChanged) {
|
if (modelHasChanged) {
|
||||||
if (manualChangeObserver != null)
|
if (manualChangeObserver != null)
|
||||||
manualChangeObserver.hasChanged();
|
manualChangeObserver.hasChanged();
|
||||||
@ -729,6 +753,5 @@ public class CircuitComponent extends JComponent {
|
|||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user