From 0a5104a70cc6fd59e683c36c0227767c311e3c78 Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Tue, 14 Jan 2003 00:53:38 +0000 Subject: [PATCH] Allow specifying the rate at which individual key presses are to be repeated. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2133 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../com/threerings/util/KeyTranslator.java | 8 +- .../threerings/util/KeyTranslatorImpl.java | 99 ++++++++++++++++--- .../com/threerings/util/KeyboardManager.java | 50 +++++----- 3 files changed, 113 insertions(+), 44 deletions(-) diff --git a/src/java/com/threerings/util/KeyTranslator.java b/src/java/com/threerings/util/KeyTranslator.java index 0d8d8182b..d8bdcf43a 100644 --- a/src/java/com/threerings/util/KeyTranslator.java +++ b/src/java/com/threerings/util/KeyTranslator.java @@ -1,5 +1,5 @@ // -// $Id: KeyTranslator.java,v 1.3 2002/01/18 23:32:14 shaper Exp $ +// $Id: KeyTranslator.java,v 1.4 2003/01/14 00:53:38 shaper Exp $ package com.threerings.util; @@ -34,6 +34,12 @@ public interface KeyTranslator */ public String getReleaseCommand (int keyCode); + /** + * Returns the number of times each second that key presses are to be + * automatically repeated while the key is held down. + */ + public int getRepeatRate (int keyCode); + /** * Returns an iterator that iterates over the available press * commands. diff --git a/src/java/com/threerings/util/KeyTranslatorImpl.java b/src/java/com/threerings/util/KeyTranslatorImpl.java index f707cc0fc..7a9e5b45d 100644 --- a/src/java/com/threerings/util/KeyTranslatorImpl.java +++ b/src/java/com/threerings/util/KeyTranslatorImpl.java @@ -1,8 +1,9 @@ // -// $Id: KeyTranslatorImpl.java,v 1.3 2002/01/18 23:32:14 shaper Exp $ +// $Id: KeyTranslatorImpl.java,v 1.4 2003/01/14 00:53:38 shaper Exp $ package com.threerings.util; +import java.util.ArrayList; import java.util.Iterator; import com.samskivert.util.HashIntMap; @@ -15,55 +16,123 @@ import com.samskivert.util.HashIntMap; public class KeyTranslatorImpl implements KeyTranslator { /** - * Adds a mapping from key press to action command string. + * Adds a mapping from a key press to an action command string that + * will auto-repeat at a default repeat rate. */ public void addPressCommand (int keyCode, String command) { - _press.put(keyCode, command); + addPressCommand(keyCode, command, DEFAULT_REPEAT_RATE); } /** - * Adds a mapping from key release to action command string. + * Adds a mapping from a key press to an action command string that + * will auto-repeat at the specified repeat rate. Overwrites any + * existing mapping and repeat rate that may have already been + * registered. + * + * @param rate the number of times each second that the key press + * should be repeated while the key is down; passing 0 + * will result in no repeating. + */ + public void addPressCommand (int keyCode, String command, int rate) + { + KeyRecord krec = getKeyRecord(keyCode); + krec.pressCommand = command; + krec.repeatRate = rate; + } + + /** + * Adds a mapping from a key release to an action command string. + * Overwrites any existing mapping that may already have been + * registered. */ public void addReleaseCommand (int keyCode, String command) { - _release.put(keyCode, command); + KeyRecord krec = getKeyRecord(keyCode); + krec.releaseCommand = command; + } + + /** + * Returns the key record for the specified key, creating it and + * inserting it in the key table if necessary. + */ + protected KeyRecord getKeyRecord (int keyCode) + { + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + if (krec == null) { + krec = new KeyRecord(); + _keys.put(keyCode, krec); + } + return krec; } // documentation inherited public boolean hasCommand (int keyCode) { - return (_press.get(keyCode) != null || - _release.get(keyCode) != null); + return (_keys.get(keyCode) != null); } // documentation inherited public String getPressCommand (int keyCode) { - return (String)_press.get(keyCode); + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + return (krec == null) ? null : krec.pressCommand; } // documentation inherited public String getReleaseCommand (int keyCode) { - return (String)_release.get(keyCode); + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + return (krec == null) ? null : krec.releaseCommand; + } + + // documentation inherited + public int getRepeatRate (int keyCode) + { + KeyRecord krec = (KeyRecord)_keys.get(keyCode); + return (krec == null) ? 0 : krec.repeatRate; } // documentation inherited public Iterator enumeratePressCommands () { - return _press.values().iterator(); + ArrayList commands = new ArrayList(); + Iterator iter = _keys.values().iterator(); + while (iter.hasNext()) { + KeyRecord krec = (KeyRecord)iter.next(); + commands.add(krec.pressCommand); + } + return commands.iterator(); } // documentation inherited public Iterator enumerateReleaseCommands () { - return _release.values().iterator(); + ArrayList commands = new ArrayList(); + Iterator iter = _keys.values().iterator(); + while (iter.hasNext()) { + KeyRecord krec = (KeyRecord)iter.next(); + commands.add(krec.releaseCommand); + } + return commands.iterator(); } - /** The mapping for key presses from key codes to action commands. */ - protected HashIntMap _press = new HashIntMap(); + protected class KeyRecord + { + /** The command to be posted when the key is pressed. */ + public String pressCommand; - /** The mapping for key releases from key codes to action commands. */ - protected HashIntMap _release = new HashIntMap(); + /** The command to be posted when the key is released. */ + public String releaseCommand; + + /** The rate in presses per second at which the key is to be + * auto-repeated. */ + public int repeatRate; + } + + /** The keys for which commands are registered. */ + protected HashIntMap _keys = new HashIntMap(); + + /** The default key press repeat rate. */ + protected static final int DEFAULT_REPEAT_RATE = 3; } diff --git a/src/java/com/threerings/util/KeyboardManager.java b/src/java/com/threerings/util/KeyboardManager.java index fdc0529e5..175c4999b 100644 --- a/src/java/com/threerings/util/KeyboardManager.java +++ b/src/java/com/threerings/util/KeyboardManager.java @@ -1,5 +1,5 @@ // -// $Id: KeyboardManager.java,v 1.15 2003/01/12 00:26:39 shaper Exp $ +// $Id: KeyboardManager.java,v 1.16 2003/01/14 00:53:38 shaper Exp $ package com.threerings.util; @@ -193,15 +193,6 @@ public class KeyboardManager _repeatDelay = delay; } - /** - * Sets the delay in milliseconds between each repeat key action - * command posted by the keyboard manager while a key is down. - */ - public void setPressDelay (long delay) - { - _pressDelay = delay; - } - /** * Releases all keys and ceases any hot repeating action that may be * going on. @@ -404,6 +395,8 @@ public class KeyboardManager _keyText = KeyEvent.getKeyText(_keyCode); _pressCommand = _xlate.getPressCommand(_keyCode); _releaseCommand = _xlate.getReleaseCommand(_keyCode); + int rate = _xlate.getRepeatRate(_keyCode); + _pressDelay = (rate == 0) ? 0 : (1000L / rate); } /** @@ -411,22 +404,23 @@ public class KeyboardManager */ public synchronized void setPressTime (long time) { - _lastPress = time; - _lastRelease = time; + if (_lastPress == 0 && _pressCommand != null) { + // post the initial key press command + postPress(time); + } - if (_iid == -1) { - // register an interval to post the command associated - // with the key press until the key is decidedly released - _iid = IntervalManager.register(this, _pressDelay, null, true); + if (_iid == -1 && _pressDelay > 0) { + // register an interval to post the key press command + // until the key is decidedly released + _iid = IntervalManager.register( + this, _pressDelay, null, true); if (DEBUG_EVENTS) { Log.info("Pressing key [key=" + _keyText + "]."); } - - if (_pressCommand != null) { - // post the initial key press command - postPress(time); - } } + + _lastPress = time; + _lastRelease = time; } /** @@ -471,7 +465,7 @@ public class KeyboardManager public synchronized void release (long timestamp) { // bail if we're not currently pressed - if (_iid == -1) { + if (_lastPress == 0) { return; } @@ -495,6 +489,9 @@ public class KeyboardManager // post the key release command postRelease(timestamp); } + + // clear out the last press and release timestamps + _lastPress = _lastRelease = 0; } // documentation inherited @@ -621,6 +618,9 @@ public class KeyboardManager /** The key code associated with this key info object. */ protected int _keyCode; + + /** The milliseconds to sleep between sending repeat key commands. */ + protected long _pressDelay; } /** An observer operation to notify observers of a key event. */ @@ -660,16 +660,10 @@ public class KeyboardManager /** The default repeat delay. */ protected static final long DEFAULT_REPEAT_DELAY = 50L; - /** The default key press delay. */ - protected static final long DEFAULT_PRESS_DELAY = 150L; - /** The expected approximate milliseconds between each key * release/press event while the key is being auto-repeated. */ protected long _repeatDelay = DEFAULT_REPEAT_DELAY; - /** The milliseconds to sleep between sending repeat key commands. */ - protected long _pressDelay = DEFAULT_PRESS_DELAY; - /** A hashtable mapping key codes to {@link KeyInfo} objects. */ protected HashIntMap _keys = new HashIntMap();