Changed KeyRepeatBlocker into KeyRepeatLimiter, which can be used to block

key repeats, or set the repeat rate to any desired value.


git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@357 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Ray Greenwell
2007-11-29 23:01:40 +00:00
parent 3b31fff153
commit 2aca740d15
@@ -23,27 +23,37 @@ package com.threerings.flash {
import flash.events.EventDispatcher; import flash.events.EventDispatcher;
import flash.events.IEventDispatcher; import flash.events.IEventDispatcher;
import flash.events.KeyboardEvent; import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import flash.utils.Dictionary; import flash.utils.Dictionary;
import flash.utils.Timer;
/** /**
* A very simple class that adapts the KeyboardEvents generated by some source by discarding * A very simple class that adapts the KeyboardEvents generated by some source and altering
* the extra KEY_DOWN events generated while a key is held down. * (or blocking) the key repeat rate.
*/ */
public class KeyRepeatBlocker extends EventDispatcher public class KeyRepeatLimiter extends EventDispatcher
{ {
/** /**
* Create a KeyRepeatBlocker that will be blocking key repeat events from * Create a KeyRepeatLimiter that will be limiting key repeat events from
* the specified source. * the specified source.
*
* @param limitRate 0 to block all key repeats, or a millisecond value specifying how often
* to dispatch KEY_DOWN events while the key is being held down. The rate will be limted
* by the frame rate of the enclosing SWF.
*/ */
public function KeyRepeatBlocker (source :IEventDispatcher) public function KeyRepeatLimiter (source :IEventDispatcher, limitRate :int = 0)
{ {
_source = source; _source = source;
_source.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown); _source.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
_source.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp); _source.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp);
if (limitRate > 0) {
_timer = new Timer(limitRate);
_timer.addEventListener(TimerEvent.TIMER, handleTimerEvent);
}
} }
/** /**
@@ -53,26 +63,64 @@ public class KeyRepeatBlocker extends EventDispatcher
{ {
_source.removeEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown); _source.removeEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
_source.removeEventListener(KeyboardEvent.KEY_UP, handleKeyUp); _source.removeEventListener(KeyboardEvent.KEY_UP, handleKeyUp);
_down = new Dictionary();
_keysDown = 0;
if (_timer != null) {
_timer.stop();
}
} }
protected function handleKeyDown (event :KeyboardEvent) :void protected function handleKeyDown (event :KeyboardEvent) :void
{ {
if (!_down[event.keyCode]) { if (undefined === _down[event.keyCode]) {
_down[event.keyCode] = true; _keysDown++;
_down[event.keyCode] = event.clone();
// maybe start the timer if we need to
if (_timer != null && !_timer.running) {
_timer.reset();
_timer.start();
}
// only dispatch if we're not limiting this key
dispatchEvent(event); dispatchEvent(event);
} }
} }
protected function handleKeyUp (event :KeyboardEvent) :void protected function handleKeyUp (event :KeyboardEvent) :void
{ {
delete _down[event.keyCode]; if (undefined !== _down[event.keyCode]) {
delete _down[event.keyCode];
_keysDown--;
if (_timer != null && _keysDown == 0) {
_timer.stop();
}
}
// always dispatch an up
dispatchEvent(event); dispatchEvent(event);
} }
protected function handleTimerEvent (event :TimerEvent) :void
{
// dispatch any saved key events
for each (var keyEvent :KeyboardEvent in _down) {
dispatchEvent(keyEvent);
}
}
/** Our source. */ /** Our source. */
protected var _source :IEventDispatcher; protected var _source :IEventDispatcher;
/** Tracks whether a key is currently being held down. */ /** Tracks whether a key is currently being held down. */
protected var _down :Dictionary = new Dictionary(); protected var _down :Dictionary = new Dictionary();
/** How many keys are currently down? */
protected var _keysDown :int;
/** The timer generating key repeats, if any. */
protected var _timer :Timer;
} }
} }