mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-16 16:34:47 -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.gui.components.data.DummyElement;
|
||||
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.test.TestCaseElement;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
@ -56,6 +57,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
||||
add(Terminal.DESCRIPTION, menu);
|
||||
add(DummyElement.DATADESCRIPTION, menu);
|
||||
add(DummyElement.TEXTDESCRIPTION, menu);
|
||||
add(Keyboard.DESCRIPTION, menu);
|
||||
|
||||
menu = Lang.get("lib_mux");
|
||||
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();
|
||||
if (!lastClock && clockVal) {
|
||||
long value = data.getValue();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (terminalDialog == null || !terminalDialog.isVisible())
|
||||
terminalDialog = new TerminalDialog(attr);
|
||||
terminalDialog.addChar((char) value);
|
||||
});
|
||||
if (value != 0)
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (terminalDialog == null || !terminalDialog.isVisible())
|
||||
terminalDialog = new TerminalDialog(attr);
|
||||
terminalDialog.addChar((char) value);
|
||||
});
|
||||
}
|
||||
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_Testcase">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="err_DFlipflopWithoutALabel">Flipflop hat keine Bezeichnung!</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_Testcase">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="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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user