]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/MaskedEditControls.py
reSWIGged
[wxWidgets.git] / wxPython / demo / MaskedEditControls.py
CommitLineData
8fa876ca
RD
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#
b881fc78
RD
10# 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
11#
12# o A few changes to correct my own mistakes earlier :-).
13#
8fa876ca
RD
14
15import string
16import sys
17import traceback
18
19import wx
20import wx.lib.maskededit as med
21import wx.lib.maskedctrl as mctl
22import wx.lib.scrolledpanel as scroll
1fded56b 23
8b9a4190 24
1fded56b
RD
25class demoMixin:
26 """
27 Centralized routines common to demo pages, to remove repetition.
28 """
29 def labelGeneralTable(self, sizer):
8fa876ca
RD
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))
1fded56b
RD
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:
8fa876ca
RD
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]) )
1fded56b
RD
55
56 if control in controls:
8fa876ca 57 newControl = med.wxMaskedTextCtrl( self, -1, "",
1fded56b
RD
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):
8fa876ca 74 if event.IsChecked(): value = checked_value
1fded56b 75 else: value = notchecked_value
8fa876ca 76
1fded56b 77 kwargs = {parameter: value}
8fa876ca 78
1fded56b
RD
79 for control in self.editList:
80 control.SetCtrlParameters(**kwargs)
81 control.Refresh()
8fa876ca 82
1fded56b
RD
83 self.Refresh()
84
85
86
87#----------------------------------------------------------------------------
8fa876ca 88class demoPage1(scroll.wxScrolledPanel, demoMixin):
1fded56b 89 def __init__(self, parent, log):
8fa876ca
RD
90 scroll.wxScrolledPanel.__init__(self, parent, -1)
91 self.sizer = wx.BoxSizer( wx.VERTICAL )
1fded56b
RD
92 self.editList = []
93
8fa876ca
RD
94 label = wx.StaticText( self, -1, """\
95Here are some basic MaskedTextCtrls to give you an idea of what you can do
1fded56b
RD
96with this control. Note that all controls have been auto-sized by including 'F' in
97the format codes.
98
99Try entering nonsensical or partial values in validated fields to see what happens.
100Note that the State and Last Name fields are list-limited (valid last names are:
101Smith, Jones, Williams). Signs on numbers can be toggled with the minus key.
102""")
103 label.SetForegroundColour( "Blue" )
8fa876ca
RD
104 header = wx.BoxSizer( wx.HORIZONTAL )
105 header.Add( label, 0, flag=wx.ALIGN_LEFT|wx.ALL, border = 5 )
1fded56b 106
8fa876ca
RD
107 highlight = wx.CheckBox( self, -1, "Highlight Empty" )
108 disallow = wx.CheckBox( self, -1, "Disallow Empty" )
109 showFill = wx.CheckBox( self, -1, "change fillChar" )
1fded56b 110
8fa876ca
RD
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 )
1fded56b 117
8fa876ca
RD
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())
1fded56b 121
8fa876ca 122 grid = wx.FlexGridSizer( 0, 5, vgap=10, hgap=10 )
1fded56b
RD
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)
8fa876ca
RD
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 )
1fded56b
RD
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"""
8b9a4190 153 self.changeControlParams( event, "emptyBackgroundColour", "Blue", "White" )
1fded56b
RD
154
155 def onShowFill( self, event ):
156 """ Set fillChar parameter to '?' or ' ' """
157 self.changeControlParams( event, "fillChar", '?', ' ' )
158
159
8fa876ca 160class demoPage2(scroll.wxScrolledPanel, demoMixin):
1fded56b
RD
161 def __init__( self, parent, log ):
162 self.log = log
8fa876ca
RD
163 scroll.wxScrolledPanel.__init__( self, parent, -1 )
164 self.sizer = wx.BoxSizer( wx.VERTICAL )
1fded56b 165
8fa876ca 166 label = wx.StaticText( self, -1, """\
8b9a4190
RD
167All these controls have been created by passing a single parameter, the autoformat code,
168and use the factory class wxMaskedCtrl with its default controlType.
169The maskededit module contains an internal dictionary of types and formats (autoformats).
1fded56b
RD
170Many of these already do complicated validation; To see some examples, try
17129 Feb 2002 vs. 2004 for the date formats, or email address validation.
172""")
173
174 label.SetForegroundColour( "Blue" )
8fa876ca 175 self.sizer.Add( label, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
1fded56b 176
8fa876ca
RD
177 description = wx.StaticText( self, -1, "Description")
178 autofmt = wx.StaticText( self, -1, "AutoFormat Code")
179 ctrl = wx.StaticText( self, -1, "MaskedCtrl")
1fded56b 180
8fa876ca
RD
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 ) )
1fded56b 184
8fa876ca
RD
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 )
1fded56b 189
8fa876ca
RD
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, "",
8b9a4190
RD
194 autoformat = autoformat,
195 demo = True,
196 name = autoformat),
8fa876ca 197 0, wx.ALIGN_LEFT )
1fded56b 198
8fa876ca 199 self.sizer.Add( grid, 0, wx.ALIGN_LEFT|wx.ALL, border=5 )
1fded56b
RD
200 self.SetSizer( self.sizer )
201 self.SetAutoLayout( 1 )
202 self.SetupScrolling()
203
204
8fa876ca 205class demoPage3(scroll.wxScrolledPanel, demoMixin):
1fded56b
RD
206 def __init__(self, parent, log):
207 self.log = log
8fa876ca
RD
208 scroll.wxScrolledPanel.__init__(self, parent, -1)
209 self.sizer = wx.BoxSizer( wx.VERTICAL )
1fded56b
RD
210 self.editList = []
211
8fa876ca 212 label = wx.StaticText( self, -1, """\
1fded56b
RD
213Here wxMaskedTextCtrls that have default values. The states
214control has a list of valid values, and the unsigned integer
215has a legal range specified.
216""")
217 label.SetForegroundColour( "Blue" )
8fa876ca
RD
218 requireValid = wx.CheckBox( self, -1, "Require Valid Value" )
219 self.Bind(wx.EVT_CHECKBOX, self.onRequireValid, id=requireValid.GetId())
1fded56b 220
8fa876ca
RD
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 )
1fded56b 225
8fa876ca 226 grid = wx.FlexGridSizer( 0, 5, vgap=10, hgap=10 )
1fded56b
RD
227 self.labelGeneralTable( grid )
228
229 controls = [
230 #description mask excl format regexp range,list,initial
8fa876ca 231 ("U.S. State (2 char)", "AA", "", 'F!_', "[A-Z]{2}", '',med.states, med.states[0]),
8b9a4190 232 ("Integer (signed)", "#{6}", "", 'F-_', "", '','', ' 0 '),
1fded56b
RD
233 ("Integer (unsigned)\n(1-399)","######", "", 'F_', "", (1,399),'', '1 '),
234 ("Float (signed)", "#{6}.#{9}", "", 'F-_R', "", '','', '000000.000000000'),
8fa876ca 235 ("Date (MDY) + Time", "##/##/#### ##:##:## AM", 'BCDEFGHIJKLMNOQRSTUVWXYZ','DF!',"", '','', wx.DateTime_Now().Format("%m/%d/%Y %I:%M:%S %p")),
1fded56b
RD
236 ]
237 self.layoutGeneralTable( controls, grid )
238
8fa876ca
RD
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 )
1fded56b
RD
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
8fa876ca 251class demoPage4(scroll.wxScrolledPanel, demoMixin):
1fded56b
RD
252 def __init__( self, parent, log ):
253 self.log = log
8fa876ca
RD
254 scroll.wxScrolledPanel.__init__( self, parent, -1 )
255 self.sizer = wx.BoxSizer( wx.VERTICAL )
1fded56b 256
8fa876ca 257 label = wx.StaticText( self, -1, """\
1fded56b
RD
258These controls have field-specific choice lists and allow autocompletion.
259
260Down arrow or Page Down in an uncompleted field with an auto-completable field will attempt
261to auto-complete a field if it has a choice list.
262Page Down and Shift-Down arrow will also auto-complete, or cycle through the complete list.
263Page Up and Shift-Up arrow will similarly cycle backwards through the list.
264""")
265
266 label.SetForegroundColour( "Blue" )
8fa876ca 267 self.sizer.Add( label, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
1fded56b 268
8fa876ca
RD
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" )
1fded56b 273
8fa876ca
RD
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 ) )
1fded56b 278
8fa876ca
RD
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 )
1fded56b
RD
284
285 autoformat = "USPHONEFULLEXT"
8fa876ca 286 fieldsDict = {0: med.Field(choices=["617","781","508","978","413"], choiceRequired=True)}
1fded56b
RD
287 fieldsLabel = """\
288{0: Field(choices=[
289 "617","781",
290 "508","978","413"],
291 choiceRequired=True)}"""
8fa876ca
RD
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, "",
1fded56b
RD
296 autoformat = autoformat,
297 fields = fieldsDict,
298 demo = True,
299 name = autoformat),
8fa876ca 300 0, wx.ALIGN_LEFT )
1fded56b
RD
301
302 autoformat = "EXPDATEMMYY"
8fa876ca 303 fieldsDict = {1: med.Field(choices=["03", "04", "05"], choiceRequired=True)}
1fded56b
RD
304 fieldsLabel = """\
305{1: Field(choices=[
306 "03", "04", "05"],
307 choiceRequired=True)}"""
8fa876ca 308 exp = med.wxMaskedTextCtrl( self, -1, "",
1fded56b
RD
309 autoformat = autoformat,
310 fields = fieldsDict,
311 demo = True,
312 name = autoformat)
313
8fa876ca
RD
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 )
1fded56b 318
8fa876ca
RD
319 fieldsDict = {0: med.Field(choices=["02134","02155"], choiceRequired=True),
320 1: med.Field(choices=["1234", "5678"], choiceRequired=False)}
1fded56b
RD
321 fieldsLabel = """\
322{0: Field(choices=["02134","02155"],
323 choiceRequired=True),
324 1: Field(choices=["1234", "5678"],
325 choiceRequired=False)}"""
326 autoformat = "USZIPPLUS4"
8fa876ca 327 zip = med.wxMaskedTextCtrl( self, -1, "",
1fded56b
RD
328 autoformat = autoformat,
329 fields = fieldsDict,
330 demo = True,
331 name = autoformat)
332
8fa876ca
RD
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 )
1fded56b 337
8fa876ca 338 self.sizer.Add( grid, 0, wx.ALIGN_LEFT|wx.ALL, border=5 )
1fded56b
RD
339 self.SetSizer( self.sizer )
340 self.SetAutoLayout(1)
341 self.SetupScrolling()
342
343
8fa876ca 344class demoPage5(scroll.wxScrolledPanel, demoMixin):
1fded56b
RD
345 def __init__( self, parent, log ):
346 self.log = log
8fa876ca
RD
347 scroll.wxScrolledPanel.__init__( self, parent, -1 )
348 self.sizer = wx.BoxSizer( wx.VERTICAL )
8b9a4190
RD
349
350
8fa876ca 351 labelMaskedCombos = wx.StaticText( self, -1, """\
8b9a4190
RD
352These are some examples of wxMaskedComboBox:""")
353 labelMaskedCombos.SetForegroundColour( "Blue" )
354
355
8fa876ca 356 label_statecode = wx.StaticText( self, -1, """\
8b9a4190
RD
357A state selector; only
358"legal" values can be
359entered:""")
8fa876ca
RD
360 statecode = med.wxMaskedComboBox( self, -1, med.states[0],
361 choices = med.states,
8b9a4190
RD
362 autoformat="USSTATE")
363
8fa876ca 364 label_statename = wx.StaticText( self, -1, """\
8b9a4190
RD
365A state name selector,
366with auto-select:""")
367
368 # Create this one using factory function:
8fa876ca
RD
369 statename = mctl.wxMaskedCtrl( self, -1, med.state_names[0],
370 controlType = mctl.controlTypes.MASKEDCOMBO,
371 choices = med.state_names,
8b9a4190
RD
372 autoformat="USSTATENAME",
373 autoSelect=True)
374 statename.SetCtrlParameters(formatcodes = 'F!V_')
375
1fded56b
RD
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] ]
8fa876ca
RD
379 fieldsDict = {0: med.Field(choices=numerators, choiceRequired=False),
380 1: med.Field(choices=denominators, choiceRequired=True)}
1fded56b
RD
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
8fa876ca 388 label_fraction = wx.StaticText( self, -1, """\
1fded56b 389A masked ComboBox for fraction selection.
8b9a4190
RD
390Choices for each side of the fraction can
391be selected with PageUp/Down:""")
1fded56b 392
8fa876ca
RD
393 fraction = mctl.wxMaskedCtrl( self, -1, "",
394 controlType = mctl.MASKEDCOMBO,
8b9a4190
RD
395 choices = choices,
396 choiceRequired = True,
397 mask = "#/##",
398 formatcodes = "F_",
399 validRegex = "^\d\/\d\d?",
400 fields = fieldsDict )
1fded56b
RD
401
402
8fa876ca 403 label_code = wx.StaticText( self, -1, """\
1fded56b
RD
404A masked ComboBox to validate
405text from a list of numeric codes:""")
406
407 choices = ["91", "136", "305", "4579"]
8fa876ca 408 code = med.wxMaskedComboBox( self, -1, choices[0],
1fded56b
RD
409 choices = choices,
410 choiceRequired = True,
411 formatcodes = "F_r",
412 mask = "####")
413
8fa876ca 414 label_selector = wx.StaticText( self, -1, """\
8b9a4190
RD
415Programmatically set
416choice sets:""")
8fa876ca
RD
417 self.list_selector = wx.ComboBox(self, -1, '', choices = ['list1', 'list2', 'list3'])
418 self.dynamicbox = mctl.wxMaskedCtrl( self, -1, ' ',
419 controlType = mctl.controlTypes.MASKEDCOMBO,
8b9a4190
RD
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'] )
1fded56b 426
8b9a4190 427 self.dynamicbox.Clear() # get rid of initial choices used to size the dropdown
1fded56b 428
1fded56b 429
8fa876ca 430 labelIpAddrs = wx.StaticText( self, -1, """\
8b9a4190
RD
431Here are some examples of wxIpAddrCtrl, a control derived from wxMaskedTextCtrl:""")
432 labelIpAddrs.SetForegroundColour( "Blue" )
1fded56b
RD
433
434
8fa876ca
RD
435 label_ipaddr1 = wx.StaticText( self, -1, "An empty control:")
436 ipaddr1 = med.wxIpAddrCtrl( self, -1, style = wx.TE_PROCESS_TAB )
1fded56b
RD
437
438
8fa876ca
RD
439 label_ipaddr2 = wx.StaticText( self, -1, "A restricted mask:")
440 ipaddr2 = med.wxIpAddrCtrl( self, -1, mask=" 10. 1.109.###" )
1fded56b
RD
441
442
8fa876ca 443 label_ipaddr3 = wx.StaticText( self, -1, """\
8b9a4190
RD
444A control with restricted legal values:
44510. (1|2) . (129..255) . (0..255)""")
8fa876ca
RD
446 ipaddr3 = mctl.wxMaskedCtrl( self, -1,
447 controlType = mctl.controlTypes.IPADDR,
8b9a4190
RD
448 mask=" 10. #.###.###")
449 ipaddr3.SetFieldParameters(0, validRegex="1|2",validRequired=False ) # requires entry to match or not allowed
450
1fded56b 451 # This allows any value in penultimate field, but colors anything outside of the range invalid:
8b9a4190
RD
452 ipaddr3.SetFieldParameters(1, validRange=(129,255), validRequired=False )
453
1fded56b 454
1fded56b 455
8fa876ca 456 labelNumerics = wx.StaticText( self, -1, """\
8b9a4190
RD
457Here are some useful configurations of a wxMaskedTextCtrl for integer and floating point input that still treat
458the control as a text control. (For a true numeric control, check out the wxMaskedNumCtrl class!)""")
459 labelNumerics.SetForegroundColour( "Blue" )
460
8fa876ca 461 label_intctrl1 = wx.StaticText( self, -1, """\
8b9a4190
RD
462An integer entry control with
463shifting insert enabled:""")
8fa876ca
RD
464 self.intctrl1 = med.wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-,F>')
465 label_intctrl2 = wx.StaticText( self, -1, """\
8b9a4190 466 Right-insert integer entry:""")
8fa876ca 467 self.intctrl2 = med.wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-,Fr')
8b9a4190 468
8fa876ca 469 label_floatctrl = wx.StaticText( self, -1, """\
1fded56b
RD
470A floating point entry control
471with right-insert for ordinal:""")
8fa876ca 472 self.floatctrl = med.wxMaskedTextCtrl(self, -1, name='floatctrl', mask="#{9}.#{2}", formatcodes="F,_-R", useParensForNegatives=False)
1fded56b
RD
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
8fa876ca 476 label_numselect = wx.StaticText( self, -1, """\
8b9a4190
RD
477<= Programmatically set the value
478 of the float entry ctrl:""")
8fa876ca 479 numselect = wx.ComboBox(self, -1, choices = [ '', '111', '222.22', '-3', '54321.666666666', '-1353.978',
8b9a4190
RD
480 '1234567', '-1234567', '123456789', '-123456789.1',
481 '1234567890.', '-1234567890.1' ])
482
8fa876ca
RD
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 )
1fded56b 530
1fded56b
RD
531 self.SetSizer( self.sizer )
532 self.SetAutoLayout(1)
533 self.SetupScrolling()
534
8fa876ca
RD
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())
8b9a4190 543
8fa876ca
RD
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())
8b9a4190 549
8fa876ca
RD
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())
1fded56b
RD
553
554
8b9a4190
RD
555
556
557 def OnComboSelection( self, event ):
1fded56b
RD
558 ctl = self.FindWindowById( event.GetId() )
559 if not ctl.IsValid():
560 self.log.write('current value not a valid choice')
8b9a4190 561 self.log.write('new value = %s' % ctl.GetValue())
1fded56b
RD
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()
1fded56b
RD
570 # Format choice to fit into format for #{9}.#{2}, with sign position reserved:
571 # (ordinal + fraction == 11 + decimal point + sign == 13)
1fded56b
RD
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
8b9a4190 583 def OnParensCheck( self, event ):
b881fc78
RD
584 self.intctrl1.SetCtrlParameters(useParensForNegatives=event.IsChecked())
585 self.intctrl2.SetCtrlParameters(useParensForNegatives=event.IsChecked())
586 self.floatctrl.SetCtrlParameters(useParensForNegatives=event.IsChecked())
8b9a4190
RD
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:
b881fc78 604 choices = med.states
8b9a4190
RD
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
1fded56b 614# ---------------------------------------------------------------------
8fa876ca 615class TestMaskedTextCtrls(wx.Notebook):
1fded56b 616 def __init__(self, parent, id, log):
8fa876ca 617 wx.Notebook.__init__(self, parent, id)
1fded56b
RD
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
638def runTest(frame, nb, log):
639 testWin = TestMaskedTextCtrls(nb, -1, log)
640 return testWin
641
642def RunStandalone():
8fa876ca
RD
643 app = wx.PySimpleApp()
644 frame = wx.Frame(None, -1, "Test MaskedTextCtrl", size=(640, 480))
1fded56b
RD
645 win = TestMaskedTextCtrls(frame, -1, sys.stdout)
646 frame.Show(True)
647 app.MainLoop()
648#----------------------------------------------------------------------------
1fded56b
RD
649
650overview = """<html>
651<PRE><FONT SIZE=-1>
8fa876ca 652""" + med.__doc__ + """
1fded56b
RD
653</FONT></PRE>
654"""
655
656if __name__ == "__main__":
657 import sys,os
658 import run
659 run.main(['', os.path.basename(sys.argv[0])])