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