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