]> git.saurik.com Git - wxWidgets.git/blob - wxPython/misc/widgetLayoutTest.py
Inital fill in background, removed tabs, -1->wxID_ANY, TRUE->true, FALSE->false
[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 if 'wxMac' in wx.PlatformInfo or 'wxGTK' in wx.PlatformInfo:
80 self.testHistory.Bind(wx.EVT_KEY_DOWN, self.OnHistoryKey)
81
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)
89
90 topSizer.Add(self.testHistory, 0, wx.RIGHT, 30)
91
92 ctlsSizer.Add(wx.StaticText(p, -1, "Module name:"),
93 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
94 mcSizer = wx.BoxSizer(wx.HORIZONTAL)
95 mcSizer.Add(self.moduleName, 0, 0)
96 mcSizer.Add(wx.StaticText(p, -1, "Class name:"),
97 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL |wx.LEFT|wx.RIGHT, 10)
98 mcSizer.Add(self.className, 1, 0)
99 ctlsSizer.Add(mcSizer, 0, wx.EXPAND)
100
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)
104 ctlsSizer.Add(wx.StaticText(p, -1, "Create Expr:"),
105 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
106 ctlsSizer.Add(self.expression, 0, wx.EXPAND)
107 ctlsSizer.Add(wx.StaticText(p, -1, "Post create:"), 0, wx.ALIGN_RIGHT)
108 ctlsSizer.Add(self.postCreate, 0, wx.EXPAND)
109 ctlsSizer.Add(wx.StaticText(p, -1, "DocString:"), 0, wx.ALIGN_RIGHT)
110 ctlsSizer.Add(self.docstring, 0, wx.EXPAND)
111 ctlsSizer.AddGrowableRow(4)
112 topSizer.Add(ctlsSizer, 1, wx.EXPAND)
113
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
130 mainSizer.Add(self.infoPane, 0, wx.EXPAND)
131
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)
137
138 p.SetSizerAndFit(mainSizer)
139 self.Fit()
140
141 self.PopulateHistory()
142
143
144
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()
159
160 for idx in range(len(self.history)):
161 item = self.history[idx]
162 # check if it is too short
163 while len(item) < 4:
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()
189 postCreate = self.postCreate.GetValue()
190
191 item = [str(moduleName), str(className), str(parameters), str(postCreate)]
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
205 self.OnClear(None)
206
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()
214 postCreate = self.postCreate.GetValue()
215
216 item = [str(moduleName), str(className), str(parameters), str(postCreate)]
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):
223 #idx = self.testHistory.GetSelection()
224 idx = evt.GetInt()
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])
230 self.postCreate.SetValue(item[3])
231 if 'wxMac' in wx.PlatformInfo:
232 self.OnUpdate(None)
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)
240
241
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
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()
255
256 expr = "w = %s.%s( testPanel, %s )" % (moduleName, className, parameters)
257 self.expression.SetValue(expr)
258
259 docstring = None
260 try:
261 docstring = eval("%s.%s.__init__.__doc__" % (moduleName, className))
262 except:
263 pass
264 if docstring is not None:
265 self.docstring.SetValue(docstring)
266 else:
267 self.docstring.SetValue("")
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
279
280 testPanel = self.testPanel
281
282 # get the details from the form
283 moduleName = self.moduleName.GetValue()
284 className = self.className.GetValue()
285 parameters = self.parameters.GetValue()
286 expr = self.expression.GetValue()[4:]
287 postCreate = self.postCreate.GetValue()
288 if 'wxMac' in wx.PlatformInfo:
289 postCreate = postCreate.replace('\r', '\n')
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
307
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()
319 w.Destroy()
320 return
321
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
332 self.infoPane.Update(w, testPanel)
333
334
335 def OnDestroyWidget(self, evt):
336 self.testWidget.Destroy()
337 self.testWidget = None
338 self.testPanel.SetSizer(None, True)
339 self.testPanel.Refresh()
340
341 # ensure the panel shrinks again
342 self.testPanel.SetSizeHints((20,20))
343 self.bottomSizer.Layout()
344 self.testPanel.SetSizeHints(wx.DefaultSize)
345
346 # make the create button be default now
347 self.createBtn.SetDefault()
348
349 self.infoPane.Clear()
350
351
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("")
358 self.postCreate.SetValue("")
359
360
361
362
363
364
365 class 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
399 class 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
454 class 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()
495
496 self._fgtxt.SetValue( clr2hex(win.GetForegroundColour(), self._fgclr) )
497 self._bgtxt.SetValue( clr2hex(win.GetBackgroundColour(), self._bgclr) )
498
499 ## f = win.GetFont()
500 ## print f.GetNativeFontInfo().ToString()
501
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()
510
511
512
513
514 app = wx.PySimpleApp(redirect=False)
515 frame = LayoutTestFrame()
516 app.SetTopWindow(frame)
517 frame.Show()
518 app.MainLoop()
519