forked from Apple-2-Tools/jace
Additional work on keyboard handling, pasting now works as does support for static invokableActions.
This commit is contained in:
parent
a477abac03
commit
9dcbc3422e
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user