2 import wxaddons
.sized_controls 
as sc
 
   5 <html><body><h2>Sized Controls</h2> 
   6 SizedControls is an addon library that attempts to simplify the 
   7 creation of sizer-based layouts. It adds the following classes: 
  11 This class automatically creates its own sizer (a vertical box sizer 
  12 by default) and automatically adds its children to the sizer. You can 
  13 change the SizedPanel's sizer type by calling 
  14 panel.SetSizerType(\"type\", [args]), where valid types are 
  15 \"horizontal\", \"vertical\", \"form\" (a 2-col flex grid sizer), and 
  16 \"grid\". Args include \"cols\" and \"rows\" attributes for 
  17 grids. This class also applies control borders that adhere to the 
  18 native platform's Human Interface Guidelines (HIG) on Win, GTK and 
  21 <h3>SizedFrame and SizedDialog</h3> 
  23 These classes automatically setup a SizedPanel which is appropriately 
  24 positioned and given appropriate borders in accordance with the 
  27 <p>Since controls are added to the parent's sizer upon creation, you 
  28 don't need to use sizer.Add or even create sizers yourself. You just 
  29 use SetSizerType() to change the sizer you want to use, and 
  30 control.SetSizerProps() to change the sizer properties of the 
  31 control. So as a result, code that used to look like this: 
  33 <table bgcolor=\"#EFEFEF\"><tr><td><pre> 
  34 ... wx.Dialog init code... 
  36 panel = wx.Panel(self, -1) 
  37 b1 = wx.Button(panel, -1) 
  38 b2 = wx.Button(panel, -1) 
  39 t1 = wx.TextCtrl(panel, -1) 
  40 b3 = wx.Button(panel, -1) 
  42 sizer = wx.BoxSizer(wx.HORIZONTAL) 
  43 sizer.Add(b1, 0, wx.ALL, 6) 
  44 sizer.Add(b2, 0, wx.ALL, 6) 
  45 sizer.Add(t1, 0, wx.EXPAND | wx.ALL, 6) 
  46 sizer.Add(b3, 0, wx.ALL, 6) 
  49 dlgSizer = wx.BoxSizer() 
  50 dlgSizer.Add(panel, 1, wx.EXPAND) 
  51 self.SetSizer(dlgSizer) 
  52 self.SetAutoLayout(True) 
  54 ... rest of dialog ...</pre> 
  57 would now look like this: 
  59 <table bgcolor=\"#EFEFEF\"><tr><td><pre> 
  60 ... wx.Dialog init code... 
  62 panel = self.GetContentsPane() 
  63 panel.SetSizerType(\"horizontal\") 
  65 b1 = wx.Button(panel, -1) 
  66 b2 = wx.Button(panel, -1) 
  68 t1 = wx.TextCtrl(panel, -1) 
  69 t1.SetSizerProps(expand=True) 
  71 b3 = wx.Button(panel, -1) 
  73 ... rest of dialog ...</pre> 
  76 and the latter example will adhere to HIG spacing guidelines on all platforms, 
  77 unlike the former example. Please check the demos for more complete and sophisticated examples of SizedControls 
  80 <h3>wx.Window.SetSizerProps Quick Reference</h3> 
  82 <p><pre>wx.Window.SetSizerProps(<props>)</pre> 
  85 <table bgcolor=\"#EFEFEF\"> 
  87 <td valign="middle" width="90"><b>Parameter</b></td> <td valign="middle"><b>Values</b></td> <td valign="middle"><b>Summary</b></td> 
  91 <td><i>expand</i></td> <td>True/False</td> 
  92 <td>Whether or not the control should grow to fill free space if  
  93 free space is available.</td> 
  97 <td><i>proportion</i></td> <td>Number (typically 0-10)</td>  
  98 <td>How much of the free space the control should take up. Note that this value is  
  99 <i>relative</i> to other controls, so a proportion of 2 means take up  
 100 'twice as much' space as controls with a proportion of 1.</td> 
 104 <td><i>halign</i> <td>"left", "center", "centre", "right"</td> 
 105 <td>Determines horizontal alignment of control.</td> 
 109 <td><i>valign</i> <td>"top", "center", "centre", "bottom"</td> 
 110 <td>Determines vertical alignment of control.</td> 
 114 <td><i>border</i> <td>Tuple: ([<i>dirs</i>], integer)</td> 
 115 <td>Specifies amount of border padding to apply to specified directions. </br> 
 116 Example: (["left", "right"], 6) would add six pixels to left and right borders. </br> 
 117 Note that, unfortunately, 
 118 it is not currently possible to assign different border sizes to each direction.</td> 
 122 <td><i>minsize</i> <td>One of the following string values: "fixed", "adjust"</td> 
 123 <td>Determines whether or not the minsize can be updated when the control's best size changes.</td> 
 129 class FormDialog(sc
.SizedDialog
): 
 130     def __init__(self
, parent
, id): 
 131         sc
.SizedDialog
.__init
__(self
, None, -1, "SizedForm Dialog",  
 132                         style
=wx
.DEFAULT_DIALOG_STYLE | wx
.RESIZE_BORDER
) 
 134         pane 
= self
.GetContentsPane() 
 135         pane
.SetSizerType("form") 
 138         wx
.StaticText(pane
, -1, "Name") 
 139         textCtrl 
= wx
.TextCtrl(pane
, -1, "Your name here") 
 140         textCtrl
.SetSizerProps(expand
=True) 
 143         wx
.StaticText(pane
, -1, "Email") 
 144         emailCtrl 
= wx
.TextCtrl(pane
, -1, "") 
 145         emailCtrl
.SetSizerProps(expand
=True) 
 148         wx
.StaticText(pane
, -1, "Gender") 
 149         wx
.Choice(pane
, -1, choices
=["male", "female"]) 
 152         wx
.StaticText(pane
, -1, "State") 
 153         wx
.TextCtrl(pane
, -1, size
=(60, -1)) # two chars for state 
 156         wx
.StaticText(pane
, -1, "Title") 
 158         # here's how to add a 'nested sizer' using sized_controls 
 159         radioPane 
= sc
.SizedPanel(pane
, -1) 
 160         radioPane
.SetSizerType("horizontal") 
 161         radioPane
.SetSizerProps(expand
=True) 
 163         # make these children of the radioPane to have them use 
 164         # the horizontal layout 
 165         wx
.RadioButton(radioPane
, -1, "Mr.") 
 166         wx
.RadioButton(radioPane
, -1, "Mrs.") 
 167         wx
.RadioButton(radioPane
, -1, "Dr.") 
 171         self
.SetButtonSizer(self
.CreateStdDialogButtonSizer(wx
.OK | wx
.CANCEL
)) 
 173         # a little trick to make sure that you can't resize the dialog to 
 174         # less screen space than the controls need 
 176         self
.SetMinSize(self
.GetSize()) 
 179 class ErrorDialog(sc
.SizedDialog
): 
 180     def __init__(self
, parent
, id): 
 181         sc
.SizedDialog
.__init
__(self
, parent
, id, "Error log viewer",  
 182                                 style
=wx
.DEFAULT_DIALOG_STYLE|wx
.RESIZE_BORDER
) 
 184         # Always use self.GetContentsPane() - this ensures that your dialog 
 185         # automatically adheres to HIG spacing requirements on all platforms. 
 186         # pane here is a sc.SizedPanel with a vertical sizer layout. All children 
 187         # should be added to this pane, NOT to self. 
 188         pane 
= self
.GetContentsPane() 
 191         self
.listCtrl 
= wx
.ListCtrl(pane
, -1, size
=(300, -1), style
=wx
.LC_REPORT
) 
 192         self
.listCtrl
.SetSizerProps(expand
=True, proportion
=1) 
 193         self
.ConfigureListCtrl() 
 196         self
.lblDetails 
= wx
.StaticText(pane
, -1, "Error Details") 
 199         self
.details 
= wx
.TextCtrl(pane
, -1, style
=wx
.TE_MULTILINE
) 
 200         self
.details
.SetSizerProps(expand
=True, proportion
=1) 
 203         # since we want to use a custom button layout, we won't use the  
 204         # CreateStdDialogBtnSizer here, we'll just create our own panel with 
 205         # a horizontal layout and add the buttons to that. 
 206         btnpane 
= sc
.SizedPanel(pane
, -1) 
 207         btnpane
.SetSizerType("horizontal") 
 208         btnpane
.SetSizerProps(expand
=True) 
 210         self
.saveBtn 
= wx
.Button(btnpane
, wx
.ID_SAVE
) 
 211         spacer 
= sc
.SizedPanel(btnpane
, -1) 
 212         spacer
.SetSizerProps(expand
=True, proportion
=1) 
 214         self
.clearBtn 
= wx
.Button(btnpane
, -1, "Clear") 
 217         self
.SetMinSize(self
.GetSize()) 
 219     def ConfigureListCtrl(self
): 
 220         self
.listCtrl
.InsertColumn(0, "Time") 
 221         self
.listCtrl
.InsertColumn(1, "Error Message") 
 222         self
.listCtrl
.SetColumnWidth(0, 100) 
 223         self
.listCtrl
.SetColumnWidth(1, 280) 
 226 class GridFrame(sc
.SizedFrame
): 
 227     def __init__(self
, parent
, id): 
 228         sc
.SizedFrame
.__init
__(self
, parent
, id, "Grid Layout Demo Frame") 
 230         pane 
= self
.GetContentsPane() 
 231         pane
.SetSizerType("grid", {"cols":3}
) # 3-column grid layout 
 234         wx
.TextCtrl(pane
, -1).SetSizerProps(halign
="left") 
 235         wx
.TextCtrl(pane
, -1).SetSizerProps(halign
="center") 
 236         wx
.TextCtrl(pane
, -1).SetSizerProps(halign
="right") 
 239         wx
.TextCtrl(pane
, -1).SetSizerProps(valign
="center") 
 240         wx
.TextCtrl(pane
, -1).SetSizerProps(expand
=True, proportion
=1) 
 241         wx
.TextCtrl(pane
, -1).SetSizerProps(valign
="center") 
 244         wx
.TextCtrl(pane
, -1).SetSizerProps(halign
="left") 
 245         wx
.TextCtrl(pane
, -1).SetSizerProps(halign
="center") 
 246         wx
.TextCtrl(pane
, -1).SetSizerProps(halign
="right") 
 248         self
.CreateStatusBar() # should always do this when there's a resize border 
 251         self
.SetMinSize(self
.GetSize()) 
 254 #--------------------------------------------------------------------------- 
 256 class TestPanel(wx
.Panel
): 
 257     def __init__(self
, parent
, log
): 
 260         wx
.Panel
.__init
__(self
, parent
, -1) 
 262         b 
= wx
.Button(self
, -1, "Sized Controls Form Dialog", (50,50)) 
 263         self
.Bind(wx
.EVT_BUTTON
, self
.OnFormButton
, b
) 
 265         b2 
= wx
.Button(self
, -1, "Sized Controls Error Dialog", (50,90)) 
 266         self
.Bind(wx
.EVT_BUTTON
, self
.OnErrorButton
, b2
) 
 268         b3 
= wx
.Button(self
, -1, "Sized Controls Grid Layout Demo", (50,130)) 
 269         self
.Bind(wx
.EVT_BUTTON
, self
.OnGridButton
, b3
)     
 272     def OnFormButton(self
, evt
): 
 274         dlg 
= FormDialog(self
, -1) 
 277         # this does not return until the dialog is closed. 
 278         val 
= dlg
.ShowModal() 
 281             self
.log
.WriteText("You pressed OK\n") 
 283             self
.log
.WriteText("You pressed Cancel\n") 
 287     def OnErrorButton(self
, evt
): 
 289         dlg 
= ErrorDialog(self
, -1) 
 292         # this does not return until the dialog is closed. 
 293         val 
= dlg
.ShowModal() 
 296             self
.log
.WriteText("You pressed OK\n") 
 298             self
.log
.WriteText("You pressed Cancel\n") 
 302     def OnGridButton(self
, evt
): 
 304         dlg 
= GridFrame(self
, -1) 
 309 def runTest(frame
, nb
, log
): 
 310     win 
= TestPanel(nb
, log
) 
 314 if __name__ 
== '__main__': 
 317     run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])