mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 08:55:05 -04:00
added a simple keyboard
This commit is contained in:
parent
07b730a87b
commit
dd508b4aba
@ -13,6 +13,7 @@ import de.neemann.digital.core.wiring.*;
|
|||||||
import de.neemann.digital.draw.elements.Tunnel;
|
import de.neemann.digital.draw.elements.Tunnel;
|
||||||
import de.neemann.digital.gui.components.data.DummyElement;
|
import de.neemann.digital.gui.components.data.DummyElement;
|
||||||
import de.neemann.digital.gui.components.graphics.GraphicCard;
|
import de.neemann.digital.gui.components.graphics.GraphicCard;
|
||||||
|
import de.neemann.digital.gui.components.terminal.Keyboard;
|
||||||
import de.neemann.digital.gui.components.terminal.Terminal;
|
import de.neemann.digital.gui.components.terminal.Terminal;
|
||||||
import de.neemann.digital.gui.components.test.TestCaseElement;
|
import de.neemann.digital.gui.components.test.TestCaseElement;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
@ -56,6 +57,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
|||||||
add(Terminal.DESCRIPTION, menu);
|
add(Terminal.DESCRIPTION, menu);
|
||||||
add(DummyElement.DATADESCRIPTION, menu);
|
add(DummyElement.DATADESCRIPTION, menu);
|
||||||
add(DummyElement.TEXTDESCRIPTION, menu);
|
add(DummyElement.TEXTDESCRIPTION, menu);
|
||||||
|
add(Keyboard.DESCRIPTION, menu);
|
||||||
|
|
||||||
menu = Lang.get("lib_mux");
|
menu = Lang.get("lib_mux");
|
||||||
add(Multiplexer.DESCRIPTION, menu);
|
add(Multiplexer.DESCRIPTION, menu);
|
||||||
|
@ -0,0 +1,104 @@
|
|||||||
|
package de.neemann.digital.gui.components.terminal;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.*;
|
||||||
|
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.core.element.Keys;
|
||||||
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import static de.neemann.digital.core.element.PinInfo.input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Keyboard extends Node implements Element {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The keyboard description
|
||||||
|
*/
|
||||||
|
public static final ElementTypeDescription DESCRIPTION
|
||||||
|
= new ElementTypeDescription(Keyboard.class,
|
||||||
|
input("C"),
|
||||||
|
input("sel", Lang.get("elem_Keyboard_pin_sel")))
|
||||||
|
.addAttribute(Keys.ROTATE)
|
||||||
|
.addAttribute(Keys.LABEL)
|
||||||
|
.setShortName(Lang.get("elem_Keyboard"));
|
||||||
|
|
||||||
|
private static final Object KEYBOARD_LOCK = new Object();
|
||||||
|
private static KeyboardDialog keyboardDialog;
|
||||||
|
|
||||||
|
private ObservableValue data;
|
||||||
|
private ObservableValue clock;
|
||||||
|
private ObservableValue select;
|
||||||
|
private boolean lastClock;
|
||||||
|
private int keyData;
|
||||||
|
private boolean sel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new terminal instance
|
||||||
|
*
|
||||||
|
* @param attributes the attributes
|
||||||
|
*/
|
||||||
|
public Keyboard(ElementAttributes attributes) {
|
||||||
|
data = new ObservableValue("D", 16).setDescription(Lang.get("elem_Keyboard_pin_D"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInputs(ObservableValues inputs) throws NodeException {
|
||||||
|
clock = inputs.get(0).addObserverToValue(this).checkBits(1, this);
|
||||||
|
select = inputs.get(1).addObserverToValue(this).checkBits(1, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableValues getOutputs() {
|
||||||
|
return data.asList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
boolean clockVal = clock.getBool();
|
||||||
|
sel = select.getBool();
|
||||||
|
if (!lastClock && clockVal) {
|
||||||
|
KeyboardDialog kbd;
|
||||||
|
synchronized (KEYBOARD_LOCK) {
|
||||||
|
kbd = keyboardDialog;
|
||||||
|
}
|
||||||
|
if (kbd==null)
|
||||||
|
keyData=0;
|
||||||
|
else
|
||||||
|
keyData = keyboardDialog.getChar();
|
||||||
|
}
|
||||||
|
lastClock = clockVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
data.set(keyData, !sel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Model model) throws NodeException {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
if (keyboardDialog == null || !keyboardDialog.isVisible()) {
|
||||||
|
synchronized (KEYBOARD_LOCK) {
|
||||||
|
keyboardDialog = new KeyboardDialog(null);
|
||||||
|
}
|
||||||
|
keyboardDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
model.addObserver(event -> {
|
||||||
|
if (event.equals(ModelEvent.STOPPED)) {
|
||||||
|
if (keyboardDialog != null) {
|
||||||
|
KeyboardDialog kd = keyboardDialog;
|
||||||
|
SwingUtilities.invokeLater(kd::dispose);
|
||||||
|
synchronized (KEYBOARD_LOCK) {
|
||||||
|
keyboardDialog = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package de.neemann.digital.gui.components.terminal;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.KeyAdapter;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple keyboard implementation
|
||||||
|
*
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class KeyboardDialog extends JDialog {
|
||||||
|
private final JLabel textLabel;
|
||||||
|
private final Object textLock = new Object();
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Instance
|
||||||
|
*
|
||||||
|
* @param owner the owner frame
|
||||||
|
*/
|
||||||
|
public KeyboardDialog(Frame owner) {
|
||||||
|
super(owner);
|
||||||
|
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||||
|
|
||||||
|
textLabel = new JLabel("Enter Text ");
|
||||||
|
textLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||||
|
getContentPane().add(textLabel);
|
||||||
|
text = "";
|
||||||
|
|
||||||
|
textLabel.setFocusable(true);
|
||||||
|
textLabel.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
String t;
|
||||||
|
synchronized (textLock) {
|
||||||
|
text += e.getKeyChar();
|
||||||
|
t = text;
|
||||||
|
}
|
||||||
|
textLabel.setText(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pack();
|
||||||
|
setLocationRelativeTo(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the oldest char
|
||||||
|
*/
|
||||||
|
public int getChar() {
|
||||||
|
if (text.length() == 0)
|
||||||
|
return 0;
|
||||||
|
else {
|
||||||
|
int c;
|
||||||
|
String t;
|
||||||
|
synchronized (textLock) {
|
||||||
|
c = text.charAt(0);
|
||||||
|
text = text.substring(1);
|
||||||
|
t = text;
|
||||||
|
}
|
||||||
|
SwingUtilities.invokeLater(() -> textLabel.setText(t));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -63,11 +63,12 @@ public class Terminal extends Node implements Element {
|
|||||||
boolean clockVal = clock.getBool();
|
boolean clockVal = clock.getBool();
|
||||||
if (!lastClock && clockVal) {
|
if (!lastClock && clockVal) {
|
||||||
long value = data.getValue();
|
long value = data.getValue();
|
||||||
SwingUtilities.invokeLater(() -> {
|
if (value != 0)
|
||||||
if (terminalDialog == null || !terminalDialog.isVisible())
|
SwingUtilities.invokeLater(() -> {
|
||||||
terminalDialog = new TerminalDialog(attr);
|
if (terminalDialog == null || !terminalDialog.isVisible())
|
||||||
terminalDialog.addChar((char) value);
|
terminalDialog = new TerminalDialog(attr);
|
||||||
});
|
terminalDialog.addChar((char) value);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
lastClock = clockVal;
|
lastClock = clockVal;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,9 @@ in der Stabilisierungsphase befindet. Hat sich die Schaltung stabilisiert wird d
|
|||||||
<string name="elem_XOr">Exclusiv Oder</string>
|
<string name="elem_XOr">Exclusiv Oder</string>
|
||||||
<string name="elem_Testcase">Testfall</string>
|
<string name="elem_Testcase">Testfall</string>
|
||||||
<string name="elem_Testcase_tt">Beschreibt einen Testfall</string>
|
<string name="elem_Testcase_tt">Beschreibt einen Testfall</string>
|
||||||
|
<string name="elem_Keyboard">Tastatur</string>
|
||||||
|
<string name="elem_Keyboard_pin_sel">Wenn gesetzt is der Ausgang D aktiv.</string>
|
||||||
|
<string name="elem_Keyboard_pin_D">Die letzte Taste oder 0, wenn keine Taste gedrückt.</string>
|
||||||
<string name="error">Fehler</string>
|
<string name="error">Fehler</string>
|
||||||
<string name="err_DFlipflopWithoutALabel">Flipflop hat keine Bezeichnung!</string>
|
<string name="err_DFlipflopWithoutALabel">Flipflop hat keine Bezeichnung!</string>
|
||||||
<string name="err_N_isNotInputOrOutput">Pin {0} in Element {1} ist werder Eingang noch Ausgang</string>
|
<string name="err_N_isNotInputOrOutput">Pin {0} in Element {1} ist werder Eingang noch Ausgang</string>
|
||||||
|
@ -112,6 +112,9 @@ The terminal opens its own window.</string>
|
|||||||
<string name="elem_XOr">XOr</string>
|
<string name="elem_XOr">XOr</string>
|
||||||
<string name="elem_Testcase">Test case</string>
|
<string name="elem_Testcase">Test case</string>
|
||||||
<string name="elem_Testcase_tt">Describes a single test case.</string>
|
<string name="elem_Testcase_tt">Describes a single test case.</string>
|
||||||
|
<string name="elem_Keyboard">Keyboard</string>
|
||||||
|
<string name="elem_Keyboard_pin_sel">If high the output D is active</string>
|
||||||
|
<string name="elem_Keyboard_pin_D">The last pressed key, or null if no key is typed.</string>
|
||||||
<string name="error">Error</string>
|
<string name="error">Error</string>
|
||||||
<string name="err_DFlipflopWithoutALabel">D-Flipflop has no label set</string>
|
<string name="err_DFlipflopWithoutALabel">D-Flipflop has no label set</string>
|
||||||
<string name="err_N_isNotInputOrOutput">Pin {0} in element {1} is not a input or output</string>
|
<string name="err_N_isNotInputOrOutput">Pin {0} in element {1} is not a input or output</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user