Additional work on keyboard handling, pasting now works as does support for static invokableActions.

This commit is contained in:
Brendan Robert 2015-02-20 01:28:35 -06:00
parent a477abac03
commit 9dcbc3422e
3 changed files with 31 additions and 33 deletions

View File

@ -21,7 +21,6 @@ package jace;
import jace.apple2e.MOS65C02; import jace.apple2e.MOS65C02;
import jace.apple2e.RAM128k; import jace.apple2e.RAM128k;
import jace.apple2e.SoftSwitches; import jace.apple2e.SoftSwitches;
import jace.config.ConfigurationPanel;
import jace.config.InvokableAction; import jace.config.InvokableAction;
import jace.config.Reconfigurable; import jace.config.Reconfigurable;
import jace.core.CPU; import jace.core.CPU;
@ -30,10 +29,7 @@ import jace.core.RAM;
import jace.core.RAMEvent; import jace.core.RAMEvent;
import jace.core.RAMListener; import jace.core.RAMListener;
import static jace.core.Utility.*; import static jace.core.Utility.*;
import jace.library.MediaLibrary;
import jace.ui.AbstractEmulatorFrame;
import jace.ui.DebuggerPanel; import jace.ui.DebuggerPanel;
import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.HeadlessException; import java.awt.HeadlessException;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@ -48,12 +44,9 @@ import java.util.Date;
import java.util.List; import java.util.List;
import javafx.embed.swing.SwingFXUtils; import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField; import javax.swing.JTextField;
/** /**

View File

@ -82,10 +82,12 @@ public class Configuration implements Reconfigurable {
public static class ConfigTreeModel implements TreeModel { public static class ConfigTreeModel implements TreeModel {
@Override
public Object getRoot() { public Object getRoot() {
return BASE; return BASE;
} }
@Override
public Object getChild(Object parent, int index) { public Object getChild(Object parent, int index) {
if (parent instanceof ConfigNode) { if (parent instanceof ConfigNode) {
ConfigNode n = (ConfigNode) parent; ConfigNode n = (ConfigNode) parent;
@ -95,6 +97,7 @@ public class Configuration implements Reconfigurable {
} }
} }
@Override
public int getChildCount(Object parent) { public int getChildCount(Object parent) {
if (parent instanceof ConfigNode) { if (parent instanceof ConfigNode) {
ConfigNode n = (ConfigNode) parent; ConfigNode n = (ConfigNode) parent;
@ -104,14 +107,17 @@ public class Configuration implements Reconfigurable {
} }
} }
@Override
public boolean isLeaf(Object node) { public boolean isLeaf(Object node) {
return getChildCount(node) == 0; return getChildCount(node) == 0;
} }
@Override
public void valueForPathChanged(TreePath path, Object newValue) { public void valueForPathChanged(TreePath path, Object newValue) {
// Do nothing... // Do nothing...
} }
@Override
public int getIndexOfChild(Object parent, Object child) { public int getIndexOfChild(Object parent, Object child) {
if (parent instanceof ConfigNode) { if (parent instanceof ConfigNode) {
ConfigNode n = (ConfigNode) parent; ConfigNode n = (ConfigNode) parent;
@ -125,10 +131,12 @@ public class Configuration implements Reconfigurable {
return -1; return -1;
} }
@Override
public void addTreeModelListener(TreeModelListener l) { public void addTreeModelListener(TreeModelListener l) {
// Do nothing... // Do nothing...
} }
@Override
public void removeTreeModelListener(TreeModelListener l) { public void removeTreeModelListener(TreeModelListener l) {
// Do nothing... // Do nothing...
} }
@ -221,13 +229,15 @@ public class Configuration implements Reconfigurable {
if (node.subject == null) { if (node.subject == null) {
return; return;
} }
for (Method m : node.subject.getClass().getMethods()) { for (Method m : node.subject.getClass().getMethods()) {
if (!m.isAnnotationPresent(InvokableAction.class)) {
continue;
}
InvokableAction action = m.getDeclaredAnnotation(InvokableAction.class); InvokableAction action = m.getDeclaredAnnotation(InvokableAction.class);
if (action == null) continue;
node.hotkeys.put(m.getName(), action.defaultKeyMapping()); node.hotkeys.put(m.getName(), action.defaultKeyMapping());
} }
for (Field f : node.subject.getClass().getFields()) { for (Field f : node.subject.getClass().getFields()) {
// System.out.println("Evaluating field " + f.getName()); // System.out.println("Evaluating field " + f.getName());
try { try {
@ -366,12 +376,9 @@ public class Configuration implements Reconfigurable {
ConfigNode newRoot = (ConfigNode) ois.readObject(); ConfigNode newRoot = (ConfigNode) ois.readObject();
applyConfigTree(newRoot, BASE); applyConfigTree(newRoot, BASE);
successful = true; successful = true;
} catch (ClassNotFoundException ex) {
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
// Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
// This just means there are no settings to be saved -- just ignore it. // This just means there are no settings to be saved -- just ignore it.
} catch (IOException ex) { } catch (ClassNotFoundException | IOException ex) {
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
} finally { } finally {
try { try {
@ -451,16 +458,16 @@ public class Configuration implements Reconfigurable {
private static void doApply(ConfigNode node) { private static void doApply(ConfigNode node) {
List<String> removeList = new ArrayList<>(); List<String> removeList = new ArrayList<>();
Keyboard.unregisterAllHandlers(node.subject); Keyboard.unregisterAllHandlers(node.subject);
for (String m : node.hotkeys.keySet()) { node.hotkeys.keySet().stream().forEach((m) -> {
Method method = findAnyMethodByName(node.subject.getClass(), m); Method method = findAnyMethodByName(node.subject.getClass(), m);
if (method == null) continue; if (method != null) {
InvokableAction action = method.getAnnotation(InvokableAction.class); InvokableAction action = method.getAnnotation(InvokableAction.class);
if (action == null) continue; for (String code : node.hotkeys.get(m)) {
for (String code : node.hotkeys.get(m)) { Keyboard.registerInvokableAction(action, node.subject, method, code);
Keyboard.registerInvokableAction(action, node.subject, method, code); }
} }
} });
for (String f : node.settings.keySet()) { for (String f : node.settings.keySet()) {
try { try {
Field ff = node.subject.getClass().getField(f); Field ff = node.subject.getClass().getField(f);

View File

@ -18,10 +18,7 @@
*/ */
package jace.core; package jace.core;
import jace.EmulatorUILogic;
import jace.apple2e.SoftSwitches; import jace.apple2e.SoftSwitches;
import jace.apple2e.Speaker;
import jace.apple2e.softswitch.KeyboardSoftSwitch;
import jace.config.InvokableAction; import jace.config.InvokableAction;
import jace.config.Reconfigurable; import jace.config.Reconfigurable;
import java.awt.Toolkit; import java.awt.Toolkit;
@ -32,6 +29,7 @@ import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -41,7 +39,6 @@ import java.util.logging.Logger;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import jdk.nashorn.internal.codegen.types.Type;
/** /**
* Keyboard manages all keyboard-related activities. For now, all hotkeys are * Keyboard manages all keyboard-related activities. For now, all hotkeys are
@ -94,6 +91,7 @@ public class Keyboard implements Reconfigurable {
private static Map<Object, Set<KeyHandler>> keyHandlersByOwner = new HashMap<>(); private static Map<Object, Set<KeyHandler>> keyHandlersByOwner = new HashMap<>();
public static void registerInvokableAction(InvokableAction action, Object owner, Method method, String code) { public static void registerInvokableAction(InvokableAction action, Object owner, Method method, String code) {
boolean isStatic = Modifier.isStatic(method.getModifiers());
registerKeyHandler(new KeyHandler(code) { registerKeyHandler(new KeyHandler(code) {
@Override @Override
public boolean handleKeyUp(KeyEvent e) { public boolean handleKeyUp(KeyEvent e) {
@ -104,9 +102,9 @@ public class Keyboard implements Reconfigurable {
Object returnValue = null; Object returnValue = null;
try { try {
if (method.getParameterCount() > 0) { if (method.getParameterCount() > 0) {
returnValue = method.invoke(owner, false); returnValue = method.invoke(isStatic ? null : owner, true);
} else { } else {
returnValue = method.invoke(owner); returnValue = method.invoke(isStatic ? null : owner);
} }
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(Keyboard.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(Keyboard.class.getName()).log(Level.SEVERE, null, ex);
@ -123,9 +121,9 @@ public class Keyboard implements Reconfigurable {
Object returnValue = null; Object returnValue = null;
try { try {
if (method.getParameterCount() > 0) { if (method.getParameterCount() > 0) {
returnValue = method.invoke(owner, true); returnValue = method.invoke(isStatic ? null : owner, true);
} else { } else {
returnValue = method.invoke(owner); returnValue = method.invoke(isStatic ? null : owner);
} }
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(Keyboard.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(Keyboard.class.getName()).log(Level.SEVERE, null, ex);
@ -272,12 +270,12 @@ public class Keyboard implements Reconfigurable {
computer.resume(); computer.resume();
} }
public static void doPaste(String text) { public static void pasteFromString(String text) {
pasteBuffer = new StringReader(text); pasteBuffer = new StringReader(text);
} }
@InvokableAction(name = "Paste clipboard", alternatives = "paste", category = "Keyboard", notifyOnRelease = false, defaultKeyMapping = {"Ctrl+Shift+V","Shift+Insert"}, consumeKeyEvent = false) @InvokableAction(name = "Paste clipboard", alternatives = "paste", category = "Keyboard", notifyOnRelease = false, defaultKeyMapping = {"Ctrl+Shift+V","Shift+Insert"}, consumeKeyEvent = true)
public static void doPaste() { public static void pasteFromClipboard() {
try { try {
Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
String contents = (String) clip.getData(DataFlavor.stringFlavor); String contents = (String) clip.getData(DataFlavor.stringFlavor);