]> git.saurik.com Git - wxWidgets.git/blob - wxPython/misc/widgetLayoutTest.py
Add GetClassDefaultAttribute. Since it is static we need to put the
[wxWidgets.git] / wxPython / misc / widgetLayoutTest.py
1 """
2 This test app is meant to help check if a widget has a good
3 DoGetBestSize method (in C++) by allowing the user to dynamically
4 create any non-toplevel widget which will be placed in a Sizer
5 designed to show how the widget will be sized naturally.
6 """
7
8 import wx
9 import sys
10 import os
11
12 # stuff for debugging
13 print "wx.VERSION_STRING = ", wx.VERSION_STRING
14 print "pid:", os.getpid()
15 #raw_input("Press Enter...")
16
17 class LayoutTestFrame(wx.Frame):
18 def __init__(self):
19 wx.Frame.__init__(self, None, -1, "Widget Layout Tester")
20
21 p = wx.Panel(self)
22
23 # Create control widgets
24 self.testHistory = wx.ListBox(p, -1, size=(150, 300))
25 self.moduleName = wx.TextCtrl(p, -1, "wx")
26 self.className = wx.TextCtrl(p, -1, "")
27 self.parameters = wx.TextCtrl(p, -1, "")
28 self.postCreate = wx.TextCtrl(p, -1, "", size=(1,75),
29 style=wx.TE_MULTILINE|wx.TE_DONTWRAP)
30 self.expression = wx.TextCtrl(p, -1, "", style=wx.TE_READONLY)
31 self.docstring = wx.TextCtrl(p, -1, "", size=(1,75),
32 style=wx.TE_READONLY|wx.TE_MULTILINE|wx.TE_DONTWRAP)
33
34 self.expression.SetBackgroundColour(
35 wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
36 self.docstring.SetBackgroundColour(
37 wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
38
39
40 addBtn = wx.Button(p, -1, "Add")
41 remBtn = wx.Button(p, -1, "Remove")
42 repBtn = wx.Button(p, -1, "Replace")
43 createBtn = wx.Button(p, -1, " Create Widget ")
44 createBtn.SetDefault()
45 destroyBtn = wx.Button(p, -1, "Destroy Widget")
46 clearBtn = wx.Button(p, -1, "Clear")
47
48 self.createBtn = createBtn
49 self.destroyBtn = destroyBtn
50
51 bottomPanel = wx.Panel(p, style=wx.SUNKEN_BORDER, name="bottomPanel")
52 bottomPanel.SetSizeHints((640,240))
53 bottomPanel.SetDefaultBackgroundColour("light blue")
54
55 self.testPanel = wx.Panel(bottomPanel, name="testPanel")
56 self.testPanel.SetDefaultBackgroundColour((205, 183, 181)) # mistyrose3
57 self.testWidget = None
58
59 self.infoPane = InfoPane(p)
60
61 # setup event bindings
62 self.Bind(wx.EVT_TEXT, self.OnUpdate, self.moduleName)
63 self.Bind(wx.EVT_TEXT, self.OnUpdate, self.className)
64 self.Bind(wx.EVT_TEXT, self.OnUpdate, self.parameters)
65 self.Bind(wx.EVT_UPDATE_UI, self.OnEnableCreate, createBtn)
66 self.Bind(wx.EVT_UPDATE_UI, self.OnEnableDestroy, destroyBtn)
67 self.Bind(wx.EVT_BUTTON, self.OnCreateWidget, createBtn)
68 self.Bind(wx.EVT_BUTTON, self.OnDestroyWidget, destroyBtn)
69 self.Bind(wx.EVT_BUTTON, self.OnClear, clearBtn)
70
71 self.Bind(wx.EVT_CLOSE, self.OnSaveHistory)
72
73 self.Bind(wx.EVT_BUTTON, self.OnAddHistory, addBtn)
74 self.Bind(wx.EVT_BUTTON, self.OnRemoveHistory, remBtn)
75 self.Bind(wx.EVT_BUTTON, self.OnReplaceHistory, repBtn)
76 self.Bind(wx.EVT_LISTBOX, self.OnHistorySelect, self.testHistory)
77 self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnHistoryActivate, self.testHistory)
78
79
80 # setup the layout
81 mainSizer = wx.BoxSizer(wx.VERTICAL)
82 topSizer = wx.BoxSizer(wx.HORIZONTAL)
83 ctlsSizer = wx.FlexGridSizer(2, 2, 5, 5)
84 ctlsSizer.AddGrowableCol(1)
85 btnSizer = wx.BoxSizer(wx.HORIZONTAL)
86
87 topSizer.Add(self.testHistory, 0, wx.RIGHT, 30)
88
89 ctlsSizer.Add(wx.StaticText(p, -1, "Module name:"),
90 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
91 mcSizer = wx.BoxSizer(wx.HORIZONTAL)
92 mcSizer.Add(self.moduleName, 0, 0)
93 mcSizer.Add(wx.StaticText(p, -1, "Class name:"),
94 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL |wx.LEFT, 10)
95 mcSizer.Add(self.className, 1, 0)
96 ctlsSizer.Add(mcSizer, 0, wx.EXPAND)
97
98 ctlsSizer.Add(wx.StaticText(p, -1, "Parameters:"),
99 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
100 ctlsSizer.Add(self.parameters, 0, wx.EXPAND)
101 ctlsSizer.Add(wx.StaticText(p, -1, "Create Expr:"),
102 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
103 ctlsSizer.Add(self.expression, 0, wx.EXPAND)
104 ctlsSizer.Add(wx.StaticText(p, -1, "Post create:"), 0, wx.ALIGN_RIGHT)
105 ctlsSizer.Add(self.postCreate, 0, wx.EXPAND)
106 ctlsSizer.Add(wx.StaticText(p, -1, "DocString:"), 0, wx.ALIGN_RIGHT)
107 ctlsSizer.Add(self.docstring, 0, wx.EXPAND)
108 ctlsSizer.AddGrowableRow(4)
109 topSizer.Add(ctlsSizer, 1, wx.EXPAND)
110
111 btnSizer.Add((5,5))
112 btnSizer.Add(addBtn, 0, wx.RIGHT, 5)
113 btnSizer.Add(remBtn, 0, wx.RIGHT, 5)
114 btnSizer.Add(repBtn, 0, wx.RIGHT, 5)
115 btnSizer.Add((0,0), 1)
116 btnSizer.Add(createBtn, 0, wx.RIGHT, 5)
117 btnSizer.Add(destroyBtn, 0, wx.RIGHT, 5)
118 btnSizer.Add(clearBtn, 0, wx.RIGHT, 5)
119 btnSizer.Add((0,0), 1)
120
121 mainSizer.Add(topSizer, 0, wx.EXPAND|wx.ALL, 10)
122 mainSizer.Add(btnSizer, 0, wx.EXPAND)
123 mainSizer.Add((10,10))
124 ##mainSizer.Add(wx.StaticLine(p, -1), 0, wx.EXPAND)
125 mainSizer.Add(bottomPanel, 1, wx.EXPAND)
126
127 mainSizer.Add(self.infoPane, 0, wx.EXPAND)
128
129 self.bottomSizer = sz = wx.BoxSizer(wx.VERTICAL)
130 sz.Add((0,0), 1)
131 sz.Add(self.testPanel, 0, wx.ALIGN_CENTER)
132 sz.Add((0,0), 1)
133 bottomPanel.SetSizer(sz)
134
135 p.SetSizerAndFit(mainSizer)
136 self.Fit()
137
138 self.PopulateHistory()
139
140
141
142
143 def PopulateHistory(self):
144 """
145 Load and eval a list of lists from a file, load the contents
146 into self.testHistory
147 """
148 fname = os.path.join(os.path.dirname(sys.argv[0]),
149 'widgetLayoutTest.cfg')
150 try:
151 self.history = eval(open(fname).read())
152 except:
153 self.history = []
154
155 self.testHistory.Clear()
156
157 for idx in range(len(self.history)):
158 item = self.history[idx]
159 # check if it is too short
160 while len(item) < 4:
161 item.append('')
162
163 # add it to the listbox
164 self.testHistory.Append(item[0] + '.' + item[1])
165
166 self.needSaved = False
167
168
169 def OnSaveHistory(self, evt):
170 if self.needSaved:
171 fname = os.path.join(os.path.dirname(sys.argv[0]),
172 'widgetLayoutTest.cfg')
173 f = open(fname, 'wb')
174 f.write('[\n')
175 for item in self.history:
176 f.write(str(item) + ',\n')
177 f.write(']\n')
178 f.close()
179 evt.Skip()
180
181
182 def OnAddHistory(self, evt):
183 moduleName = self.moduleName.GetValue()
184 className = self.className.GetValue()
185 parameters = self.parameters.GetValue()
186 postCreate = self.postCreate.GetValue()
187
188 item = [str(moduleName), str(className), str(parameters), str(postCreate)]
189 self.history.append(item)
190 self.testHistory.Append(item[0] + '.' + item[1])
191
192 self.testHistory.SetSelection(len(self.history)-1)
193 self.needSaved = True
194
195
196 def OnRemoveHistory(self, evt):
197 idx = self.testHistory.GetSelection()
198 if idx != wx.NOT_FOUND:
199 del self.history[idx]
200 self.testHistory.Delete(idx)
201 self.needSaved = True
202 self.OnClear(None)
203
204
205 def OnReplaceHistory(self, evt):
206 idx = self.testHistory.GetSelection()
207 if idx != wx.NOT_FOUND:
208 moduleName = self.moduleName.GetValue()
209 className = self.className.GetValue()
210 parameters = self.parameters.GetValue()
211 postCreate = self.postCreate.GetValue()
212
213 item = [str(moduleName), str(className), str(parameters), str(postCreate)]
214 self.history[idx] = item
215 self.testHistory.SetString(idx, item[0] + '.' + item[1])
216 self.needSaved = True
217
218
219 def OnHistorySelect(self, evt):
220 idx = self.testHistory.GetSelection()
221 if idx != wx.NOT_FOUND:
222 item = self.history[idx]
223 self.moduleName.SetValue(item[0])
224 self.className.SetValue(item[1])
225 self.parameters.SetValue(item[2])
226 self.postCreate.SetValue(item[3])
227
228
229 def OnHistoryActivate(self, evt):
230 btn = self.testHistory.GetParent().GetDefaultItem()
231 if btn is not None:
232 e = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, btn.GetId())
233 btn.Command(e)
234
235
236
237 def OnUpdate(self, evt):
238 # get the details from the form
239 moduleName = self.moduleName.GetValue()
240 className = self.className.GetValue()
241 parameters = self.parameters.GetValue()
242
243 expr = "w = %s.%s( testPanel, %s )" % (moduleName, className, parameters)
244 self.expression.SetValue(expr)
245
246 docstring = ""
247 try:
248 docstring = eval("%s.%s.__init__.__doc__" % (moduleName, className))
249 except:
250 pass
251 self.docstring.SetValue(docstring)
252
253
254 def OnEnableDestroy(self, evt):
255 evt.Enable(self.testWidget is not None)
256
257 def OnEnableCreate(self, evt):
258 evt.Enable(self.testWidget is None)
259
260
261 def OnCreateWidget(self, evt):
262 if self.testWidget is not None:
263 return
264
265 testPanel = self.testPanel
266
267 # get the details from the form
268 moduleName = self.moduleName.GetValue()
269 className = self.className.GetValue()
270 parameters = self.parameters.GetValue()
271 expr = self.expression.GetValue()[4:]
272 postCreate = self.postCreate.GetValue()
273
274 # make sure the module is imported already
275 if not sys.modules.has_key(moduleName):
276 try:
277 m = __import__(moduleName)
278 except importError:
279 wx.MessageBox("Unable to import module!", "Error")
280 return
281
282 # create the widget
283 try:
284 w = eval(expr)
285 except Exception, e:
286 wx.MessageBox("Got a '%s' Exception!" % e.__class__.__name__, "Error")
287 import traceback
288 traceback.print_exc()
289 return
290
291 # Is there postCreate code?
292 if postCreate:
293 ns = {}
294 ns.update(globals())
295 ns.update(locals())
296 try:
297 exec postCreate in ns
298 except Exception, e:
299 wx.MessageBox("Got a '%s' Exception!" % e.__class__.__name__, "Error")
300 import traceback
301 traceback.print_exc()
302 w.Destroy()
303 return
304
305 # Put the widget in a sizer and the sizer in the testPanel
306 sizer = wx.BoxSizer(wx.VERTICAL)
307 sizer.Add(w, 0, wx.ALL, 5)
308 self.testPanel.SetSizer(sizer)
309 self.testWidget = w
310 self.bottomSizer.Layout()
311
312 # make the destroy button be default now
313 self.destroyBtn.SetDefault()
314
315 self.infoPane.Update(w, testPanel)
316
317
318 def OnDestroyWidget(self, evt):
319 self.testWidget.Destroy()
320 self.testWidget = None
321 self.testPanel.SetSizer(None, True)
322 self.testPanel.Refresh()
323
324 # ensure the panel shrinks again
325 self.testPanel.SetSizeHints((20,20))
326 self.bottomSizer.Layout()
327 self.testPanel.SetSizeHints(wx.DefaultSize)
328
329 # make the create button be default now
330 self.createBtn.SetDefault()
331
332 self.infoPane.Clear()
333
334
335 def OnClear(self, evt):
336 self.moduleName.SetValue("")
337 self.className.SetValue("")
338 self.parameters.SetValue("")
339 self.expression.SetValue("")
340 self.docstring.SetValue("")
341 self.postCreate.SetValue("")
342
343
344
345
346
347
348 class InfoPane(wx.Panel):
349 """
350 This class is used to display details of various properties of the
351 widget and the testPanel to aid with debugging.
352 """
353 def __init__(self, parent):
354 wx.Panel.__init__(self, parent)
355
356 # create subwidgets
357 self.wPane = SizeInfoPane(self, "Widget")
358 self.tpPane= SizeInfoPane(self, "testPanel")
359 self.cPane = ColourInfoPanel(self, "Widget colours")
360
361 # Setup the layout
362 sizer = wx.BoxSizer(wx.HORIZONTAL)
363 sizer.Add(self.wPane, 0, wx.EXPAND|wx.ALL, 5)
364 sizer.Add(self.tpPane, 0, wx.EXPAND|wx.ALL, 5)
365 sizer.Add(self.cPane, 0, wx.EXPAND|wx.ALL, 5)
366
367 self.SetSizer(sizer)
368
369
370 def Update(self, w, tp):
371 self.wPane.Update(w)
372 self.tpPane.Update(tp)
373 self.cPane.Update(w)
374
375 def Clear(self):
376 self.wPane.Clear()
377 self.tpPane.Clear()
378 self.cPane.Clear()
379
380
381
382 class SizeInfoPane(wx.Panel):
383 """
384 A component of the InfoPane that shows vaious window size attributes.
385 """
386 def __init__(self, parent, label):
387 wx.Panel.__init__(self, parent)
388
389 # create subwidgets
390 sb = wx.StaticBox(self, -1, label)
391 self._size = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY)
392 self._minsize = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY)
393 self._bestsize = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY)
394 self._adjbstsize = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY)
395
396 # setup the layout
397 fgs = wx.FlexGridSizer(2, 2, 5, 5)
398 fgs.AddGrowableCol(1)
399
400 fgs.Add(wx.StaticText(self, -1, "Size:"),
401 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
402 fgs.Add(self._size, 0, wx.EXPAND)
403
404 fgs.Add(wx.StaticText(self, -1, "MinSize:"),
405 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
406 fgs.Add(self._minsize, 0, wx.EXPAND)
407
408 fgs.Add(wx.StaticText(self, -1, "BestSize:"),
409 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
410 fgs.Add(self._bestsize, 0, wx.EXPAND)
411
412 fgs.Add(wx.StaticText(self, -1, "AdjustedBestSize:"),
413 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
414 fgs.Add(self._adjbstsize, 0, wx.EXPAND)
415
416 sbs = wx.StaticBoxSizer(sb, wx.VERTICAL)
417 sbs.Add(fgs, 0, wx.EXPAND|wx.ALL, 4)
418
419 self.SetSizer(sbs)
420
421
422 def Update(self, win):
423 self._size.SetValue( str(win.GetSize()) )
424 self._minsize.SetValue( str(win.GetMinSize()) )
425 self._bestsize.SetValue( str(win.GetBestSize()) )
426 self._adjbstsize.SetValue( str(win.GetAdjustedBestSize()) )
427
428
429 def Clear(self):
430 self._size.SetValue("")
431 self._minsize.SetValue("")
432 self._bestsize.SetValue("")
433 self._adjbstsize.SetValue("")
434
435
436
437 class ColourInfoPanel(wx.Panel):
438 """
439 A component of the InfoPane that shows fg and bg colour attributes.
440 """
441 def __init__(self, parent, label):
442 wx.Panel.__init__(self, parent)
443
444 # create subwidgets
445 sb = wx.StaticBox(self, -1, label)
446 self._fgtxt = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY)
447 self._fgclr = wx.Panel(self, style=wx.SIMPLE_BORDER)
448 self._fgclr.SetSizeHints((20,20))
449 self._bgtxt = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY)
450 self._bgclr = wx.Panel(self, style=wx.SIMPLE_BORDER)
451 self._bgclr.SetSizeHints((20,20))
452
453 # setup the layout
454 fgs = wx.FlexGridSizer(2, 3, 5, 5)
455 fgs.AddGrowableCol(1)
456
457 fgs.Add(wx.StaticText(self, -1, "FG colour:"),
458 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
459 fgs.Add(self._fgtxt, 0, wx.EXPAND)
460 fgs.Add(self._fgclr)
461
462 fgs.Add(wx.StaticText(self, -1, "BG colour:"),
463 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
464 fgs.Add(self._bgtxt, 0, wx.EXPAND)
465 fgs.Add(self._bgclr)
466
467 sbs = wx.StaticBoxSizer(sb, wx.VERTICAL)
468 sbs.Add(fgs, 0, wx.EXPAND|wx.ALL, 4)
469
470 self.SetSizer(sbs)
471
472
473 def Update(self, win):
474 def clr2hex(c, cp):
475 cp.SetBackgroundColour(c)
476 cp.Refresh()
477 return "#%02X%02X%02X" % c.Get()
478
479 self._fgtxt.SetValue( clr2hex(win.GetForegroundColour(), self._fgclr) )
480 self._bgtxt.SetValue( clr2hex(win.GetBackgroundColour(), self._bgclr) )
481
482 ## f = win.GetFont()
483 ## print f.GetNativeFontInfo().ToString()
484
485
486 def Clear(self):
487 self._fgtxt.SetValue("")
488 self._bgtxt.SetValue("")
489 self._fgclr.SetBackgroundColour(self.GetBackgroundColour())
490 self._bgclr.SetBackgroundColour(self.GetBackgroundColour())
491 self._fgclr.Refresh()
492 self._bgclr.Refresh()
493
494
495
496
497 app = wx.PySimpleApp(redirect=True)
498 frame = LayoutTestFrame()
499 app.SetTopWindow(frame)
500 frame.Show()
501 app.MainLoop()
502