diff --git a/distribution/ReleaseNotes.txt b/distribution/ReleaseNotes.txt index a79d6325b..c7159f066 100644 --- a/distribution/ReleaseNotes.txt +++ b/distribution/ReleaseNotes.txt @@ -8,10 +8,10 @@ planned as v0.10 - With CTRL + mouse button you can now select and move/delete wires. - Added a real bidirectional switch and a relay. - Added N and P channel FETs and some CMOS examples, including a 16 bit SRAM +- Added a rotary encoder - Improved and documented the file import strategy. - Added a tree view to insert components. - Added support for the ATF1502 and ATF1504 CPLDs. -- Added a rotary encoder - some minor bug fixes v0.9, released on 03. Feb 2017 diff --git a/src/main/java/de/neemann/digital/draw/shapes/InteractorInterface.java b/src/main/java/de/neemann/digital/draw/shapes/InteractorInterface.java index 1c3dd52a5..cb23e150e 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/InteractorInterface.java +++ b/src/main/java/de/neemann/digital/draw/shapes/InteractorInterface.java @@ -10,9 +10,9 @@ import de.neemann.digital.gui.sync.Sync; 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. + * The {@link de.neemann.digital.draw.elements.VisualElement}s InteractorInterface instance is called + * if the element is clicked during execution. So the User can interact with the element. + * Example usage at the {@link InputShape} to let the user toggle the inputs state. * * @author hneemann * @see InputShape @@ -21,9 +21,11 @@ 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 + * @param cc the CircuitComponent + * @param pos the popuplocation on screen + * @param ioState the state of the element + * @param element the element which is clicked + * @param modelSync used to sync model access * @return true if model is changed */ boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync); @@ -31,9 +33,11 @@ public interface InteractorInterface { /** * Called mouse is pressed on running model * - * @param cc the CircuitComponent - * @param pos the popuplocation on screen - * @param ioState the state of the element + * @param cc the CircuitComponent + * @param pos the popuplocation on screen + * @param ioState the state of the element + * @param element the element on which the mouse is pressed + * @param modelSync used to sync model access * @return true if model is changed */ boolean pressed(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync); @@ -41,9 +45,11 @@ public interface InteractorInterface { /** * Called mouse is released on running model * - * @param cc the CircuitComponent - * @param pos the popuplocation on screen - * @param ioState the state of the element + * @param cc the CircuitComponent + * @param pos the popuplocation on screen + * @param ioState the state of the element + * @param element the element on which the mouse is released + * @param modelSync used to sync model access * @return true if model is changed */ boolean released(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync); @@ -55,6 +61,8 @@ public interface InteractorInterface { * @param pos the position in the model coordinates * @param transform transformation to transform shape coordinates to the model coordinates * @param ioState the state of the element + * @param element the element on which the mouse is dragged + * @param modelSync used to sync model access * @return true if model is changed */ boolean dragged(CircuitComponent cc, Vector pos, Transform transform, IOState ioState, Element element, Sync modelSync); diff --git a/src/main/java/de/neemann/digital/draw/shapes/RotEncoderShape.java b/src/main/java/de/neemann/digital/draw/shapes/RotEncoderShape.java index 777111496..692861254 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/RotEncoderShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/RotEncoderShape.java @@ -24,6 +24,7 @@ import static de.neemann.digital.draw.shapes.GenericShape.SIZE2; * @author hneemann */ public class RotEncoderShape implements Shape { + private static final Vector CENTER = new Vector(SIZE2, SIZE2); private final String label; private final PinDescriptions outputs; private int state; @@ -74,7 +75,7 @@ public class RotEncoderShape implements Shape { @Override public boolean dragged(CircuitComponent cc, Vector pos, Transform trans, IOState ioState, Element element, Sync modelSync) { if (ioState != null) { - Vector p = pos.sub(trans.transform(new Vector(SIZE2, SIZE2))); + Vector p = pos.sub(trans.transform(CENTER)); final int dist = p.x * p.x + p.y * p.y; if (dist > 100 && dist < 900) { int s = (int) (Math.atan2(p.y, p.x) / Math.PI * 16); @@ -82,16 +83,12 @@ public class RotEncoderShape implements Shape { initialState = s; initial = false; } else { - // somewhat unusual but ensures that every step is visible to the model. - int ds = 0; - if (s > initialState) ds = 1; - else if (s < initialState) ds = -1; - initialState = s; - if (ds != 0) { - state += ds; + if (s != initialState) { + state += s - initialState; + initialState = s; modelSync.access(() -> { - boolean a = ((state / 2) & 1) != 0; - boolean b = (((state + 1) / 2) & 1) != 0; + boolean a = (state & 2) != 0; + boolean b = ((state + 1) & 2) != 0; ioState.getOutput(0).setBool(a); ioState.getOutput(1).setBool(b); }); @@ -114,14 +111,16 @@ public class RotEncoderShape implements Shape { .add(-SIZE, SIZE * 2) .add(-SIZE, -SIZE), Style.NORMAL); - graphic.drawCircle(new Vector(-SIZE, -SIZE), new Vector(SIZE * 2, SIZE * 2), Style.NORMAL); - graphic.drawCircle(new Vector(-SIZE2, -SIZE2), new Vector(SIZE + SIZE2, SIZE + SIZE2), Style.THIN); + final int r1 = SIZE + SIZE2; + graphic.drawCircle(CENTER.add(-r1, -r1), CENTER.add(r1, r1), Style.NORMAL); + final int r2 = SIZE; + graphic.drawCircle(CENTER.add(-r2, -r2), CENTER.add(r2, r2), Style.THIN); final double alpha = state / 16.0 * Math.PI; int x = (int) ((SIZE + 1) * Math.cos(alpha)); int y = (int) ((SIZE + 1) * Math.sin(alpha)); - graphic.drawLine(new Vector(SIZE2, SIZE2), new Vector(SIZE2 + x, SIZE2 + y), Style.NORMAL); + graphic.drawLine(CENTER, CENTER.add(x, y), Style.NORMAL); Vector textPos = new Vector(SIZE, SIZE * 2 + 4); graphic.drawText(textPos, textPos.add(1, 0), label, Orientation.CENTERTOP, Style.NORMAL);