]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/MaskedEditControls.py
Aquire the GIL before raising the NotImplementedError exception
[wxWidgets.git] / wxPython / demo / MaskedEditControls.py
1 # 11/23/2003 - Jeff Grimmett (grimmtooth@softhome.net)
2 #
3 # o Updated for wx namespace
4 #
5 # 11/26/2003 - Jeff Grimmett (grimmtooth@softhome.net)
6 #
7 # o the three libraries below all have not been hit by the
8 # wx renamer.
9 #
10 # 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
11 #
12 # o A few changes to correct my own mistakes earlier :-).
13 #
14
15 import string
16 import sys
17 import traceback
18
19 import wx
20 import wx.lib.maskededit as med
21 import wx.lib.maskedctrl as mctl
22 import wx.lib.scrolledpanel as scroll
23
24
25 class demoMixin:
26 """
27 Centralized routines common to demo pages, to remove repetition.
28 """
29 def labelGeneralTable(self, sizer):
30 description = wx.StaticText( self, -1, "Description", )
31 mask = wx.StaticText( self, -1, "Mask Value" )
32 formatcode = wx.StaticText( self, -1, "Format" )
33 regex = wx.StaticText( self, -1, "Regexp Validator(opt.)" )
34 ctrl = wx.StaticText( self, -1, "wxMaskedTextCtrl" )
35
36 description.SetFont( wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD))
37 mask.SetFont( wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD))
38 formatcode.SetFont( wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD) )
39 regex.SetFont( wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD))
40 ctrl.SetFont( wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD))
41
42 sizer.Add(description)
43 sizer.Add(mask)
44 sizer.Add(formatcode)
45 sizer.Add(regex)
46 sizer.Add(ctrl)
47
48
49 def layoutGeneralTable(self, controls, sizer):
50 for control in controls:
51 sizer.Add( wx.StaticText( self, -1, control[0]) )
52 sizer.Add( wx.StaticText( self, -1, control[1]) )
53 sizer.Add( wx.StaticText( self, -1, control[3]) )
54 sizer.Add( wx.StaticText( self, -1, control[4]) )
55
56 if control in controls:
57 newControl = med.wxMaskedTextCtrl( self, -1, "",
58 mask = control[1],
59 excludeChars = control[2],
60 formatcodes = control[3],
61 includeChars = "",
62 validRegex = control[4],
63 validRange = control[5],
64 choices = control[6],
65 choiceRequired = True,
66 defaultValue = control[7],
67 demo = True,
68 name = control[0])
69 self.editList.append(newControl)
70 sizer.Add(newControl)
71
72
73 def changeControlParams(self, event, parameter, checked_value, notchecked_value):
74 if event.IsChecked(): value = checked_value
75 else: value = notchecked_value
76
77 kwargs = {parameter: value}
78
79 for control in self.editList:
80 control.SetCtrlParameters(**kwargs)
81 control.Refresh()
82
83 self.Refresh()
84
85
86
87 #----------------------------------------------------------------------------
88 class demoPage1(scroll.wxScrolledPanel, demoMixin):
89 def __init__(self, parent, log):
90 scroll.wxScrolledPanel.__init__(self, parent, -1)
91 self.sizer = wx.BoxSizer( wx.VERTICAL )
92 self.editList = []
93
94 label = wx.StaticText( self, -1, """\
95 Here are some basic MaskedTextCtrls to give you an idea of what you can do
96 with this control. Note that all controls have been auto-sized by including 'F' in
97 the format codes.
98
99 Try entering nonsensical or partial values in validated fields to see what happens.
100 Note that the State and Last Name fields are list-limited (valid last names are:
101 Smith, Jones, Williams). Signs on numbers can be toggled with the minus key.
102 """)
103 label.SetForegroundColour( "Blue" )
104 header = wx.BoxSizer( wx.HORIZONTAL )
105 header.Add( label, 0, flag=wx.ALIGN_LEFT|wx.ALL, border = 5 )
106
107 highlight = wx.CheckBox( self, -1, "Highlight Empty" )
108 disallow = wx.CheckBox( self, -1, "Disallow Empty" )
109 showFill = wx.CheckBox( self, -1, "change fillChar" )
110
111 vbox = wx.BoxSizer( wx.VERTICAL )
112 vbox.Add( highlight, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
113 vbox.Add( disallow, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
114 vbox.Add( showFill, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
115 header.Add((15, 0))
116 header.Add(vbox, 0, flag=wx.ALIGN_LEFT|wx.ALL, border=5 )
117
118 self.Bind(wx.EVT_CHECKBOX, self.onHighlightEmpty, id=highlight.GetId())
119 self.Bind(wx.EVT_CHECKBOX, self.onDisallowEmpty, id=disallow.GetId())
120 self.Bind(wx.EVT_CHECKBOX, self.onShowFill, id=showFill.GetId())
121
122 grid = wx.FlexGridSizer( 0, 5, vgap=10, hgap=10 )
123 self.labelGeneralTable(grid)
124
125 # The following list is of the controls for the demo. Feel free to play around with
126 # the options!
127 controls = [
128 #description mask excl format regexp range,list,initial
129 ("Phone No", "(###) ###-#### x:###", "", 'F^-', "^\(\d{3}\) \d{3}-\d{4}", '','',''),
130 ("Social Sec#", "###-##-####", "", 'F', "\d{3}-\d{2}-\d{4}", '','',''),
131 ("Full Name", "C{14}", "", 'F_', '^[A-Z][a-zA-Z]+ [A-Z][a-zA-Z]+', '','',''),
132 ("Last Name Only", "C{14}", "", 'F {list}', '^[A-Z][a-zA-Z]+', '',('Smith','Jones','Williams'),''),
133 ("Zip plus 4", "#{5}-#{4}", "", 'F', "\d{5}-(\s{4}|\d{4})", '','',''),
134 ("Customer No", "\CAA-###", "", 'F!', "C[A-Z]{2}-\d{3}", '','',''),
135 ("Invoice Total", "#{9}.##", "", 'F-_,', "", '','',''),
136 ("Integer", "#{9}", "", 'F-_', "", '','',''),
137 ]
138
139 self.layoutGeneralTable(controls, grid)
140 self.sizer.Add( header, 0, flag=wx.ALIGN_LEFT|wx.ALL, border=5 )
141 self.sizer.Add( grid, 0, flag= wx.ALIGN_LEFT|wx.LEFT, border=5 )
142 self.SetSizer(self.sizer)
143 self.SetupScrolling()
144 self.SetAutoLayout(1)
145
146
147 def onDisallowEmpty( self, event ):
148 """ Set emptyInvalid parameter on/off """
149 self.changeControlParams( event, "emptyInvalid", True, False )
150
151 def onHighlightEmpty( self, event ):
152 """ Highlight empty values"""
153 self.changeControlParams( event, "emptyBackgroundColour", "Blue", "White" )
154
155 def onShowFill( self, event ):
156 """ Set fillChar parameter to '?' or ' ' """
157 self.changeControlParams( event, "fillChar", '?', ' ' )
158
159
160 class demoPage2(scroll.wxScrolledPanel, demoMixin):
161 def __init__( self, parent, log ):
162 self.log = log
163 scroll.wxScrolledPanel.__init__( self, parent, -1 )
164 self.sizer = wx.BoxSizer( wx.VERTICAL )
165
166 label = wx.StaticText( self, -1, """\
167 All these controls have been created by passing a single parameter, the autoformat code,
168 and use the factory class wxMaskedCtrl with its default controlType.
169 The maskededit module contains an internal dictionary of types and formats (autoformats).
170 Many of these already do complicated validation; To see some examples, try
171 29 Feb 2002 vs. 2004 for the date formats, or email address validation.
172 """)
173
174 label.SetForegroundColour( "Blue" )
175 self.sizer.Add( label, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
176
177 description = wx.StaticText( self, -1, "Description")
178 autofmt = wx.StaticText( self, -1, "AutoFormat Code")
179 ctrl = wx.StaticText( self, -1, "MaskedCtrl")
180
181 description.SetFont( wx.Font( 9, wx.SWISS, wx.NORMAL, wx.BOLD ) )
182 autofmt.SetFont( wx.Font( 9, wx.SWISS, wx.NORMAL, wx.BOLD ) )
183 ctrl.SetFont( wx.Font( 9, wx.SWISS, wx.NORMAL, wx.BOLD ) )
184
185 grid = wx.FlexGridSizer( 0, 3, vgap=10, hgap=5 )
186 grid.Add( description, 0, wx.ALIGN_LEFT )
187 grid.Add( autofmt, 0, wx.ALIGN_LEFT )
188 grid.Add( ctrl, 0, wx.ALIGN_LEFT )
189
190 for autoformat, desc in med.autoformats:
191 grid.Add( wx.StaticText( self, -1, desc), 0, wx.ALIGN_LEFT )
192 grid.Add( wx.StaticText( self, -1, autoformat), 0, wx.ALIGN_LEFT )
193 grid.Add( mctl.wxMaskedCtrl( self, -1, "",
194 autoformat = autoformat,
195 demo = True,
196 name = autoformat),
197 0, wx.ALIGN_LEFT )
198
199 self.sizer.Add( grid, 0, wx.ALIGN_LEFT|wx.ALL, border=5 )
200 self.SetSizer( self.sizer )
201 self.SetAutoLayout( 1 )
202 self.SetupScrolling()
203
204
205 class demoPage3(scroll.wxScrolledPanel, demoMixin):
206 def __init__(self, parent, log):
207 self.log = log
208 scroll.wxScrolledPanel.__init__(self, parent, -1)
209 self.sizer = wx.BoxSizer( wx.VERTICAL )
210 self.editList = []
211
212 label = wx.StaticText( self, -1, """\
213 Here wxMaskedTextCtrls that have default values. The states
214 control has a list of valid values, and the unsigned integer
215 has a legal range specified.
216 """)
217 label.SetForegroundColour( "Blue" )
218 requireValid = wx.CheckBox( self, -1, "Require Valid Value" )
219 self.Bind(wx.EVT_CHECKBOX, self.onRequireValid, id=requireValid.GetId())
220
221 header = wx.BoxSizer( wx.HORIZONTAL )
222 header.Add( label, 0, flag=wx.ALIGN_LEFT|wx.ALL, border = 5)
223 header.Add((75, 0))
224 header.Add( requireValid, 0, flag=wx.ALIGN_LEFT|wx.ALL, border=10 )
225
226 grid = wx.FlexGridSizer( 0, 5, vgap=10, hgap=10 )
227 self.labelGeneralTable( grid )
228
229 controls = [
230 #description mask excl format regexp range,list,initial
231 ("U.S. State (2 char)", "AA", "", 'F!_', "[A-Z]{2}", '',med.states, med.states[0]),
232 ("Integer (signed)", "#{6}", "", 'F-_', "", '','', ' 0 '),
233 ("Integer (unsigned)\n(1-399)","######", "", 'F_', "", (1,399),'', '1 '),
234 ("Float (signed)", "#{6}.#{9}", "", 'F-_R', "", '','', '000000.000000000'),
235 ("Date (MDY) + Time", "##/##/#### ##:##:## AM", 'BCDEFGHIJKLMNOQRSTUVWXYZ','DF!',"", '','', wx.DateTime_Now().Format("%m/%d/%Y %I:%M:%S %p")),
236 ]
237 self.layoutGeneralTable( controls, grid )
238
239 self.sizer.Add( header, 0, flag=wx.ALIGN_LEFT|wx.ALL, border=5 )
240 self.sizer.Add( grid, 0, flag=wx.ALIGN_LEFT|wx.ALL, border=5 )
241
242 self.SetSizer( self.sizer )
243 self.SetAutoLayout( 1 )
244 self.SetupScrolling()
245
246 def onRequireValid( self, event ):
247 """ Set validRequired parameter on/off """
248 self.changeControlParams( event, "validRequired", True, False )
249
250
251 class demoPage4(scroll.wxScrolledPanel, demoMixin):
252 def __init__( self, parent, log ):
253 self.log = log
254 scroll.wxScrolledPanel.__init__( self, parent, -1 )
255 self.sizer = wx.BoxSizer( wx.VERTICAL )
256
257 label = wx.StaticText( self, -1, """\
258 These controls have field-specific choice lists and allow autocompletion.
259
260 Down arrow or Page Down in an uncompleted field with an auto-completable field will attempt
261 to auto-complete a field if it has a choice list.
262 Page Down and Shift-Down arrow will also auto-complete, or cycle through the complete list.
263 Page Up and Shift-Up arrow will similarly cycle backwards through the list.
264 """)
265
266 label.SetForegroundColour( "Blue" )
267 self.sizer.Add( label, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
268
269 description = wx.StaticText( self, -1, "Description" )
270 autofmt = wx.StaticText( self, -1, "AutoFormat Code" )
271 fields = wx.StaticText( self, -1, "Field Objects" )
272 ctrl = wx.StaticText( self, -1, "wxMaskedTextCtrl" )
273
274 description.SetFont( wx.Font( 9, wx.SWISS, wx.NORMAL, wx.BOLD ) )
275 autofmt.SetFont( wx.Font( 9, wx.SWISS, wx.NORMAL, wx.BOLD ) )
276 fields.SetFont( wx.Font( 9, wx.SWISS, wx.NORMAL, wx.BOLD ) )
277 ctrl.SetFont( wx.Font( 9, wx.SWISS, wx.NORMAL, wx.BOLD ) )
278
279 grid = wx.FlexGridSizer( 0, 4, vgap=10, hgap=10 )
280 grid.Add( description, 0, wx.ALIGN_LEFT )
281 grid.Add( autofmt, 0, wx.ALIGN_LEFT )
282 grid.Add( fields, 0, wx.ALIGN_LEFT )
283 grid.Add( ctrl, 0, wx.ALIGN_LEFT )
284
285 autoformat = "USPHONEFULLEXT"
286 fieldsDict = {0: med.Field(choices=["617","781","508","978","413"], choiceRequired=True)}
287 fieldsLabel = """\
288 {0: Field(choices=[
289 "617","781",
290 "508","978","413"],
291 choiceRequired=True)}"""
292 grid.Add( wx.StaticText( self, -1, "Restricted Area Code"), 0, wx.ALIGN_LEFT )
293 grid.Add( wx.StaticText( self, -1, autoformat), 0, wx.ALIGN_LEFT )
294 grid.Add( wx.StaticText( self, -1, fieldsLabel), 0, wx.ALIGN_LEFT )
295 grid.Add( med.wxMaskedTextCtrl( self, -1, "",
296 autoformat = autoformat,
297 fields = fieldsDict,
298 demo = True,
299 name = autoformat),
300 0, wx.ALIGN_LEFT )
301
302 autoformat = "EXPDATEMMYY"
303 fieldsDict = {1: med.Field(choices=["03", "04", "05"], choiceRequired=True)}
304 fieldsLabel = """\
305 {1: Field(choices=[
306 "03", "04", "05"],
307 choiceRequired=True)}"""
308 exp = med.wxMaskedTextCtrl( self, -1, "",
309 autoformat = autoformat,
310 fields = fieldsDict,
311 demo = True,
312 name = autoformat)
313
314 grid.Add( wx.StaticText( self, -1, "Restricted Expiration"), 0, wx.ALIGN_LEFT )
315 grid.Add( wx.StaticText( self, -1, autoformat), 0, wx.ALIGN_LEFT )
316 grid.Add( wx.StaticText( self, -1, fieldsLabel), 0, wx.ALIGN_LEFT )
317 grid.Add( exp, 0, wx.ALIGN_LEFT )
318
319 fieldsDict = {0: med.Field(choices=["02134","02155"], choiceRequired=True),
320 1: med.Field(choices=["1234", "5678"], choiceRequired=False)}
321 fieldsLabel = """\
322 {0: Field(choices=["02134","02155"],
323 choiceRequired=True),
324 1: Field(choices=["1234", "5678"],
325 choiceRequired=False)}"""
326 autoformat = "USZIPPLUS4"
327 zip = med.wxMaskedTextCtrl( self, -1, "",
328 autoformat = autoformat,
329 fields = fieldsDict,
330 demo = True,
331 name = autoformat)
332
333 grid.Add( wx.StaticText( self, -1, "Restricted Zip + 4"), 0, wx.ALIGN_LEFT )
334 grid.Add( wx.StaticText( self, -1, autoformat), 0, wx.ALIGN_LEFT )
335 grid.Add( wx.StaticText( self, -1, fieldsLabel), 0, wx.ALIGN_LEFT )
336 grid.Add( zip, 0, wx.ALIGN_LEFT )
337
338 self.sizer.Add( grid, 0, wx.ALIGN_LEFT|wx.ALL, border=5 )
339 self.SetSizer( self.sizer )
340 self.SetAutoLayout(1)
341 self.SetupScrolling()
342
343
344 class demoPage5(scroll.wxScrolledPanel, demoMixin):
345 def __init__( self, parent, log ):
346 self.log = log
347 scroll.wxScrolledPanel.__init__( self, parent, -1 )
348 self.sizer = wx.BoxSizer( wx.VERTICAL )
349
350
351 labelMaskedCombos = wx.StaticText( self, -1, """\
352 These are some examples of wxMaskedComboBox:""")
353 labelMaskedCombos.SetForegroundColour( "Blue" )
354
355
356 label_statecode = wx.StaticText( self, -1, """\
357 A state selector; only
358 "legal" values can be
359 entered:""")
360 statecode = med.wxMaskedComboBox( self, -1, med.states[0],
361 choices = med.states,
362 autoformat="USSTATE")
363
364 label_statename = wx.StaticText( self, -1, """\
365 A state name selector,
366 with auto-select:""")
367
368 # Create this one using factory function:
369 statename = mctl.wxMaskedCtrl( self, -1, med.state_names[0],
370 controlType = mctl.controlTypes.MASKEDCOMBO,
371 choices = med.state_names,
372 autoformat="USSTATENAME",
373 autoSelect=True)
374 statename.SetCtrlParameters(formatcodes = 'F!V_')
375
376
377 numerators = [ str(i) for i in range(1, 4) ]
378 denominators = [ string.ljust(str(i), 2) for i in [2,3,4,5,8,16,32,64] ]
379 fieldsDict = {0: med.Field(choices=numerators, choiceRequired=False),
380 1: med.Field(choices=denominators, choiceRequired=True)}
381 choices = []
382 for n in numerators:
383 for d in denominators:
384 if n != d:
385 choices.append( '%s/%s' % (n,d) )
386
387
388 label_fraction = wx.StaticText( self, -1, """\
389 A masked ComboBox for fraction selection.
390 Choices for each side of the fraction can
391 be selected with PageUp/Down:""")
392
393 fraction = mctl.wxMaskedCtrl( self, -1, "",
394 controlType = mctl.MASKEDCOMBO,
395 choices = choices,
396 choiceRequired = True,
397 mask = "#/##",
398 formatcodes = "F_",
399 validRegex = "^\d\/\d\d?",
400 fields = fieldsDict )
401
402
403 label_code = wx.StaticText( self, -1, """\
404 A masked ComboBox to validate
405 text from a list of numeric codes:""")
406
407 choices = ["91", "136", "305", "4579"]
408 code = med.wxMaskedComboBox( self, -1, choices[0],
409 choices = choices,
410 choiceRequired = True,
411 formatcodes = "F_r",
412 mask = "####")
413
414 label_selector = wx.StaticText( self, -1, """\
415 Programmatically set
416 choice sets:""")
417 self.list_selector = wx.ComboBox(self, -1, '', choices = ['list1', 'list2', 'list3'])
418 self.dynamicbox = mctl.wxMaskedCtrl( self, -1, ' ',
419 controlType = mctl.controlTypes.MASKEDCOMBO,
420 mask = 'XXXX',
421 formatcodes = 'F_',
422 # these are to give dropdown some initial height,
423 # as base control apparently only sets that size
424 # during initial construction <sigh>:
425 choices = ['', '1', '2', '3', '4', '5'] )
426
427 self.dynamicbox.Clear() # get rid of initial choices used to size the dropdown
428
429
430 labelIpAddrs = wx.StaticText( self, -1, """\
431 Here are some examples of wxIpAddrCtrl, a control derived from wxMaskedTextCtrl:""")
432 labelIpAddrs.SetForegroundColour( "Blue" )
433
434
435 label_ipaddr1 = wx.StaticText( self, -1, "An empty control:")
436 ipaddr1 = med.wxIpAddrCtrl( self, -1, style = wx.TE_PROCESS_TAB )
437
438
439 label_ipaddr2 = wx.StaticText( self, -1, "A restricted mask:")
440 ipaddr2 = med.wxIpAddrCtrl( self, -1, mask=" 10. 1.109.###" )
441
442
443 label_ipaddr3 = wx.StaticText( self, -1, """\
444 A control with restricted legal values:
445 10. (1|2) . (129..255) . (0..255)""")
446 ipaddr3 = mctl.wxMaskedCtrl( self, -1,
447 controlType = mctl.controlTypes.IPADDR,
448 mask=" 10. #.###.###")
449 ipaddr3.SetFieldParameters(0, validRegex="1|2",validRequired=False ) # requires entry to match or not allowed
450
451 # This allows any value in penultimate field, but colors anything outside of the range invalid:
452 ipaddr3.SetFieldParameters(1, validRange=(129,255), validRequired=False )
453
454
455
456 labelNumerics = wx.StaticText( self, -1, """\
457 Here are some useful configurations of a wxMaskedTextCtrl for integer and floating point input that still treat
458 the control as a text control. (For a true numeric control, check out the wxMaskedNumCtrl class!)""")
459 labelNumerics.SetForegroundColour( "Blue" )
460
461 label_intctrl1 = wx.StaticText( self, -1, """\
462 An integer entry control with
463 shifting insert enabled:""")
464 self.intctrl1 = med.wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-,F>')
465 label_intctrl2 = wx.StaticText( self, -1, """\
466 Right-insert integer entry:""")
467 self.intctrl2 = med.wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-,Fr')
468
469 label_floatctrl = wx.StaticText( self, -1, """\
470 A floating point entry control
471 with right-insert for ordinal:""")
472 self.floatctrl = med.wxMaskedTextCtrl(self, -1, name='floatctrl', mask="#{9}.#{2}", formatcodes="F,_-R", useParensForNegatives=False)
473 self.floatctrl.SetFieldParameters(0, formatcodes='r<', validRequired=True) # right-insert, require explicit cursor movement to change fields
474 self.floatctrl.SetFieldParameters(1, defaultValue='00') # don't allow blank fraction
475
476 label_numselect = wx.StaticText( self, -1, """\
477 <= Programmatically set the value
478 of the float entry ctrl:""")
479 numselect = wx.ComboBox(self, -1, choices = [ '', '111', '222.22', '-3', '54321.666666666', '-1353.978',
480 '1234567', '-1234567', '123456789', '-123456789.1',
481 '1234567890.', '-1234567890.1' ])
482
483 parens_check = wx.CheckBox(self, -1, "Use () to indicate negatives in above controls")
484
485
486
487 gridCombos = wx.FlexGridSizer( 0, 4, vgap=10, hgap = 10 )
488 gridCombos.Add( label_statecode, 0, wx.ALIGN_LEFT )
489 gridCombos.Add( statecode, 0, wx.ALIGN_LEFT )
490 gridCombos.Add( label_fraction, 0, wx.ALIGN_LEFT )
491 gridCombos.Add( fraction, 0, wx.ALIGN_LEFT )
492 gridCombos.Add( label_statename, 0, wx.ALIGN_LEFT )
493 gridCombos.Add( statename, 0, wx.ALIGN_LEFT )
494 gridCombos.Add( label_code, 0, wx.ALIGN_LEFT )
495 gridCombos.Add( code, 0, wx.ALIGN_LEFT )
496 gridCombos.Add( label_selector, 0, wx.ALIGN_LEFT)
497 hbox = wx.BoxSizer( wx.HORIZONTAL )
498 hbox.Add( self.list_selector, 0, wx.ALIGN_LEFT )
499 hbox.Add(wx.StaticText(self, -1, ' => '), 0, wx.ALIGN_LEFT)
500 hbox.Add( self.dynamicbox, 0, wx.ALIGN_LEFT )
501 gridCombos.Add( hbox, 0, wx.ALIGN_LEFT )
502
503 gridIpAddrs = wx.FlexGridSizer( 0, 4, vgap=10, hgap = 15 )
504 gridIpAddrs.Add( label_ipaddr1, 0, wx.ALIGN_LEFT )
505 gridIpAddrs.Add( ipaddr1, 0, wx.ALIGN_LEFT )
506 gridIpAddrs.Add( label_ipaddr2, 0, wx.ALIGN_LEFT )
507 gridIpAddrs.Add( ipaddr2, 0, wx.ALIGN_LEFT )
508 gridIpAddrs.Add( label_ipaddr3, 0, wx.ALIGN_LEFT )
509 gridIpAddrs.Add( ipaddr3, 0, wx.ALIGN_LEFT )
510
511 gridNumerics = wx.FlexGridSizer( 0, 4, vgap=10, hgap = 10 )
512 gridNumerics.Add( label_intctrl1, 0, wx.ALIGN_LEFT )
513 gridNumerics.Add( self.intctrl1, 0, wx.ALIGN_LEFT )
514 gridNumerics.Add( label_intctrl2, 0, wx.ALIGN_RIGHT )
515 gridNumerics.Add( self.intctrl2, 0, wx.ALIGN_LEFT )
516 gridNumerics.Add( label_floatctrl, 0, wx.ALIGN_LEFT )
517 gridNumerics.Add( self.floatctrl, 0, wx.ALIGN_LEFT )
518 gridNumerics.Add( label_numselect, 0, wx.ALIGN_RIGHT )
519 gridNumerics.Add( numselect, 0, wx.ALIGN_LEFT )
520
521 self.sizer.Add( labelMaskedCombos, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
522 self.sizer.Add( gridCombos, 0, wx.ALIGN_LEFT|wx.ALL, border=5 )
523 self.sizer.Add( wx.StaticLine(self, -1), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, border=8 )
524 self.sizer.Add( labelIpAddrs, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
525 self.sizer.Add( gridIpAddrs, 0, wx.ALIGN_LEFT|wx.ALL, border=5 )
526 self.sizer.Add( wx.StaticLine(self, -1), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, border=8 )
527 self.sizer.Add( labelNumerics, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
528 self.sizer.Add( gridNumerics, 0, wx.ALIGN_LEFT|wx.ALL, border=5 )
529 self.sizer.Add( parens_check, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
530
531 self.SetSizer( self.sizer )
532 self.SetAutoLayout(1)
533 self.SetupScrolling()
534
535 self.Bind(wx.EVT_COMBOBOX, self.OnComboSelection, id=fraction.GetId())
536 self.Bind(wx.EVT_COMBOBOX, self.OnComboSelection, id=code.GetId())
537 self.Bind(wx.EVT_COMBOBOX, self.OnComboSelection, id=statecode.GetId())
538 self.Bind(wx.EVT_COMBOBOX, self.OnComboSelection, id=statename.GetId())
539 self.Bind(wx.EVT_TEXT, self.OnTextChange, id=code.GetId())
540 self.Bind(wx.EVT_TEXT, self.OnTextChange, id=statecode.GetId())
541 self.Bind(wx.EVT_TEXT, self.OnTextChange, id=statename.GetId())
542 self.Bind(wx.EVT_COMBOBOX, self.OnListSelection, id=self.list_selector.GetId())
543
544 self.Bind(wx.EVT_TEXT, self.OnTextChange, id=self.intctrl1.GetId())
545 self.Bind(wx.EVT_TEXT, self.OnTextChange, id=self.intctrl2.GetId())
546 self.Bind(wx.EVT_TEXT, self.OnTextChange, id=self.floatctrl.GetId())
547 self.Bind(wx.EVT_COMBOBOX, self.OnNumberSelect, id=numselect.GetId())
548 self.Bind(wx.EVT_CHECKBOX, self.OnParensCheck, id=parens_check.GetId())
549
550 self.Bind(wx.EVT_TEXT, self.OnIpAddrChange, id=ipaddr1.GetId())
551 self.Bind(wx.EVT_TEXT, self.OnIpAddrChange, id=ipaddr2.GetId())
552 self.Bind(wx.EVT_TEXT, self.OnIpAddrChange, id=ipaddr3.GetId())
553
554
555
556
557 def OnComboSelection( self, event ):
558 ctl = self.FindWindowById( event.GetId() )
559 if not ctl.IsValid():
560 self.log.write('current value not a valid choice')
561 self.log.write('new value = %s' % ctl.GetValue())
562
563 def OnTextChange( self, event ):
564 ctl = self.FindWindowById( event.GetId() )
565 if ctl.IsValid():
566 self.log.write('new value = %s\n' % ctl.GetValue() )
567
568 def OnNumberSelect( self, event ):
569 value = event.GetString()
570 # Format choice to fit into format for #{9}.#{2}, with sign position reserved:
571 # (ordinal + fraction == 11 + decimal point + sign == 13)
572 if value:
573 floattext = "%13.2f" % float(value)
574 else:
575 floattext = value # clear the value again
576 try:
577 self.floatctrl.SetValue(floattext)
578 except:
579 type, value, tb = sys.exc_info()
580 for line in traceback.format_exception_only(type, value):
581 self.log.write(line)
582
583 def OnParensCheck( self, event ):
584 self.intctrl1.SetCtrlParameters(useParensForNegatives=event.IsChecked())
585 self.intctrl2.SetCtrlParameters(useParensForNegatives=event.IsChecked())
586 self.floatctrl.SetCtrlParameters(useParensForNegatives=event.IsChecked())
587
588 def OnIpAddrChange( self, event ):
589 ipaddr = self.FindWindowById( event.GetId() )
590 if ipaddr.IsValid():
591 self.log.write('new addr = %s\n' % ipaddr.GetAddress() )
592
593 def OnListSelection( self, event ):
594 list = self.list_selector.GetStringSelection()
595 formatcodes = 'F_'
596 if list == 'list1':
597 choices = ['abc', 'defg', 'hi']
598 mask = 'aaaa'
599 elif list == 'list2':
600 choices = ['1', '2', '34', '567']
601 formatcodes += 'r'
602 mask = '###'
603 else:
604 choices = med.states
605 mask = 'AA'
606 formatcodes += '!'
607 self.dynamicbox.SetCtrlParameters( mask = mask,
608 choices = choices,
609 choiceRequired=True,
610 autoSelect=True,
611 formatcodes=formatcodes)
612 self.dynamicbox.SetValue(choices[0])
613
614 # ---------------------------------------------------------------------
615 class TestMaskedTextCtrls(wx.Notebook):
616 def __init__(self, parent, id, log):
617 wx.Notebook.__init__(self, parent, id)
618 self.log = log
619
620 win = demoPage1(self, log)
621 self.AddPage(win, "General examples")
622
623 win = demoPage2(self, log)
624 self.AddPage(win, 'Auto-formatted controls')
625
626 win = demoPage3(self, log)
627 self.AddPage(win, "Using default values")
628
629 win = demoPage4(self, log)
630 self.AddPage(win, 'Using auto-complete fields')
631
632 win = demoPage5(self, log)
633 self.AddPage(win, 'Other masked controls')
634
635
636 #----------------------------------------------------------------------------
637
638 def runTest(frame, nb, log):
639 testWin = TestMaskedTextCtrls(nb, -1, log)
640 return testWin
641
642 def RunStandalone():
643 app = wx.PySimpleApp()
644 frame = wx.Frame(None, -1, "Test MaskedTextCtrl", size=(640, 480))
645 win = TestMaskedTextCtrls(frame, -1, sys.stdout)
646 frame.Show(True)
647 app.MainLoop()
648 #----------------------------------------------------------------------------
649
650 overview = """<html>
651 <PRE><FONT SIZE=-1>
652 """ + med.__doc__ + """
653 </FONT></PRE>
654 """
655
656 if __name__ == "__main__":
657 import sys,os
658 import run
659 run.main(['', os.path.basename(sys.argv[0])])