refactoring of rotary encoder shape

This commit is contained in:
hneemann 2017-04-06 18:21:27 +02:00
parent 93e01bb681
commit bc56bd3fd5
3 changed files with 33 additions and 26 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);