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