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