]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/KeyEvents.py
HandlePrintClient shouldn't go above a top-level window
[wxWidgets.git] / wxPython / demo / KeyEvents.py
CommitLineData
8fa876ca
RD
1
2import wx
3import wx.lib.mixins.listctrl as listmix
3b867149
RD
4
5#----------------------------------------------------------------------
6
7keyMap = {
33971536
RD
8 wx.WXK_BACK : "WXK_BACK",
9 wx.WXK_TAB : "WXK_TAB",
10 wx.WXK_RETURN : "WXK_RETURN",
11 wx.WXK_ESCAPE : "WXK_ESCAPE",
12 wx.WXK_SPACE : "WXK_SPACE",
13 wx.WXK_DELETE : "WXK_DELETE",
14 wx.WXK_START : "WXK_START",
15 wx.WXK_LBUTTON : "WXK_LBUTTON",
16 wx.WXK_RBUTTON : "WXK_RBUTTON",
17 wx.WXK_CANCEL : "WXK_CANCEL",
18 wx.WXK_MBUTTON : "WXK_MBUTTON",
19 wx.WXK_CLEAR : "WXK_CLEAR",
20 wx.WXK_SHIFT : "WXK_SHIFT",
21 wx.WXK_ALT : "WXK_ALT",
22 wx.WXK_CONTROL : "WXK_CONTROL",
23 wx.WXK_MENU : "WXK_MENU",
24 wx.WXK_PAUSE : "WXK_PAUSE",
25 wx.WXK_CAPITAL : "WXK_CAPITAL",
26 wx.WXK_PRIOR : "WXK_PRIOR",
27 wx.WXK_NEXT : "WXK_NEXT",
28 wx.WXK_END : "WXK_END",
29 wx.WXK_HOME : "WXK_HOME",
30 wx.WXK_LEFT : "WXK_LEFT",
31 wx.WXK_UP : "WXK_UP",
32 wx.WXK_RIGHT : "WXK_RIGHT",
33 wx.WXK_DOWN : "WXK_DOWN",
34 wx.WXK_SELECT : "WXK_SELECT",
35 wx.WXK_PRINT : "WXK_PRINT",
36 wx.WXK_EXECUTE : "WXK_EXECUTE",
37 wx.WXK_SNAPSHOT : "WXK_SNAPSHOT",
38 wx.WXK_INSERT : "WXK_INSERT",
39 wx.WXK_HELP : "WXK_HELP",
40 wx.WXK_NUMPAD0 : "WXK_NUMPAD0",
41 wx.WXK_NUMPAD1 : "WXK_NUMPAD1",
42 wx.WXK_NUMPAD2 : "WXK_NUMPAD2",
43 wx.WXK_NUMPAD3 : "WXK_NUMPAD3",
44 wx.WXK_NUMPAD4 : "WXK_NUMPAD4",
45 wx.WXK_NUMPAD5 : "WXK_NUMPAD5",
46 wx.WXK_NUMPAD6 : "WXK_NUMPAD6",
47 wx.WXK_NUMPAD7 : "WXK_NUMPAD7",
48 wx.WXK_NUMPAD8 : "WXK_NUMPAD8",
49 wx.WXK_NUMPAD9 : "WXK_NUMPAD9",
50 wx.WXK_MULTIPLY : "WXK_MULTIPLY",
51 wx.WXK_ADD : "WXK_ADD",
52 wx.WXK_SEPARATOR : "WXK_SEPARATOR",
53 wx.WXK_SUBTRACT : "WXK_SUBTRACT",
54 wx.WXK_DECIMAL : "WXK_DECIMAL",
55 wx.WXK_DIVIDE : "WXK_DIVIDE",
56 wx.WXK_F1 : "WXK_F1",
57 wx.WXK_F2 : "WXK_F2",
58 wx.WXK_F3 : "WXK_F3",
59 wx.WXK_F4 : "WXK_F4",
60 wx.WXK_F5 : "WXK_F5",
61 wx.WXK_F6 : "WXK_F6",
62 wx.WXK_F7 : "WXK_F7",
63 wx.WXK_F8 : "WXK_F8",
64 wx.WXK_F9 : "WXK_F9",
65 wx.WXK_F10 : "WXK_F10",
66 wx.WXK_F11 : "WXK_F11",
67 wx.WXK_F12 : "WXK_F12",
68 wx.WXK_F13 : "WXK_F13",
69 wx.WXK_F14 : "WXK_F14",
70 wx.WXK_F15 : "WXK_F15",
71 wx.WXK_F16 : "WXK_F16",
72 wx.WXK_F17 : "WXK_F17",
73 wx.WXK_F18 : "WXK_F18",
74 wx.WXK_F19 : "WXK_F19",
75 wx.WXK_F20 : "WXK_F20",
76 wx.WXK_F21 : "WXK_F21",
77 wx.WXK_F22 : "WXK_F22",
78 wx.WXK_F23 : "WXK_F23",
79 wx.WXK_F24 : "WXK_F24",
80 wx.WXK_NUMLOCK : "WXK_NUMLOCK",
81 wx.WXK_SCROLL : "WXK_SCROLL",
82 wx.WXK_PAGEUP : "WXK_PAGEUP",
83 wx.WXK_PAGEDOWN : "WXK_PAGEDOWN",
84 wx.WXK_NUMPAD_SPACE : "WXK_NUMPAD_SPACE",
85 wx.WXK_NUMPAD_TAB : "WXK_NUMPAD_TAB",
86 wx.WXK_NUMPAD_ENTER : "WXK_NUMPAD_ENTER",
87 wx.WXK_NUMPAD_F1 : "WXK_NUMPAD_F1",
88 wx.WXK_NUMPAD_F2 : "WXK_NUMPAD_F2",
89 wx.WXK_NUMPAD_F3 : "WXK_NUMPAD_F3",
90 wx.WXK_NUMPAD_F4 : "WXK_NUMPAD_F4",
91 wx.WXK_NUMPAD_HOME : "WXK_NUMPAD_HOME",
92 wx.WXK_NUMPAD_LEFT : "WXK_NUMPAD_LEFT",
93 wx.WXK_NUMPAD_UP : "WXK_NUMPAD_UP",
94 wx.WXK_NUMPAD_RIGHT : "WXK_NUMPAD_RIGHT",
95 wx.WXK_NUMPAD_DOWN : "WXK_NUMPAD_DOWN",
96 wx.WXK_NUMPAD_PRIOR : "WXK_NUMPAD_PRIOR",
97 wx.WXK_NUMPAD_PAGEUP : "WXK_NUMPAD_PAGEUP",
98 wx.WXK_NUMPAD_NEXT : "WXK_NUMPAD_NEXT",
99 wx.WXK_NUMPAD_PAGEDOWN : "WXK_NUMPAD_PAGEDOWN",
100 wx.WXK_NUMPAD_END : "WXK_NUMPAD_END",
101 wx.WXK_NUMPAD_BEGIN : "WXK_NUMPAD_BEGIN",
102 wx.WXK_NUMPAD_INSERT : "WXK_NUMPAD_INSERT",
103 wx.WXK_NUMPAD_DELETE : "WXK_NUMPAD_DELETE",
104 wx.WXK_NUMPAD_EQUAL : "WXK_NUMPAD_EQUAL",
105 wx.WXK_NUMPAD_MULTIPLY : "WXK_NUMPAD_MULTIPLY",
106 wx.WXK_NUMPAD_ADD : "WXK_NUMPAD_ADD",
107 wx.WXK_NUMPAD_SEPARATOR : "WXK_NUMPAD_SEPARATOR",
108 wx.WXK_NUMPAD_SUBTRACT : "WXK_NUMPAD_SUBTRACT",
109 wx.WXK_NUMPAD_DECIMAL : "WXK_NUMPAD_DECIMAL",
110 wx.WXK_NUMPAD_DIVIDE : "WXK_NUMPAD_DIVIDE",
3b867149
RD
111}
112
113
114#----------------------------------------------------------------------
115
8fa876ca 116class 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
33971536 121 , name="sink")
8fa876ca
RD
122
123 self.SetBackgroundColour(wx.BLUE)
1e4a197e 124 self.haveFocus = False
38f7d801 125 self.callSkip = True
1e4a197e
RD
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 199class 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
39ac2874 217 self.InsertColumn(idx, "")
3b867149 218
39ac2874 219 for x in range(idx):
8fa876ca 220 self.SetColumnWidth(x, wx.LIST_AUTOSIZE_USEHEADER)
3b867149
RD
221
222 self.SetColumnWidth(1, 125)
223
224
225 def LogKeyEvent(self, evType, evt):
226 keycode = evt.GetKeyCode()
227 keyname = keyMap.get(keycode, None)
228 if keyname is None:
d82c2542
RD
229 if "unicode" in wx.PlatformInfo:
230 keycode = evt.GetUnicodeKey()
231 if keycode <= 127:
232 keycode = evt.GetKeyCode()
7db509e2
RD
233 keyname = "\"" + unichr(evt.GetUnicodeKey()) + "\""
234
235 elif keycode < 256:
3b867149
RD
236 if keycode == 0:
237 keyname = "NUL"
238 elif keycode < 27:
239 keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
240 else:
241 keyname = "\"%s\"" % chr(keycode)
242 else:
243 keyname = "unknown (%s)" % keycode
244
245 modifiers = ""
246 for mod, ch in [(evt.ControlDown(), 'C'),
247 (evt.AltDown(), 'A'),
248 (evt.ShiftDown(), 'S'),
249 (evt.MetaDown(), 'M')]:
250 if mod:
251 modifiers += ch
252 else:
253 modifiers += '-'
254
f0a0d77e 255 id = self.InsertStringItem(self.GetItemCount(), evType)
3b867149
RD
256 self.SetStringItem(id, 1, keyname)
257 self.SetStringItem(id, 2, str(keycode))
258 self.SetStringItem(id, 3, modifiers)
d9975a31
RD
259 self.SetStringItem(id, 4, str(evt.GetUnicodeKey()))
260 self.SetStringItem(id, 5, str(evt.GetRawKeyCode()))
261 self.SetStringItem(id, 6, str(evt.GetRawKeyFlags()))
3b867149
RD
262
263 #print ( id, evType, keyname, str(keycode), modifiers, str(evt.GetRawKeyCode()), str(evt.GetRawKeyFlags()))
264
265 self.EnsureVisible(id)
266
267
268 def ClearLog(self):
269 self.DeleteAllItems()
270
39ac2874
RD
271 def CopyLog(self):
272 # build a newline and tab delimited string to put into the clipboard
273 if "unicode" in wx.PlatformInfo:
274 st = u""
275 else:
276 st = ""
277 for h in self.colHeaders:
278 st += h + "\t"
279 st += "\n"
280
281 for idx in range(self.GetItemCount()):
282 for col in range(self.GetColumnCount()):
283 item = self.GetItem(idx, col)
284 st += item.GetText() + "\t"
285 st += "\n"
286
287 data = wx.TextDataObject()
288 data.SetText(st)
289 if wx.TheClipboard.Open():
290 wx.TheClipboard.SetData(data)
291 wx.TheClipboard.Close()
292 else:
293 wx.MessageBox("Unable to open the clipboard", "Error")
294
295
296
3b867149
RD
297
298#----------------------------------------------------------------------
299
300
8fa876ca 301class TestPanel(wx.Panel):
3b867149
RD
302 def __init__(self, parent, log):
303 self.log = log
8fa876ca 304 wx.Panel.__init__(self, parent, -1, style=0)
3b867149 305 self.keysink = KeySink(self)
5193b348 306 self.keysink.SetMinSize((100, 65))
3b867149
RD
307 self.keylog = KeyLog(self)
308
39ac2874 309 btn = wx.Button(self, -1, "Clear", style=wx.BU_EXACTFIT)
8fa876ca 310 self.Bind(wx.EVT_BUTTON, self.OnClearBtn, btn)
33971536
RD
311 btn.SetToolTipString(
312 "Clear the items from the log window")
3b867149 313
39ac2874
RD
314 btn2 = wx.Button(self, -1, "Copy", style=wx.BU_EXACTFIT)
315 self.Bind(wx.EVT_BUTTON, self.OnCopyBtn, btn2)
33971536
RD
316 btn2.SetToolTipString(
317 "Copy the contents of the log window to the clipboard")
39ac2874
RD
318
319 cb1 = wx.CheckBox(self, -1, "Call evt.Skip in Key* events")
8fa876ca 320 self.Bind(wx.EVT_CHECKBOX, self.OnSkipCB, cb1)
38f7d801 321 cb1.SetValue(True)
3b867149 322
39ac2874 323 cb2 = wx.CheckBox(self, -1, "KEY_UP")
8fa876ca 324 self.Bind(wx.EVT_CHECKBOX, self.OnKeyUpCB, cb2)
1e4a197e 325 cb2.SetValue(True)
3b867149 326
39ac2874 327 cb3 = wx.CheckBox(self, -1, "KEY_DOWN")
8fa876ca 328 self.Bind(wx.EVT_CHECKBOX, self.OnKeyDnCB, cb3)
1e4a197e 329 cb3.SetValue(True)
3b867149 330
39ac2874 331 cb4 = wx.CheckBox(self, -1, "CHAR")
8fa876ca 332 self.Bind(wx.EVT_CHECKBOX, self.OnCharCB, cb4)
1e4a197e 333 cb4.SetValue(True)
3b867149 334
8fa876ca
RD
335 buttons = wx.BoxSizer(wx.HORIZONTAL)
336 buttons.Add(btn, 0, wx.ALL, 4)
39ac2874 337 buttons.Add(btn2, 0, wx.ALL, 4)
8fa876ca
RD
338 buttons.Add(cb1, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 6)
339 buttons.Add(cb2, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
340 buttons.Add(cb3, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
341 buttons.Add(cb4, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
3b867149 342
8fa876ca
RD
343 sizer = wx.BoxSizer(wx.VERTICAL)
344 sizer.Add(self.keysink, 0, wx.GROW)
3b867149 345 sizer.Add(buttons)
8fa876ca 346 sizer.Add(self.keylog, 1, wx.GROW)
3b867149
RD
347
348 self.SetSizer(sizer)
349
350
351 def OnClearBtn(self, evt):
352 self.keylog.ClearLog()
353
39ac2874
RD
354 def OnCopyBtn(self, evt):
355 self.keylog.CopyLog()
356
3b867149
RD
357 def OnSkipCB(self, evt):
358 self.keysink.SetCallSkip(evt.GetInt())
359
360 def OnKeyUpCB(self, evt):
361 self.keysink.SetLogKeyUp(evt.GetInt())
362
363 def OnKeyDnCB(self, evt):
364 self.keysink.SetLogKeyDn(evt.GetInt())
365
366 def OnCharCB(self, evt):
367 self.keysink.SetLogChar(evt.GetInt())
368
369
370#----------------------------------------------------------------------
371
372def runTest(frame, nb, log):
373 win = TestPanel(nb, log)
374 return win
375
376#----------------------------------------------------------------------
377
378
379
380overview = """<html><body>
381<h2><center>wxKeyEvents</center></h2>
382
8fa876ca 383This demo simply catches all key events and prints info about them.
3b867149
RD
384It is meant to be used as a compatibility test for cross platform work.
385
386</body></html>
387"""
388
389
390
391if __name__ == '__main__':
392 import sys,os
393 import run
8eca4fef 394 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3b867149 395