]>
Commit | Line | Data |
---|---|---|
5448935a KO |
1 | import wx |
2 | import wxaddons.sized_controls as sc | |
3 | ||
3bdec81e | 4 | overview = """\ |
eee9bf2e RD |
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: | |
8 | ||
9 | <h3>SizedPanel</h3> | |
10 | ||
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 | |
19 | Mac. | |
20 | ||
21 | <h3>SizedFrame and SizedDialog</h3> | |
22 | ||
23 | These classes automatically setup a SizedPanel which is appropriately | |
24 | positioned and given appropriate borders in accordance with the | |
3bdec81e KO |
25 | platform's HIGs. |
26 | ||
eee9bf2e RD |
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: | |
3bdec81e | 32 | |
eee9bf2e | 33 | <table bgcolor=\"#EFEFEF\"><tr><td><pre> |
3bdec81e KO |
34 | ... wx.Dialog init code... |
35 | ||
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) | |
41 | ||
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) | |
47 | panel.SetSizer(sizer) | |
48 | ||
49 | dlgSizer = wx.BoxSizer() | |
50 | dlgSizer.Add(panel, 1, wx.EXPAND) | |
51 | self.SetSizer(dlgSizer) | |
52 | self.SetAutoLayout(True) | |
53 | ||
eee9bf2e | 54 | ... rest of dialog ...</pre> |
3bdec81e KO |
55 | </td></tr></table> |
56 | ||
57 | would now look like this: | |
58 | ||
eee9bf2e | 59 | <table bgcolor=\"#EFEFEF\"><tr><td><pre> |
3bdec81e KO |
60 | ... wx.Dialog init code... |
61 | ||
62 | panel = self.GetContentsPane() | |
eee9bf2e | 63 | panel.SetSizerType(\"horizontal\") |
3bdec81e KO |
64 | |
65 | b1 = wx.Button(panel, -1) | |
66 | b2 = wx.Button(panel, -1) | |
67 | ||
68 | t1 = wx.TextCtrl(panel, -1) | |
69 | t1.SetSizerProps(expand=True) | |
70 | ||
71 | b3 = wx.Button(panel, -1) | |
72 | ||
eee9bf2e | 73 | ... rest of dialog ...</pre> |
3bdec81e | 74 | </td></tr></table> |
eee9bf2e | 75 | |
3bdec81e | 76 | and the latter example will adhere to HIG spacing guidelines on all platforms, |
b64274c7 | 77 | unlike the former example. Please check the demos for more complete and sophisticated examples of SizedControls |
3bdec81e | 78 | in action. |
b64274c7 KO |
79 | |
80 | <h3>wx.Window.SetSizerProps Quick Reference</h3> | |
81 | ||
82 | <p><pre>wx.Window.SetSizerProps(<props>)</pre> | |
83 | ||
84 | <p> | |
85 | <table bgcolor=\"#EFEFEF\"> | |
86 | <tr> | |
87 | <td valign="middle" width="90"><b>Parameter</b></td> <td valign="middle"><b>Values</b></td> <td valign="middle"><b>Summary</b></td> | |
88 | </tr> | |
89 | ||
90 | <tr> | |
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> | |
94 | </tr> | |
95 | ||
96 | <tr> | |
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> | |
101 | </tr> | |
102 | ||
103 | <tr> | |
104 | <td><i>halign</i> <td>"left", "center", "centre", "right"</td> | |
105 | <td>Determines horizontal alignment of control.</td> | |
106 | </tr> | |
107 | ||
108 | <tr> | |
109 | <td><i>valign</i> <td>"top", "center", "centre", "bottom"</td> | |
110 | <td>Determines vertical alignment of control.</td> | |
111 | </tr> | |
112 | ||
113 | <tr> | |
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> | |
119 | </tr> | |
120 | ||
121 | <tr> | |
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> | |
124 | </tr> | |
125 | ||
126 | </table> | |
3bdec81e KO |
127 | """ |
128 | ||
5448935a KO |
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) | |
133 | ||
134 | pane = self.GetContentsPane() | |
135 | pane.SetSizerType("form") | |
136 | ||
137 | # row 1 | |
138 | wx.StaticText(pane, -1, "Name") | |
139 | textCtrl = wx.TextCtrl(pane, -1, "Your name here") | |
140 | textCtrl.SetSizerProps(expand=True) | |
141 | ||
142 | # row 2 | |
143 | wx.StaticText(pane, -1, "Email") | |
144 | emailCtrl = wx.TextCtrl(pane, -1, "") | |
145 | emailCtrl.SetSizerProps(expand=True) | |
146 | ||
147 | # row 3 | |
148 | wx.StaticText(pane, -1, "Gender") | |
149 | wx.Choice(pane, -1, choices=["male", "female"]) | |
150 | ||
151 | # row 4 | |
152 | wx.StaticText(pane, -1, "State") | |
153 | wx.TextCtrl(pane, -1, size=(60, -1)) # two chars for state | |
154 | ||
155 | # row 5 | |
156 | wx.StaticText(pane, -1, "Title") | |
157 | ||
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) | |
162 | ||
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.") | |
168 | # end row 5 | |
169 | ||
170 | # add dialog buttons | |
171 | self.SetButtonSizer(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL)) | |
172 | ||
173 | # a little trick to make sure that you can't resize the dialog to | |
174 | # less screen space than the controls need | |
175 | self.Fit() | |
176 | self.SetMinSize(self.GetSize()) | |
177 | ||
178 | ||
179 | class ErrorDialog(sc.SizedDialog): | |
180 | def __init__(self, parent, id): | |
181 | sc.SizedDialog.__init__(self, parent, id, "Error log viewer", | |
5448935a KO |
182 | style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) |
183 | ||
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() | |
189 | ||
190 | # first row | |
3bdec81e | 191 | self.listCtrl = wx.ListCtrl(pane, -1, size=(300, -1), style=wx.LC_REPORT) |
5448935a KO |
192 | self.listCtrl.SetSizerProps(expand=True, proportion=1) |
193 | self.ConfigureListCtrl() | |
194 | ||
195 | # second row | |
196 | self.lblDetails = wx.StaticText(pane, -1, "Error Details") | |
197 | ||
198 | # third row | |
199 | self.details = wx.TextCtrl(pane, -1, style=wx.TE_MULTILINE) | |
200 | self.details.SetSizerProps(expand=True, proportion=1) | |
201 | ||
202 | # final row | |
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) | |
209 | ||
210 | self.saveBtn = wx.Button(btnpane, wx.ID_SAVE) | |
211 | spacer = sc.SizedPanel(btnpane, -1) | |
212 | spacer.SetSizerProps(expand=True, proportion=1) | |
213 | ||
214 | self.clearBtn = wx.Button(btnpane, -1, "Clear") | |
215 | ||
216 | self.Fit() | |
217 | self.SetMinSize(self.GetSize()) | |
218 | ||
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) | |
224 | ||
b64274c7 KO |
225 | |
226 | class GridFrame(sc.SizedFrame): | |
227 | def __init__(self, parent, id): | |
228 | sc.SizedFrame.__init__(self, parent, id, "Grid Layout Demo Frame") | |
229 | ||
230 | pane = self.GetContentsPane() | |
231 | pane.SetSizerType("grid", {"cols":3}) # 3-column grid layout | |
232 | ||
233 | # row 1 | |
234 | wx.TextCtrl(pane, -1).SetSizerProps(halign="left") | |
235 | wx.TextCtrl(pane, -1).SetSizerProps(halign="center") | |
236 | wx.TextCtrl(pane, -1).SetSizerProps(halign="right") | |
237 | ||
238 | # row 2 | |
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") | |
242 | ||
243 | # row 3 | |
244 | wx.TextCtrl(pane, -1).SetSizerProps(halign="left") | |
245 | wx.TextCtrl(pane, -1).SetSizerProps(halign="center") | |
246 | wx.TextCtrl(pane, -1).SetSizerProps(halign="right") | |
247 | ||
248 | self.CreateStatusBar() # should always do this when there's a resize border | |
249 | ||
250 | self.Fit() | |
251 | self.SetMinSize(self.GetSize()) | |
252 | ||
253 | ||
5448935a KO |
254 | #--------------------------------------------------------------------------- |
255 | ||
256 | class TestPanel(wx.Panel): | |
257 | def __init__(self, parent, log): | |
258 | self.log = log | |
259 | self.parent = parent | |
260 | wx.Panel.__init__(self, parent, -1) | |
261 | ||
262 | b = wx.Button(self, -1, "Sized Controls Form Dialog", (50,50)) | |
263 | self.Bind(wx.EVT_BUTTON, self.OnFormButton, b) | |
264 | ||
265 | b2 = wx.Button(self, -1, "Sized Controls Error Dialog", (50,90)) | |
b64274c7 KO |
266 | self.Bind(wx.EVT_BUTTON, self.OnErrorButton, b2) |
267 | ||
268 | b3 = wx.Button(self, -1, "Sized Controls Grid Layout Demo", (50,130)) | |
269 | self.Bind(wx.EVT_BUTTON, self.OnGridButton, b3) | |
5448935a KO |
270 | |
271 | ||
272 | def OnFormButton(self, evt): | |
273 | ||
274 | dlg = FormDialog(self, -1) | |
275 | dlg.CenterOnScreen() | |
276 | ||
277 | # this does not return until the dialog is closed. | |
278 | val = dlg.ShowModal() | |
279 | ||
280 | if val == wx.ID_OK: | |
281 | self.log.WriteText("You pressed OK\n") | |
282 | else: | |
283 | self.log.WriteText("You pressed Cancel\n") | |
284 | ||
285 | dlg.Destroy() | |
286 | ||
287 | def OnErrorButton(self, evt): | |
288 | ||
289 | dlg = ErrorDialog(self, -1) | |
290 | dlg.CenterOnScreen() | |
291 | ||
292 | # this does not return until the dialog is closed. | |
293 | val = dlg.ShowModal() | |
294 | ||
295 | if val == wx.ID_OK: | |
296 | self.log.WriteText("You pressed OK\n") | |
297 | else: | |
298 | self.log.WriteText("You pressed Cancel\n") | |
299 | ||
300 | dlg.Destroy() | |
301 | ||
b64274c7 KO |
302 | def OnGridButton(self, evt): |
303 | ||
304 | dlg = GridFrame(self, -1) | |
305 | dlg.CenterOnScreen() | |
306 | ||
307 | dlg.Show() | |
308 | ||
5448935a KO |
309 | def runTest(frame, nb, log): |
310 | win = TestPanel(nb, log) | |
311 | return win | |
5448935a KO |
312 | |
313 | if __name__ == "__main__": | |
314 | app = wx.PySimpleApp() | |
315 | dlg = FormDialog() | |
eee9bf2e | 316 | dlg.ShowModal() |