added "active low" option to button.

This commit is contained in:
hneemann 2017-06-26 13:07:12 +02:00
parent 493328416d
commit 04de28b577
5 changed files with 51 additions and 20 deletions

View File

@ -390,4 +390,10 @@ public final class Keys {
public static final Key<Boolean> FET_UNIDIRECTIONAL
= new Key<>("unidirectional", false);
/**
* true if component is active low
*/
public static final Key<Boolean> ACTIVE_LOW
= new Key<>("activeLow", false);
}

View File

@ -19,10 +19,13 @@ public class Button implements Element {
*/
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Button.class)
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL);
.addAttribute(Keys.LABEL)
.addAttribute(Keys.ACTIVE_LOW);
private final ObservableValue output;
private final String label;
private final Boolean invert;
private boolean pressed;
/**
* Creates a new instance
@ -32,6 +35,8 @@ public class Button implements Element {
public Button(ElementAttributes attributes) {
output = new ObservableValue("out", 1).setPinDescription(DESCRIPTION);
label = attributes.get(Keys.LABEL);
invert = attributes.get(Keys.ACTIVE_LOW);
output.setValue(invert ? 1 : 0);
}
@Override
@ -48,4 +53,27 @@ public class Button implements Element {
public void registerNodes(Model model) {
model.addSignal(new Signal(label, output));
}
/**
* Sets the buttons state
*
* @param pressed true if pressed
*/
public void setPressed(boolean pressed) {
if (pressed != this.pressed) {
this.pressed = pressed;
if (pressed ^ invert) {
output.setValue(1);
} else {
output.setValue(0);
}
}
}
/**
* @return true if pressed
*/
public boolean isPressed() {
return pressed;
}
}

View File

@ -1,10 +1,10 @@
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.core.element.PinDescriptions;
import de.neemann.digital.core.io.Button;
import de.neemann.digital.draw.elements.IOState;
import de.neemann.digital.draw.elements.Pin;
import de.neemann.digital.draw.elements.Pins;
@ -28,7 +28,7 @@ public class ButtonShape implements Shape {
private final String label;
private final PinDescriptions outputs;
private IOState ioState;
private Button button;
/**
* Creates a new instance
@ -49,7 +49,7 @@ public class ButtonShape implements Shape {
@Override
public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) {
this.ioState = ioState;
this.button = (Button) ioState.getElement();
ioState.getOutput(0).addObserverToValue(guiObserver);
return new InteractorInterface() {
@Override
@ -59,19 +59,13 @@ public class ButtonShape implements Shape {
@Override
public boolean pressed(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync) {
modelSync.access(() -> {
ObservableValue value = ioState.getOutput(0);
value.setValue(1);
});
modelSync.access(() -> button.setPressed(true));
return true;
}
@Override
public boolean released(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync) {
modelSync.access(() -> {
ObservableValue value = ioState.getOutput(0);
value.setValue(0);
});
modelSync.access(() -> button.setPressed(false));
return true;
}
@ -84,10 +78,10 @@ public class ButtonShape implements Shape {
@Override
public void drawTo(Graphic graphic, Style heighLight) {
boolean down = false;
if (ioState != null) down = ioState.getOutput(0).getBool();
boolean isPressed = false;
if (button != null) isPressed = button.isPressed();
if (down) {
if (isPressed) {
graphic.drawPolygon(new Polygon(true)
.add(-SIZE * 2 - 1, -SIZE)
.add(-1, -SIZE)
@ -109,7 +103,6 @@ public class ButtonShape implements Shape {
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);
}

View File

@ -67,8 +67,8 @@
Dieses Element kann verwendet werden, um einen Assemblerbefehl BRK zu implementieren.
Es kann dann ein Programm bis zum nächsten BRK-Befehl ausgeführt werden.</string>
<string name="elem_Button">Taster</string>
<string name="elem_Button_tt">Ein einfacher Taster, welcher in seinen Ausgangszustand (0) zurückkehrt wenn er nicht gehalten wird. Am Ausgang liegt eine 1 an solange der Taster gedrückt ist.</string>
<string name="elem_Button_pin_out">Gibt 1 zurück wenn gedrückt, sonst 0. Setzt sich auf 0 zurück wenn nicht gehalten.</string>
<string name="elem_Button_tt">Ein einfacher Taster, welcher in seinen Ausgangszustand zurückkehrt wenn er nicht gehalten wird.</string>
<string name="elem_Button_pin_out">Das Ausgangssignal des Tasters.</string>
<string name="elem_Clock">Takteingang</string>
<string name="elem_Clock_pin_C">Wechselt im vorgegebenen Takt zwischen 0 und 1.</string>
<string name="elem_Clock_tt">Ein Takstignal. Dieses Taksignal kann über die Echtzeituhr gesteuert werden. Die Taktfrequenz kann im Attribute-Dialog eingestellt werden.</string>
@ -676,6 +676,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
schneller simuliert werden, als bidirektionale Transistoren. Da es keine Rückwirkung von Drain zu Source gibt, können
Transistoren in diesem Modus auch keine Kurzschlüsse über die Drain-Source Strecke verursachen. Daher kann dieser
Modus in manchen CMOS-Schaltungen erforderlich sein.</string>
<string name="key_activeLow">Active Low</string>
<string name="key_activeLow_tt">Wenn gesetzt, ist der Ausgang im aktiven Zustand Low.</string>
<string name="mod_insertWire">Leitung eingefügt.</string>
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>

View File

@ -67,8 +67,8 @@
You can use the component to implement a BRK assembly instruction.
Then you can run a simulated processor until a BRK instruction is reached.</string>
<string name="elem_Button">Button</string>
<string name="elem_Button_tt">A simple button which resets back to its original state (0) when not held down. Outputs a 1 if held down.</string>
<string name="elem_Button_pin_out">Returns 1 if pressed else 0. Resets back to 0 when not held down.</string>
<string name="elem_Button_tt">A simple button which resets back to its original state when not held down.</string>
<string name="elem_Button_pin_out">The output signal of the button.</string>
<string name="elem_Clock">Clock Input</string>
<string name="elem_Clock_pin_C">Alternates 0 and 1 with the set clock speed.</string>
<string name="elem_Clock_tt">A clock signal. Its possible to control it by the real time clock. Clock speed (in Hz) can be set in attributes dialog.</string>
@ -665,6 +665,8 @@ The names of the variables may not be unique.</string>
much faster to simulate than bidirectional transistors. Since there is no feedback from drain to source, in this
mode, the transistor can not short the connected wires when it is conducting. Thus, this mode is necessary to
simulate certain CMOS circuits.</string>
<string name="key_activeLow">Active Low</string>
<string name="key_activeLow_tt">If selected the output is low if the component is active.</string>
<string name="mod_insertWire">Inserted wire.</string>
<string name="mod_insertCopied">Insert from clipboard.</string>