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 testImage
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]), 'image.png')
20 class LayoutTestFrame(wx
.Frame
):
22 wx
.Frame
.__init
__(self
, None, -1, "Widget Layout Tester")
26 # Create control widgets
27 self
.testHistory
= wx
.ListBox(p
, -1, size
=(150, 300))
28 self
.moduleName
= wx
.TextCtrl(p
, -1, "wx")
29 self
.className
= wx
.TextCtrl(p
, -1, "")
30 self
.parameters
= wx
.TextCtrl(p
, -1, "")
31 self
.postCreate
= wx
.TextCtrl(p
, -1, "", size
=(1,75),
32 style
=wx
.TE_MULTILINE|wx
.TE_DONTWRAP
)
33 self
.expression
= wx
.TextCtrl(p
, -1, "", style
=wx
.TE_READONLY
)
34 self
.docstring
= wx
.TextCtrl(p
, -1, "", size
=(1,75),
35 style
=wx
.TE_READONLY|wx
.TE_MULTILINE|wx
.TE_DONTWRAP
)
37 self
.expression
.SetBackgroundColour(
38 wx
.SystemSettings
.GetColour(wx
.SYS_COLOUR_INFOBK
))
39 self
.docstring
.SetBackgroundColour(
40 wx
.SystemSettings
.GetColour(wx
.SYS_COLOUR_INFOBK
))
43 addBtn
= wx
.Button(p
, -1, "Add")
44 remBtn
= wx
.Button(p
, -1, "Remove")
45 repBtn
= wx
.Button(p
, -1, "Replace")
46 createBtn
= wx
.Button(p
, -1, " Create Widget ")
47 createBtn
.SetDefault()
48 destroyBtn
= wx
.Button(p
, -1, "Destroy Widget")
49 clearBtn
= wx
.Button(p
, -1, "Clear")
51 self
.createBtn
= createBtn
52 self
.destroyBtn
= destroyBtn
54 bottomPanel
= wx
.Panel(p
, style
=wx
.SUNKEN_BORDER
, name
="bottomPanel")
55 bottomPanel
.SetMinSize((640,240))
56 bottomPanel
.SetOwnBackgroundColour("light blue")
58 self
.testPanel
= wx
.Panel(bottomPanel
, name
="testPanel")
59 self
.testPanel
.SetOwnBackgroundColour((205, 183, 181)) # mistyrose3
60 self
.testWidget
= None
62 self
.infoPane
= InfoPane(p
)
64 # setup event bindings
65 self
.Bind(wx
.EVT_TEXT
, self
.OnUpdate
, self
.moduleName
)
66 self
.Bind(wx
.EVT_TEXT
, self
.OnUpdate
, self
.className
)
67 self
.Bind(wx
.EVT_TEXT
, self
.OnUpdate
, self
.parameters
)
68 self
.Bind(wx
.EVT_UPDATE_UI
, self
.OnEnableCreate
, createBtn
)
69 self
.Bind(wx
.EVT_UPDATE_UI
, self
.OnEnableDestroy
, destroyBtn
)
70 self
.Bind(wx
.EVT_BUTTON
, self
.OnCreateWidget
, createBtn
)
71 self
.Bind(wx
.EVT_BUTTON
, self
.OnDestroyWidget
, destroyBtn
)
72 self
.Bind(wx
.EVT_BUTTON
, self
.OnClear
, clearBtn
)
74 self
.Bind(wx
.EVT_CLOSE
, self
.OnSaveHistory
)
76 self
.Bind(wx
.EVT_BUTTON
, self
.OnAddHistory
, addBtn
)
77 self
.Bind(wx
.EVT_BUTTON
, self
.OnRemoveHistory
, remBtn
)
78 self
.Bind(wx
.EVT_BUTTON
, self
.OnReplaceHistory
, repBtn
)
79 self
.Bind(wx
.EVT_LISTBOX
, self
.OnHistorySelect
, self
.testHistory
)
80 self
.Bind(wx
.EVT_LISTBOX_DCLICK
, self
.OnHistoryActivate
, self
.testHistory
)
82 if 'wxMac' in wx
.PlatformInfo
or 'wxGTK' in wx
.PlatformInfo
:
83 self
.testHistory
.Bind(wx
.EVT_KEY_DOWN
, self
.OnHistoryKey
)
87 mainSizer
= wx
.BoxSizer(wx
.VERTICAL
)
88 topSizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
89 ctlsSizer
= wx
.FlexGridSizer(2, 2, 5, 5)
90 ctlsSizer
.AddGrowableCol(1)
91 btnSizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
93 topSizer
.Add(self
.testHistory
, 0, wx
.RIGHT
, 30)
95 ctlsSizer
.Add(wx
.StaticText(p
, -1, "Module name:"),
96 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
97 mcSizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
98 mcSizer
.Add(self
.moduleName
, 0, 0)
99 mcSizer
.Add(wx
.StaticText(p
, -1, "Class name:"),
100 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL |wx
.LEFT|wx
.RIGHT
, 10)
101 mcSizer
.Add(self
.className
, 1, 0)
102 ctlsSizer
.Add(mcSizer
, 0, wx
.EXPAND
)
104 ctlsSizer
.Add(wx
.StaticText(p
, -1, "Parameters:"),
105 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
106 ctlsSizer
.Add(self
.parameters
, 0, wx
.EXPAND
)
107 ctlsSizer
.Add(wx
.StaticText(p
, -1, "Create Expr:"),
108 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
109 ctlsSizer
.Add(self
.expression
, 0, wx
.EXPAND
)
110 ctlsSizer
.Add(wx
.StaticText(p
, -1, "Post create:"), 0, wx
.ALIGN_RIGHT
)
111 ctlsSizer
.Add(self
.postCreate
, 0, wx
.EXPAND
)
112 ctlsSizer
.Add(wx
.StaticText(p
, -1, "DocString:"), 0, wx
.ALIGN_RIGHT
)
113 ctlsSizer
.Add(self
.docstring
, 0, wx
.EXPAND
)
114 ctlsSizer
.AddGrowableRow(4)
115 topSizer
.Add(ctlsSizer
, 1, wx
.EXPAND
)
118 btnSizer
.Add(addBtn
, 0, wx
.RIGHT
, 5)
119 btnSizer
.Add(remBtn
, 0, wx
.RIGHT
, 5)
120 btnSizer
.Add(repBtn
, 0, wx
.RIGHT
, 5)
121 btnSizer
.Add((0,0), 1)
122 btnSizer
.Add(createBtn
, 0, wx
.RIGHT
, 5)
123 btnSizer
.Add(destroyBtn
, 0, wx
.RIGHT
, 5)
124 btnSizer
.Add(clearBtn
, 0, wx
.RIGHT
, 5)
125 btnSizer
.Add((0,0), 1)
127 mainSizer
.Add(topSizer
, 0, wx
.EXPAND|wx
.ALL
, 10)
128 mainSizer
.Add(btnSizer
, 0, wx
.EXPAND
)
129 mainSizer
.Add((10,10))
130 ##mainSizer.Add(wx.StaticLine(p, -1), 0, wx.EXPAND)
131 mainSizer
.Add(bottomPanel
, 1, wx
.EXPAND
)
133 mainSizer
.Add(self
.infoPane
, 0, wx
.EXPAND
)
135 self
.bottomSizer
= sz
= wx
.BoxSizer(wx
.VERTICAL
)
137 sz
.Add(self
.testPanel
, 0, wx
.ALIGN_CENTER
)
139 bottomPanel
.SetSizer(sz
)
141 p
.SetSizerAndFit(mainSizer
)
144 self
.PopulateHistory()
149 def PopulateHistory(self
):
151 Load and eval a list of lists from a file, load the contents
152 into self.testHistory
154 fname
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]), 'widgets.cfg')
156 self
.history
= eval(open(fname
).read())
160 self
.testHistory
.Clear()
162 for idx
in range(len(self
.history
)):
163 item
= self
.history
[idx
]
164 # check if it is too short
168 # add it to the listbox
169 self
.testHistory
.Append(item
[0] + '.' + item
[1])
171 self
.needSaved
= False
174 def OnSaveHistory(self
, evt
):
176 fname
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]), 'widgets.cfg')
177 f
= open(fname
, 'wb')
179 for item
in self
.history
:
180 f
.write(str(item
) + ',\n')
186 def OnAddHistory(self
, evt
):
187 moduleName
= self
.moduleName
.GetValue()
188 className
= self
.className
.GetValue()
189 parameters
= self
.parameters
.GetValue()
190 postCreate
= self
.postCreate
.GetValue()
192 item
= [str(moduleName
), str(className
), str(parameters
), str(postCreate
)]
193 self
.history
.append(item
)
194 self
.testHistory
.Append(item
[0] + '.' + item
[1])
196 self
.testHistory
.SetSelection(len(self
.history
)-1)
197 self
.needSaved
= True
200 def OnRemoveHistory(self
, evt
):
201 idx
= self
.testHistory
.GetSelection()
202 if idx
!= wx
.NOT_FOUND
:
203 del self
.history
[idx
]
204 self
.testHistory
.Delete(idx
)
205 self
.needSaved
= True
209 def OnReplaceHistory(self
, evt
):
210 idx
= self
.testHistory
.GetSelection()
211 if idx
!= wx
.NOT_FOUND
:
212 moduleName
= self
.moduleName
.GetValue()
213 className
= self
.className
.GetValue()
214 parameters
= self
.parameters
.GetValue()
215 postCreate
= self
.postCreate
.GetValue()
217 item
= [str(moduleName
), str(className
), str(parameters
), str(postCreate
)]
218 self
.history
[idx
] = item
219 self
.testHistory
.SetString(idx
, item
[0] + '.' + item
[1])
220 self
.needSaved
= True
223 def OnHistorySelect(self
, evt
):
224 #idx = self.testHistory.GetSelection()
226 if idx
!= wx
.NOT_FOUND
:
227 item
= self
.history
[idx
]
228 self
.moduleName
.SetValue(item
[0])
229 self
.className
.SetValue(item
[1])
230 self
.parameters
.SetValue(item
[2])
231 self
.postCreate
.SetValue(item
[3])
232 if 'wxMac' in wx
.PlatformInfo
:
236 def OnHistoryActivate(self
, evt
):
237 btn
= self
.testHistory
.GetTopLevelParent().GetDefaultItem()
239 e
= wx
.CommandEvent(wx
.wxEVT_COMMAND_BUTTON_CLICKED
, btn
.GetId())
243 def OnHistoryKey(self
, evt
):
244 key
= evt
.GetKeyCode()
245 if key
== wx
.WXK_RETURN
:
246 self
.OnHistoryActivate(None)
251 def OnUpdate(self
, evt
):
252 # get the details from the form
253 moduleName
= self
.moduleName
.GetValue()
254 className
= self
.className
.GetValue()
255 parameters
= self
.parameters
.GetValue()
257 expr
= "w = %s.%s( testPanel, %s )" % (moduleName
, className
, parameters
)
258 self
.expression
.SetValue(expr
)
262 docstring
= eval("%s.%s.__init__.__doc__" % (moduleName
, className
))
265 if docstring
is not None:
266 self
.docstring
.SetValue(docstring
)
268 self
.docstring
.SetValue("")
270 def OnEnableDestroy(self
, evt
):
271 evt
.Enable(self
.testWidget
is not None)
273 def OnEnableCreate(self
, evt
):
274 evt
.Enable(self
.testWidget
is None)
277 def OnCreateWidget(self
, evt
):
278 if self
.testWidget
is not None:
281 testPanel
= self
.testPanel
283 # get the details from the form
284 moduleName
= self
.moduleName
.GetValue()
285 className
= self
.className
.GetValue()
286 parameters
= self
.parameters
.GetValue()
287 expr
= self
.expression
.GetValue()[4:]
288 postCreate
= self
.postCreate
.GetValue()
289 if 'wxMac' in wx
.PlatformInfo
:
290 postCreate
= postCreate
.replace('\r', '\n')
292 # make sure the module is imported already
293 if not sys
.modules
.has_key(moduleName
):
295 m
= __import__(moduleName
)
297 wx
.MessageBox("Unable to import module!", "Error")
304 wx
.MessageBox("Got a '%s' Exception!" % e
.__class
__.__name
__, "Error")
306 traceback
.print_exc()
309 # Is there postCreate code?
315 exec postCreate
in ns
317 wx
.MessageBox("Got a '%s' Exception!" % e
.__class
__.__name
__, "Error")
319 traceback
.print_exc()
323 # Put the widget in a sizer and the sizer in the testPanel
324 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
325 sizer
.Add(w
, 0, wx
.ALL
, 5)
326 self
.testPanel
.SetSizer(sizer
)
328 self
.bottomSizer
.Layout()
330 # make the destroy button be default now
331 self
.destroyBtn
.SetDefault()
333 self
.infoPane
.Update(w
, testPanel
)
336 def OnDestroyWidget(self
, evt
):
337 self
.testWidget
.Destroy()
338 self
.testWidget
= None
339 self
.testPanel
.SetSizer(None, True)
340 self
.testPanel
.Refresh()
342 # ensure the panel shrinks again now that it has no sizer
343 self
.testPanel
.SetMinSize((20,20))
344 self
.bottomSizer
.Layout()
345 self
.testPanel
.SetMinSize(wx
.DefaultSize
)
347 # make the create button be default now
348 self
.createBtn
.SetDefault()
350 self
.infoPane
.Clear()
353 def OnClear(self
, evt
):
354 self
.moduleName
.SetValue("")
355 self
.className
.SetValue("")
356 self
.parameters
.SetValue("")
357 self
.expression
.SetValue("")
358 self
.docstring
.SetValue("")
359 self
.postCreate
.SetValue("")
366 class InfoPane(wx
.Panel
):
368 This class is used to display details of various properties of the
369 widget and the testPanel to aid with debugging.
371 def __init__(self
, parent
):
372 wx
.Panel
.__init
__(self
, parent
)
375 self
.wPane
= SizeInfoPane(self
, "Widget")
376 self
.tpPane
= SizeInfoPane(self
, "testPanel")
377 self
.cPane
= ColourInfoPanel(self
, "Widget colours")
380 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
381 sizer
.Add(self
.wPane
, 0, wx
.EXPAND|wx
.ALL
, 5)
382 sizer
.Add(self
.tpPane
, 0, wx
.EXPAND|wx
.ALL
, 5)
383 sizer
.Add(self
.cPane
, 0, wx
.EXPAND|wx
.ALL
, 5)
388 def Update(self
, w
, tp
):
390 self
.tpPane
.Update(tp
)
400 class SizeInfoPane(wx
.Panel
):
402 A component of the InfoPane that shows vaious window size attributes.
404 def __init__(self
, parent
, label
):
405 wx
.Panel
.__init
__(self
, parent
)
408 sb
= wx
.StaticBox(self
, -1, label
)
409 self
._size
= wx
.TextCtrl(self
, -1, "", style
=wx
.TE_READONLY
)
410 self
._minsize
= wx
.TextCtrl(self
, -1, "", style
=wx
.TE_READONLY
)
411 self
._bestsize
= wx
.TextCtrl(self
, -1, "", style
=wx
.TE_READONLY
)
412 self
._effmin
= 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, "EffectiveMinSize:"),
431 0, wx
.ALIGN_RIGHT|wx
.ALIGN_CENTER_VERTICAL
)
432 fgs
.Add(self
._effmin
, 0, wx
.EXPAND
)
434 sbs
= wx
.StaticBoxSizer(sb
, wx
.VERTICAL
)
435 sbs
.Add(fgs
, 0, wx
.EXPAND|wx
.ALL
, 4)
440 def Update(self
, win
):
441 self
._size
.SetValue( str(win
.GetSize()) )
442 self
._minsize
.SetValue( str(win
.GetMinSize()) )
443 self
._bestsize
.SetValue( str(win
.GetBestSize()) )
444 self
._effmin
.SetValue( str(win
.GetEffectiveMinSize()) )
447 self
._size
.SetValue("")
448 self
._minsize
.SetValue("")
449 self
._bestsize
.SetValue("")
450 self
._effmin
.SetValue("")
454 class ColourInfoPanel(wx
.Panel
):
456 A component of the InfoPane that shows fg and bg colour attributes.
458 def __init__(self
, parent
, label
):
459 wx
.Panel
.__init
__(self
, parent
)
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
.SetMinSize((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
.SetMinSize((20,20))
471 fgs
= wx
.FlexGridSizer(2, 3, 5, 5)
472 fgs
.AddGrowableCol(1)
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
)
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
)
484 sbs
= wx
.StaticBoxSizer(sb
, wx
.VERTICAL
)
485 sbs
.Add(fgs
, 0, wx
.EXPAND|wx
.ALL
, 4)
490 def Update(self
, win
):
492 cp
.SetBackgroundColour(c
)
494 return "#%02X%02X%02X" % c
.Get()
496 self
._fgtxt
.SetValue( clr2hex(win
.GetForegroundColour(), self
._fgclr
) )
497 self
._bgtxt
.SetValue( clr2hex(win
.GetBackgroundColour(), self
._bgclr
) )
501 self
._fgtxt
.SetValue("")
502 self
._bgtxt
.SetValue("")
503 self
._fgclr
.SetBackgroundColour(self
.GetBackgroundColour())
504 self
._bgclr
.SetBackgroundColour(self
.GetBackgroundColour())
505 self
._fgclr
.Refresh()
506 self
._bgclr
.Refresh()
511 app
= wx
.PySimpleApp(redirect
=False)
512 frame
= LayoutTestFrame()
513 app
.SetTopWindow(frame
)