]>
Commit | Line | Data |
---|---|---|
1 | # 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net) | |
2 | # | |
3 | # o Updated for wx namespace | |
4 | # | |
5 | # 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net) | |
6 | # | |
7 | # o lib.mixins.listctrl needs wx renamer applied. | |
8 | # | |
9 | ||
10 | import wx | |
11 | import wx.lib.mixins.listctrl as listmix | |
12 | ||
13 | #---------------------------------------------------------------------- | |
14 | ||
15 | keyMap = { | |
16 | wx.WXK_BACK : "wx.WXK_BACK", | |
17 | wx.WXK_TAB : "wx.WXK_TAB", | |
18 | wx.WXK_RETURN : "wx.WXK_RETURN", | |
19 | wx.WXK_ESCAPE : "wx.WXK_ESCAPE", | |
20 | wx.WXK_SPACE : "wx.WXK_SPACE", | |
21 | wx.WXK_DELETE : "wx.WXK_DELETE", | |
22 | wx.WXK_START : "wx.WXK_START", | |
23 | wx.WXK_LBUTTON : "wx.WXK_LBUTTON", | |
24 | wx.WXK_RBUTTON : "wx.WXK_RBUTTON", | |
25 | wx.WXK_CANCEL : "wx.WXK_CANCEL", | |
26 | wx.WXK_MBUTTON : "wx.WXK_MBUTTON", | |
27 | wx.WXK_CLEAR : "wx.WXK_CLEAR", | |
28 | wx.WXK_SHIFT : "wx.WXK_SHIFT", | |
29 | wx.WXK_ALT : "wx.WXK_ALT", | |
30 | wx.WXK_CONTROL : "wx.WXK_CONTROL", | |
31 | wx.WXK_MENU : "wx.WXK_MENU", | |
32 | wx.WXK_PAUSE : "wx.WXK_PAUSE", | |
33 | wx.WXK_CAPITAL : "wx.WXK_CAPITAL", | |
34 | wx.WXK_PRIOR : "wx.WXK_PRIOR", | |
35 | wx.WXK_NEXT : "wx.WXK_NEXT", | |
36 | wx.WXK_END : "wx.WXK_END", | |
37 | wx.WXK_HOME : "wx.WXK_HOME", | |
38 | wx.WXK_LEFT : "wx.WXK_LEFT", | |
39 | wx.WXK_UP : "wx.WXK_UP", | |
40 | wx.WXK_RIGHT : "wx.WXK_RIGHT", | |
41 | wx.WXK_DOWN : "wx.WXK_DOWN", | |
42 | wx.WXK_SELECT : "wx.WXK_SELECT", | |
43 | wx.WXK_PRINT : "wx.WXK_PRINT", | |
44 | wx.WXK_EXECUTE : "wx.WXK_EXECUTE", | |
45 | wx.WXK_SNAPSHOT : "wx.WXK_SNAPSHOT", | |
46 | wx.WXK_INSERT : "wx.WXK_INSERT", | |
47 | wx.WXK_HELP : "wx.WXK_HELP", | |
48 | wx.WXK_NUMPAD0 : "wx.WXK_NUMPAD0", | |
49 | wx.WXK_NUMPAD1 : "wx.WXK_NUMPAD1", | |
50 | wx.WXK_NUMPAD2 : "wx.WXK_NUMPAD2", | |
51 | wx.WXK_NUMPAD3 : "wx.WXK_NUMPAD3", | |
52 | wx.WXK_NUMPAD4 : "wx.WXK_NUMPAD4", | |
53 | wx.WXK_NUMPAD5 : "wx.WXK_NUMPAD5", | |
54 | wx.WXK_NUMPAD6 : "wx.WXK_NUMPAD6", | |
55 | wx.WXK_NUMPAD7 : "wx.WXK_NUMPAD7", | |
56 | wx.WXK_NUMPAD8 : "wx.WXK_NUMPAD8", | |
57 | wx.WXK_NUMPAD9 : "wx.WXK_NUMPAD9", | |
58 | wx.WXK_MULTIPLY : "wx.WXK_MULTIPLY", | |
59 | wx.WXK_ADD : "wx.WXK_ADD", | |
60 | wx.WXK_SEPARATOR : "wx.WXK_SEPARATOR", | |
61 | wx.WXK_SUBTRACT : "wx.WXK_SUBTRACT", | |
62 | wx.WXK_DECIMAL : "wx.WXK_DECIMAL", | |
63 | wx.WXK_DIVIDE : "wx.WXK_DIVIDE", | |
64 | wx.WXK_F1 : "wx.WXK_F1", | |
65 | wx.WXK_F2 : "wx.WXK_F2", | |
66 | wx.WXK_F3 : "wx.WXK_F3", | |
67 | wx.WXK_F4 : "wx.WXK_F4", | |
68 | wx.WXK_F5 : "wx.WXK_F5", | |
69 | wx.WXK_F6 : "wx.WXK_F6", | |
70 | wx.WXK_F7 : "wx.WXK_F7", | |
71 | wx.WXK_F8 : "wx.WXK_F8", | |
72 | wx.WXK_F9 : "wx.WXK_F9", | |
73 | wx.WXK_F10 : "wx.WXK_F10", | |
74 | wx.WXK_F11 : "wx.WXK_F11", | |
75 | wx.WXK_F12 : "wx.WXK_F12", | |
76 | wx.WXK_F13 : "wx.WXK_F13", | |
77 | wx.WXK_F14 : "wx.WXK_F14", | |
78 | wx.WXK_F15 : "wx.WXK_F15", | |
79 | wx.WXK_F16 : "wx.WXK_F16", | |
80 | wx.WXK_F17 : "wx.WXK_F17", | |
81 | wx.WXK_F18 : "wx.WXK_F18", | |
82 | wx.WXK_F19 : "wx.WXK_F19", | |
83 | wx.WXK_F20 : "wx.WXK_F20", | |
84 | wx.WXK_F21 : "wx.WXK_F21", | |
85 | wx.WXK_F22 : "wx.WXK_F22", | |
86 | wx.WXK_F23 : "wx.WXK_F23", | |
87 | wx.WXK_F24 : "wx.WXK_F24", | |
88 | wx.WXK_NUMLOCK : "wx.WXK_NUMLOCK", | |
89 | wx.WXK_SCROLL : "wx.WXK_SCROLL", | |
90 | wx.WXK_PAGEUP : "wx.WXK_PAGEUP", | |
91 | wx.WXK_PAGEDOWN : "wx.WXK_PAGEDOWN", | |
92 | wx.WXK_NUMPAD_SPACE : "wx.WXK_NUMPAD_SPACE", | |
93 | wx.WXK_NUMPAD_TAB : "wx.WXK_NUMPAD_TAB", | |
94 | wx.WXK_NUMPAD_ENTER : "wx.WXK_NUMPAD_ENTER", | |
95 | wx.WXK_NUMPAD_F1 : "wx.WXK_NUMPAD_F1", | |
96 | wx.WXK_NUMPAD_F2 : "wx.WXK_NUMPAD_F2", | |
97 | wx.WXK_NUMPAD_F3 : "wx.WXK_NUMPAD_F3", | |
98 | wx.WXK_NUMPAD_F4 : "wx.WXK_NUMPAD_F4", | |
99 | wx.WXK_NUMPAD_HOME : "wx.WXK_NUMPAD_HOME", | |
100 | wx.WXK_NUMPAD_LEFT : "wx.WXK_NUMPAD_LEFT", | |
101 | wx.WXK_NUMPAD_UP : "wx.WXK_NUMPAD_UP", | |
102 | wx.WXK_NUMPAD_RIGHT : "wx.WXK_NUMPAD_RIGHT", | |
103 | wx.WXK_NUMPAD_DOWN : "wx.WXK_NUMPAD_DOWN", | |
104 | wx.WXK_NUMPAD_PRIOR : "wx.WXK_NUMPAD_PRIOR", | |
105 | wx.WXK_NUMPAD_PAGEUP : "wx.WXK_NUMPAD_PAGEUP", | |
106 | wx.WXK_NUMPAD_NEXT : "wx.WXK_NUMPAD_NEXT", | |
107 | wx.WXK_NUMPAD_PAGEDOWN : "wx.WXK_NUMPAD_PAGEDOWN", | |
108 | wx.WXK_NUMPAD_END : "wx.WXK_NUMPAD_END", | |
109 | wx.WXK_NUMPAD_BEGIN : "wx.WXK_NUMPAD_BEGIN", | |
110 | wx.WXK_NUMPAD_INSERT : "wx.WXK_NUMPAD_INSERT", | |
111 | wx.WXK_NUMPAD_DELETE : "wx.WXK_NUMPAD_DELETE", | |
112 | wx.WXK_NUMPAD_EQUAL : "wx.WXK_NUMPAD_EQUAL", | |
113 | wx.WXK_NUMPAD_MULTIPLY : "wx.WXK_NUMPAD_MULTIPLY", | |
114 | wx.WXK_NUMPAD_ADD : "wx.WXK_NUMPAD_ADD", | |
115 | wx.WXK_NUMPAD_SEPARATOR : "wx.WXK_NUMPAD_SEPARATOR", | |
116 | wx.WXK_NUMPAD_SUBTRACT : "wx.WXK_NUMPAD_SUBTRACT", | |
117 | wx.WXK_NUMPAD_DECIMAL : "wx.WXK_NUMPAD_DECIMAL", | |
118 | wx.WXK_NUMPAD_DIVIDE : "wx.WXK_NUMPAD_DIVIDE", | |
119 | } | |
120 | ||
121 | ||
122 | #---------------------------------------------------------------------- | |
123 | ||
124 | class KeySink(wx.Window): | |
125 | def __init__(self, parent): | |
126 | wx.Window.__init__(self, parent, -1, style=wx.WANTS_CHARS | |
127 | #| wx.RAISED_BORDER | |
128 | #| wx.SUNKEN_BORDER | |
129 | ) | |
130 | ||
131 | self.SetBackgroundColour(wx.BLUE) | |
132 | self.haveFocus = False | |
133 | self.callSkip = False | |
134 | self.logKeyDn = True | |
135 | self.logKeyUp = True | |
136 | self.logChar = True | |
137 | ||
138 | self.Bind(wx.EVT_PAINT, self.OnPaint) | |
139 | self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) | |
140 | self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) | |
141 | self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) | |
142 | ||
143 | self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) | |
144 | self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) | |
145 | self.Bind(wx.EVT_CHAR, self.OnChar) | |
146 | ||
147 | ||
148 | def SetCallSkip(self, skip): | |
149 | self.callSkip = skip | |
150 | ||
151 | def SetLogKeyUp(self, val): | |
152 | self.logKeyUp = val | |
153 | ||
154 | def SetLogKeyDn(self, val): | |
155 | self.logKeyDn = val | |
156 | ||
157 | def SetLogChar(self, val): | |
158 | self.logChar = val | |
159 | ||
160 | ||
161 | def OnPaint(self, evt): | |
162 | dc = wx.PaintDC(self) | |
163 | rect = self.GetClientRect() | |
164 | dc.SetTextForeground(wx.WHITE) | |
165 | dc.DrawLabel("Click here and then press some keys", | |
166 | rect, wx.ALIGN_CENTER | wx.ALIGN_TOP) | |
167 | if self.haveFocus: | |
168 | dc.SetTextForeground(wx.GREEN) | |
169 | dc.DrawLabel("Have Focus", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM) | |
170 | else: | |
171 | dc.SetTextForeground(wx.RED) | |
172 | dc.DrawLabel("Need Focus!", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM) | |
173 | ||
174 | ||
175 | def OnSetFocus(self, evt): | |
176 | self.haveFocus = True | |
177 | self.Refresh() | |
178 | ||
179 | def OnKillFocus(self, evt): | |
180 | self.haveFocus = False | |
181 | self.Refresh() | |
182 | ||
183 | def OnMouse(self, evt): | |
184 | if evt.ButtonDown(): | |
185 | self.SetFocus() | |
186 | ||
187 | ||
188 | def OnKeyDown(self, evt): | |
189 | if self.logKeyDn: | |
190 | self.GetParent().keylog.LogKeyEvent("KeyDown", evt) | |
191 | if self.callSkip: | |
192 | evt.Skip() | |
193 | ||
194 | def OnKeyUp(self, evt): | |
195 | if self.logKeyUp: | |
196 | self.GetParent().keylog.LogKeyEvent("KeyUp", evt) | |
197 | if self.callSkip: | |
198 | evt.Skip() | |
199 | ||
200 | def OnChar(self, evt): | |
201 | if self.logChar: | |
202 | self.GetParent().keylog.LogKeyEvent("Char", evt) | |
203 | ||
204 | ||
205 | #---------------------------------------------------------------------- | |
206 | ||
207 | class KeyLog(wx.ListCtrl, listmix.wxListCtrlAutoWidthMixin): | |
208 | ||
209 | def __init__(self, parent): | |
210 | wx.ListCtrl.__init__(self, parent, -1, | |
211 | style = wx.LC_REPORT|wx.LC_VRULES|wx.LC_HRULES) | |
212 | listmix.wxListCtrlAutoWidthMixin.__init__(self) | |
213 | ||
214 | self.InsertColumn(0, "Event Type") | |
215 | self.InsertColumn(1, "Key Name") | |
216 | self.InsertColumn(2, "Key Code") | |
217 | self.InsertColumn(3, "Modifiers") | |
218 | self.InsertColumn(4, "RawKeyCode") | |
219 | self.InsertColumn(5, "RawKeyFlags") | |
220 | self.InsertColumn(6, "") | |
221 | ||
222 | for x in range(6): | |
223 | self.SetColumnWidth(x, wx.LIST_AUTOSIZE_USEHEADER) | |
224 | ||
225 | self.SetColumnWidth(1, 125) | |
226 | ||
227 | ||
228 | def LogKeyEvent(self, evType, evt): | |
229 | keycode = evt.GetKeyCode() | |
230 | keyname = keyMap.get(keycode, None) | |
231 | if keyname is None: | |
232 | if keycode < 256: | |
233 | if keycode == 0: | |
234 | keyname = "NUL" | |
235 | elif keycode < 27: | |
236 | keyname = "Ctrl-%s" % chr(ord('A') + keycode-1) | |
237 | else: | |
238 | keyname = "\"%s\"" % chr(keycode) | |
239 | else: | |
240 | keyname = "unknown (%s)" % keycode | |
241 | ||
242 | modifiers = "" | |
243 | for mod, ch in [(evt.ControlDown(), 'C'), | |
244 | (evt.AltDown(), 'A'), | |
245 | (evt.ShiftDown(), 'S'), | |
246 | (evt.MetaDown(), 'M')]: | |
247 | if mod: | |
248 | modifiers += ch | |
249 | else: | |
250 | modifiers += '-' | |
251 | ||
252 | id = self.InsertStringItem(self.GetItemCount(), evType) | |
253 | self.SetStringItem(id, 1, keyname) | |
254 | self.SetStringItem(id, 2, str(keycode)) | |
255 | self.SetStringItem(id, 3, modifiers) | |
256 | self.SetStringItem(id, 4, str(evt.GetRawKeyCode())) | |
257 | self.SetStringItem(id, 5, str(evt.GetRawKeyFlags())) | |
258 | ||
259 | #print ( id, evType, keyname, str(keycode), modifiers, str(evt.GetRawKeyCode()), str(evt.GetRawKeyFlags())) | |
260 | ||
261 | self.EnsureVisible(id) | |
262 | ||
263 | ||
264 | def ClearLog(self): | |
265 | self.DeleteAllItems() | |
266 | ||
267 | ||
268 | #---------------------------------------------------------------------- | |
269 | ||
270 | ||
271 | class TestPanel(wx.Panel): | |
272 | def __init__(self, parent, log): | |
273 | self.log = log | |
274 | wx.Panel.__init__(self, parent, -1, style=0) | |
275 | self.keysink = KeySink(self) | |
276 | self.keysink.SetSize((100, 65)) | |
277 | self.keylog = KeyLog(self) | |
278 | ||
279 | btn = wx.Button(self, -1, "Clear Log") | |
280 | self.Bind(wx.EVT_BUTTON, self.OnClearBtn, btn) | |
281 | ||
282 | cb1 = wx.CheckBox(self, -1, "Call evt.Skip for Key Up/Dn events") | |
283 | self.Bind(wx.EVT_CHECKBOX, self.OnSkipCB, cb1) | |
284 | ||
285 | cb2 = wx.CheckBox(self, -1, "EVT_KEY_UP") | |
286 | self.Bind(wx.EVT_CHECKBOX, self.OnKeyUpCB, cb2) | |
287 | cb2.SetValue(True) | |
288 | ||
289 | cb3 = wx.CheckBox(self, -1, "EVT_KEY_DOWN") | |
290 | self.Bind(wx.EVT_CHECKBOX, self.OnKeyDnCB, cb3) | |
291 | cb3.SetValue(True) | |
292 | ||
293 | cb4 = wx.CheckBox(self, -1, "EVT_CHAR") | |
294 | self.Bind(wx.EVT_CHECKBOX, self.OnCharCB, cb4) | |
295 | cb4.SetValue(True) | |
296 | ||
297 | buttons = wx.BoxSizer(wx.HORIZONTAL) | |
298 | buttons.Add(btn, 0, wx.ALL, 4) | |
299 | buttons.Add(cb1, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 6) | |
300 | buttons.Add(cb2, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6) | |
301 | buttons.Add(cb3, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6) | |
302 | buttons.Add(cb4, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6) | |
303 | ||
304 | sizer = wx.BoxSizer(wx.VERTICAL) | |
305 | sizer.Add(self.keysink, 0, wx.GROW) | |
306 | sizer.Add(buttons) | |
307 | sizer.Add(self.keylog, 1, wx.GROW) | |
308 | ||
309 | self.SetSizer(sizer) | |
310 | ||
311 | ||
312 | def OnClearBtn(self, evt): | |
313 | self.keylog.ClearLog() | |
314 | ||
315 | def OnSkipCB(self, evt): | |
316 | self.keysink.SetCallSkip(evt.GetInt()) | |
317 | ||
318 | def OnKeyUpCB(self, evt): | |
319 | self.keysink.SetLogKeyUp(evt.GetInt()) | |
320 | ||
321 | def OnKeyDnCB(self, evt): | |
322 | self.keysink.SetLogKeyDn(evt.GetInt()) | |
323 | ||
324 | def OnCharCB(self, evt): | |
325 | self.keysink.SetLogChar(evt.GetInt()) | |
326 | ||
327 | ||
328 | #---------------------------------------------------------------------- | |
329 | ||
330 | def runTest(frame, nb, log): | |
331 | win = TestPanel(nb, log) | |
332 | return win | |
333 | ||
334 | #---------------------------------------------------------------------- | |
335 | ||
336 | ||
337 | ||
338 | overview = """<html><body> | |
339 | <h2><center>wxKeyEvents</center></h2> | |
340 | ||
341 | This demo simply catches all key events and prints info about them. | |
342 | It is meant to be used as a compatibility test for cross platform work. | |
343 | ||
344 | </body></html> | |
345 | """ | |
346 | ||
347 | ||
348 | ||
349 | if __name__ == '__main__': | |
350 | import sys,os | |
351 | import run | |
352 | run.main(['', os.path.basename(sys.argv[0])]) | |
353 |