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.
13 print "wx.VERSION_STRING = ", wx
.VERSION_STRING
14 print "pid:", os
.getpid()
15 ##raw_input("Press Enter...")
17 class LayoutTestFrame(wx
.Frame
):
19 wx
.Frame
.__init
__(self
, None, -1, "Widget Layout Tester")
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
)
34 self
.expression
.SetBackgroundColour(
35 wx
.SystemSettings
.GetColour(wx
.SYS_COLOUR_INFOBK
))
36 self
.docstring
.SetBackgroundColour(
37 wx
.SystemSettings
.GetColour(wx
.SYS_COLOUR_INFOBK
))
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")
48 self
.createBtn
= createBtn
49 self
.destroyBtn
= destroyBtn
51 bottomPanel
= wx
.Panel(p
, style
=wx
.SUNKEN_BORDER
, name
="bottomPanel")
52 bottomPanel
.SetMinSize((640,240))
53 bottomPanel
.SetOwnBackgroundColour("light blue")
55 self
.testPanel
= wx
.Panel(bottomPanel
, name
="testPanel")
56 self
.testPanel
.SetOwnBackgroundColour((205, 183, 181)) # mistyrose3
57 self
.testWidget
= None
59 self
.infoPane
= InfoPane(p
)
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
)
71 self
.Bind(wx
.EVT_CLOSE
, self
.OnSaveHistory
)
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
)
79 if 'wxMac' in wx
.PlatformInfo
or 'wxGTK' in wx
.PlatformInfo
:
80 self
.testHistory
.Bind(wx
.EVT_KEY_DOWN
, self
.OnHistoryKey
)
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
)
90 topSizer
.Add(self
.testHistory
, 0, wx
.RIGHT
, 30)
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
)
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
)
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)
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
)
130 mainSizer
.Add(self
.infoPane
, 0, wx
.EXPAND
)
132 self
.bottomSizer
= sz
= wx
.BoxSizer(wx
.VERTICAL
)
134 sz
.Add(self
.testPanel
, 0, wx
.ALIGN_CENTER
)
136 bottomPanel
.SetSizer(sz
)
138 p
.SetSizerAndFit(mainSizer
)
141 self
.PopulateHistory()
146 def PopulateHistory(self
):
148 Load and eval a list of lists from a file, load the contents
149 into self.testHistory
151 fname
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
152 'widgetLayoutTest.cfg')
154 self
.history
= eval(open(fname
).read())
158 self
.testHistory
.Clear()
160 for idx
in range(len(self
.history
)):
161 item
= self
.history
[idx
]
162 # check if it is too short
166 # add it to the listbox
167 self
.testHistory
.Append(item
[0] + '.' + item
[1])
169 self
.needSaved
= False
172 def OnSaveHistory(self
, evt
):
174 fname
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
175 'widgetLayoutTest.cfg')
176 f
= open(fname
, 'wb')
178 for item
in self
.history
:
179 f
.write(str(item
) + ',\n')
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()
191 item
= [str(moduleName
), str(className
), str(parameters
), str(postCreate
)]
192 self
.history
.append(item
)
193 self
.testHistory
.Append(item
[0] + '.' + item
[1])
195 self
.testHistory
.SetSelection(len(self
.history
)-1)
196 self
.needSaved
= True
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
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()
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
222 def OnHistorySelect(self
, evt
):
223 #idx = self.testHistory.GetSelection()
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
:
235 def OnHistoryActivate(self
, evt
):
236 btn
= self
.testHistory
.GetParent().GetDefaultItem()
238 e
= wx
.CommandEvent(wx
.wxEVT_COMMAND_BUTTON_CLICKED
, btn
.GetId())
242 def OnHistoryKey(self
, evt
):
243 key
= evt
.GetKeyCode()
244 if key
== wx
.WXK_RETURN
:
245 self
.OnHistoryActivate(None)
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()
256 expr
= "w = %s.%s( testPanel, %s )" % (moduleName
, className
, parameters
)
257 self
.expression
.SetValue(expr
)
261 docstring
= eval("%s.%s.__init__.__doc__" % (moduleName
, className
))
264 if docstring
is not None:
265 self
.docstring
.SetValue(docstring
)
267 self
.docstring
.SetValue("")
269 def OnEnableDestroy(self
, evt
):
270 evt
.Enable(self
.testWidget
is not None)
272 def OnEnableCreate(self
, evt
):
273 evt
.Enable(self
.testWidget
is None)
276 def OnCreateWidget(self
, evt
):
277 if self
.testWidget
is not None:
280 testPanel
= self
.testPanel
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')
291 # make sure the module is imported already
292 if not sys
.modules
.has_key(moduleName
):
294 m
= __import__(moduleName
)
296 wx
.MessageBox("Unable to import module!", "Error")
303 wx
.MessageBox("Got a '%s' Exception!" % e
.__class
__.__name
__, "Error")
305 traceback
.print_exc()
308 # Is there postCreate code?
314 exec postCreate
in ns
316 wx
.MessageBox("Got a '%s' Exception!" % e
.__class
__.__name
__, "Error")
318 traceback
.print_exc()
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
)
327 self
.bottomSizer
.Layout()
329 # make the destroy button be default now
330 self
.destroyBtn
.SetDefault()
332 self
.infoPane
.Update(w
, testPanel
)
335 def OnDestroyWidget(self
, evt
):
336 self
.testWidget
.Destroy()
337 self
.testWidget
= None
338 self
.testPanel
.SetSizer(None, True)
339 self
.testPanel
.Refresh()
341 # ensure the panel shrinks again now that it has no sizer
342 self
.testPanel
.SetMinSize((20,20))
343 self
.bottomSizer
.Layout()
344 self
.testPanel
.SetMinSize(wx
.DefaultSize
)
346 # make the create button be default now
347 self
.createBtn
.SetDefault()
349 self
.infoPane
.Clear()
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("")
365 class InfoPane(wx
.Panel
):
367 This class is used to display details of various properties of the
368 widget and the testPanel to aid with debugging.
370 def __init__(self
, parent
):
371 wx
.Panel
.__init
__(self
, parent
)
374 self
.wPane
= SizeInfoPane(self
, "Widget")
375 self
.tpPane
= SizeInfoPane(self
, "testPanel")
376 self
.cPane
= ColourInfoPanel(self
, "Widget colours")
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)
387 def Update(self
, w
, tp
):
389 self
.tpPane
.Update(tp
)
399 class SizeInfoPane(wx
.Panel
):
401 A component of the InfoPane that shows vaious window size attributes.
403 def __init__(self
, parent
, label
):
404 wx
.Panel
.__init
__(self
, parent
)
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 self
._bestfit
= wx
.TextCtrl(self
, -1, "", style
=wx
.TE_READONLY
)
415 fgs
= wx
.FlexGridSizer(2, 2, 5, 5)
416 fgs
.AddGrowableCol(1)
418 fgs
.Add(wx
.StaticText(self
, -1, "Size:"),
419 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
420 fgs
.Add(self
._size
, 0, wx
.EXPAND
)
422 fgs
.Add(wx
.StaticText(self
, -1, "MinSize:"),
423 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
424 fgs
.Add(self
._minsize
, 0, wx
.EXPAND
)
426 fgs
.Add(wx
.StaticText(self
, -1, "BestSize:"),
427 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
428 fgs
.Add(self
._bestsize
, 0, wx
.EXPAND
)
430 fgs
.Add(wx
.StaticText(self
, -1, "AdjustedBestSize:"),
431 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
432 fgs
.Add(self
._adjbstsize
, 0, wx
.EXPAND
)
434 fgs
.Add(wx
.StaticText(self
, -1, "BestFittingSize:"),
435 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
436 fgs
.Add(self
._bestfit
, 0, wx
.EXPAND
)
438 sbs
= wx
.StaticBoxSizer(sb
, wx
.VERTICAL
)
439 sbs
.Add(fgs
, 0, wx
.EXPAND|wx
.ALL
, 4)
444 def Update(self
, win
):
445 self
._size
.SetValue( str(win
.GetSize()) )
446 self
._minsize
.SetValue( str(win
.GetMinSize()) )
447 self
._bestsize
.SetValue( str(win
.GetBestSize()) )
448 self
._adjbstsize
.SetValue( str(win
.GetAdjustedBestSize()) )
449 self
._bestfit
.SetValue( str(win
.GetEffectiveMinSize()) )
452 self
._size
.SetValue("")
453 self
._minsize
.SetValue("")
454 self
._bestsize
.SetValue("")
455 self
._adjbstsize
.SetValue("")
456 self
._bestfit
.SetValue("")
460 class ColourInfoPanel(wx
.Panel
):
462 A component of the InfoPane that shows fg and bg colour attributes.
464 def __init__(self
, parent
, label
):
465 wx
.Panel
.__init
__(self
, parent
)
468 sb
= wx
.StaticBox(self
, -1, label
)
469 self
._fgtxt
= wx
.TextCtrl(self
, -1, "", style
=wx
.TE_READONLY
)
470 self
._fgclr
= wx
.Panel(self
, style
=wx
.SIMPLE_BORDER
)
471 self
._fgclr
.SetMinSize((20,20))
472 self
._bgtxt
= wx
.TextCtrl(self
, -1, "", style
=wx
.TE_READONLY
)
473 self
._bgclr
= wx
.Panel(self
, style
=wx
.SIMPLE_BORDER
)
474 self
._bgclr
.SetMinSize((20,20))
477 fgs
= wx
.FlexGridSizer(2, 3, 5, 5)
478 fgs
.AddGrowableCol(1)
480 fgs
.Add(wx
.StaticText(self
, -1, "FG colour:"),
481 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
482 fgs
.Add(self
._fgtxt
, 0, wx
.EXPAND
)
485 fgs
.Add(wx
.StaticText(self
, -1, "BG colour:"),
486 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
487 fgs
.Add(self
._bgtxt
, 0, wx
.EXPAND
)
490 sbs
= wx
.StaticBoxSizer(sb
, wx
.VERTICAL
)
491 sbs
.Add(fgs
, 0, wx
.EXPAND|wx
.ALL
, 4)
496 def Update(self
, win
):
498 cp
.SetBackgroundColour(c
)
500 return "#%02X%02X%02X" % c
.Get()
502 self
._fgtxt
.SetValue( clr2hex(win
.GetForegroundColour(), self
._fgclr
) )
503 self
._bgtxt
.SetValue( clr2hex(win
.GetBackgroundColour(), self
._bgclr
) )
507 self
._fgtxt
.SetValue("")
508 self
._bgtxt
.SetValue("")
509 self
._fgclr
.SetBackgroundColour(self
.GetBackgroundColour())
510 self
._bgclr
.SetBackgroundColour(self
.GetBackgroundColour())
511 self
._fgclr
.Refresh()
512 self
._bgclr
.Refresh()
517 app
= wx
.PySimpleApp(redirect
=False)
518 frame
= LayoutTestFrame()
519 app
.SetTopWindow(frame
)