Handling Keyboard Events

Im working on a project that required a Keyboard Manager to track shortcut keys within the Flex app, so i went ahead a wrote this quick little POC that I later incorporated into the project. I handle shortcut keys by adding and removing key listeners and mapping them to a dictionary of available keys. My final implementation handled [cmd + shift + key] for windows and [alt + key] for mac switched based on Capabilities.os.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="onCreationComplete()">
 
	<mx:Script>
		<![CDATA[
			import com.lejnieks.poc.enum.KeyCodes;
 
			private var _keyCodes:Dictionary;
 
			private function onCreationComplete():void
			{
				_keyCodes = new Dictionary();
 
				addKeyCodes();
 
				addEventListener(MouseEvent.CLICK, clickHandler);
				addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			}
 
			private function clickHandler(event:MouseEvent):void
			{
				stage.focus = this;
			}
 
			private function addKeyDownListeners():void
			{
				var hasKeyUpListener:Boolean = hasEventListener(KeyboardEvent.KEY_UP);
				var hasKeyDownListener:Boolean = hasEventListener(KeyboardEvent.KEY_DOWN);
 
				if(!hasKeyUpListener)
				{
					addEventListener(KeyboardEvent.KEY_UP,onKeyUp);
				}
 
				if(hasKeyDownListener)
				{
					removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
				}
			}
 
			private function onKeyUp( e:KeyboardEvent ):void
			{
				addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
				output_cmd.text = output_key.text = output_shift.text = "";
			}
 
			private function onKeyDown(evt:KeyboardEvent):void
			{
				var os:String = Capabilities.os;
 
				if( os.indexOf("Windows") > -1 ) os = "Windows";
				else if (os.indexOf("Mac") > -1) os = "Mac";
 
				switch(os)
				{
					case "Windows":
						handleWindowsKeyDown( evt );
						break;
 
					case "Mac":
						handleMacKeyDown( evt );
						break;
 
					default:
						//You are not on a supported OS
						break;
				}
			}
 
			private function handleMacKeyDown( e:KeyboardEvent ):void
			{
				var keyTranslated:String = getKeyCodeTranslated( e.keyCode );
 
				if(e.altKey)
				{
					output_alt.text = "alt key is pressed";
					if( keyTranslated != null )
					{
						output_key.text = keyTranslated + " key is pressed";
						addKeyDownListeners();
					}
				}
			}
 
			private function handleWindowsKeyDown( e:KeyboardEvent ):void
			{
				var keyTranslated:String = getKeyCodeTranslated( e.keyCode );
 
				if(e.ctrlKey)
				{
					output_cmd.text = "cmd/ctrl key is pressed";
 
					if(e.shiftKey)
					{
						output_shift.text = "shift key is pressed";
 
						if( keyTranslated != null )
						{
							output_key.text = keyTranslated + " key is pressed";
							addKeyDownListeners();
						}
					}
				}
			}
 
			private function addKeyCodes():void
			{
				_keyCodes = KeyCodes.toDictionary();
			}
 
			private function getKeyCodeTranslated( keyCode:uint ):String
			{
				return _keyCodes[keyCode];
			}
		]]>
	</mx:Script>
 
	<mx:TextInput id="output_cmd" width="200" borderColor="#000000" borderStyle="solid" />
	<mx:TextInput id="output_shift" width="200" borderColor="#000000" borderStyle="solid" />
	<mx:Spacer height="20"/>
 
	<mx:TextInput id="output_alt" width="200" borderColor="#000000" borderStyle="solid" />
	<mx:Spacer height="20"/>
 
	<mx:TextInput id="output_key" width="200" borderColor="#000000" borderStyle="solid" />
 
</mx:Application>

and the Enum to Dictionary Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.lejnieks.poc.enum
{
	import flash.utils.Dictionary;
	import flash.utils.describeType;
 
 
	public class KeyCodes
	{
		public static const A:uint = 65;
		public static const B:uint = 66;
		public static const C:uint = 67;
		public static const D:uint = 68;
		public static const E:uint = 69;
		public static const F:uint = 70;
		public static const G:uint = 71;
		public static const H:uint = 72;
		public static const I:uint = 73;
		public static const J:uint = 74;
		public static const K:uint = 75;
		public static const L:uint = 76;
		public static const M:uint = 77;
		public static const N:uint = 78;
		public static const O:uint = 79;
		public static const P:uint = 80;
		public static const Q:uint = 81;
		public static const R:uint = 82;
		public static const S:uint = 83;
		public static const T:uint = 84;
		public static const U:uint = 85;
		public static const V:uint = 86;
		public static const W:uint = 87;
		public static const X:uint = 88;
		public static const Y:uint = 89;
		public static const Z:uint = 90;
 
		public static const ALT_E:uint = 180;
 
		public function KeyCodes() {}
 
		public static function toArray():Array
		{
			var keyCodes:Array = new Array();
			var classInfo:XML = describeType(KeyCodes);
			for each (var v:XML in classInfo..constant)
			{
				var name:String = String(v.@name);
			    var value:String = KeyCodes[name];
			    keyCodes.push(value);
			}
			keyCodes.sort();
			return keyCodes;
		}
 
		public static function toDictionary():Dictionary
		{
			var keyCodesDict:Dictionary = new Dictionary();
			var classInfo:XML = describeType(KeyCodes);
 
			for each (var v:XML in classInfo..constant)
			{
				var name:String = String(v.@name);
			    var value:String = KeyCodes[name];
			    keyCodesDict[value] = name;
			}
			return keyCodesDict;
		}
 
	}
}

Download the source files here




1 Comment

speak up

Add your comment below, or trackback from your own site.

Subscribe to these comments.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

*Required Fields