Updates to wxMaskedEditCtrl.

Added wxMaskedNumCtrl.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@23909 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2003-09-25 18:29:40 +00:00
parent 3adf0c5b2b
commit f0e615b6ab
8 changed files with 4836 additions and 795 deletions

View File

@@ -1,10 +1,12 @@
from wxPython.wx import *
from wxPython.lib.maskededit import Field, wxMaskedTextCtrl, wxMaskedComboBox, wxIpAddrCtrl, states, months
from wxPython.lib.maskededit import __doc__ as overviewdoc
from wxPython.lib.maskededit import Field, wxMaskedTextCtrl, wxMaskedComboBox, wxIpAddrCtrl, states, state_names, months
from wxPython.lib.maskededit import __doc__ as maskededit_doc
from wxPython.lib.maskededit import autoformats
from wxPython.lib.maskedctrl import wxMaskedCtrl, controlTypes, MASKEDCOMBO
from wxPython.lib.scrolledpanel import wxScrolledPanel
import string, sys, traceback
class demoMixin:
"""
Centralized routines common to demo pages, to remove repetition.
@@ -14,7 +16,7 @@ class demoMixin:
mask = wxStaticText( self, -1, "Mask Value" )
formatcode = wxStaticText( self, -1, "Format" )
regex = wxStaticText( self, -1, "Regexp Validator(opt.)" )
ctrl = wxStaticText( self, -1, "wxMaskedEdit Ctrl" )
ctrl = wxStaticText( self, -1, "wxMaskedTextCtrl" )
description.SetFont( wxFont(9, wxSWISS, wxNORMAL, wxBOLD))
mask.SetFont( wxFont(9, wxSWISS, wxNORMAL, wxBOLD))
@@ -130,7 +132,7 @@ Smith, Jones, Williams). Signs on numbers can be toggled with the minus key.
def onHighlightEmpty( self, event ):
""" Highlight empty values"""
self.changeControlParams( event, "emptyBackgroundColor", "Blue", "White" )
self.changeControlParams( event, "emptyBackgroundColour", "Blue", "White" )
def onShowFill( self, event ):
""" Set fillChar parameter to '?' or ' ' """
@@ -144,8 +146,9 @@ class demoPage2(wxScrolledPanel, demoMixin):
self.sizer = wxBoxSizer( wxVERTICAL )
label = wxStaticText( self, -1, """\
All these controls have been created by passing a single parameter, the autoformat code.
The class contains an internal dictionary of types and formats (autoformats).
All these controls have been created by passing a single parameter, the autoformat code,
and use the factory class wxMaskedCtrl with its default controlType.
The maskededit module contains an internal dictionary of types and formats (autoformats).
Many of these already do complicated validation; To see some examples, try
29 Feb 2002 vs. 2004 for the date formats, or email address validation.
""")
@@ -155,7 +158,7 @@ Many of these already do complicated validation; To see some examples, try
description = wxStaticText( self, -1, "Description")
autofmt = wxStaticText( self, -1, "AutoFormat Code")
ctrl = wxStaticText( self, -1, "wxMaskedEdit Control")
ctrl = wxStaticText( self, -1, "wxMaskedCtrl")
description.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
autofmt.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
@@ -169,10 +172,10 @@ Many of these already do complicated validation; To see some examples, try
for autoformat, desc in autoformats:
grid.Add( wxStaticText( self, -1, desc), 0, wxALIGN_LEFT )
grid.Add( wxStaticText( self, -1, autoformat), 0, wxALIGN_LEFT )
grid.Add( wxMaskedTextCtrl( self, -1, "",
autoformat = autoformat,
demo = True,
name = autoformat),
grid.Add( wxMaskedCtrl( self, -1, "",
autoformat = autoformat,
demo = True,
name = autoformat),
0, wxALIGN_LEFT )
self.sizer.Add( grid, 0, wxALIGN_LEFT|wxALL, border=5 )
@@ -208,7 +211,7 @@ has a legal range specified.
controls = [
#description mask excl format regexp range,list,initial
("U.S. State (2 char)", "AA", "", 'F!_', "[A-Z]{2}", '',states, states[0]),
("Integer (signed)", "#{6}", "", 'F-_R', "", '','', '0 '),
("Integer (signed)", "#{6}", "", 'F-_', "", '','', ' 0 '),
("Integer (unsigned)\n(1-399)","######", "", 'F_', "", (1,399),'', '1 '),
("Float (signed)", "#{6}.#{9}", "", 'F-_R', "", '','', '000000.000000000'),
("Date (MDY) + Time", "##/##/#### ##:##:## AM", 'BCDEFGHIJKLMNOQRSTUVWXYZ','DF!',"", '','', wxDateTime_Now().Format("%m/%d/%Y %I:%M:%S %p")),
@@ -248,7 +251,7 @@ Page Up and Shift-Up arrow will similarly cycle backwards through the list.
description = wxStaticText( self, -1, "Description" )
autofmt = wxStaticText( self, -1, "AutoFormat Code" )
fields = wxStaticText( self, -1, "Field Objects" )
ctrl = wxStaticText( self, -1, "wxMaskedEdit Control" )
ctrl = wxStaticText( self, -1, "wxMaskedTextCtrl" )
description.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
autofmt.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
@@ -325,12 +328,33 @@ class demoPage5(wxScrolledPanel, demoMixin):
self.log = log
wxScrolledPanel.__init__( self, parent, -1 )
self.sizer = wxBoxSizer( wxVERTICAL )
label = wxStaticText( self, -1, """\
These are examples of wxMaskedComboBox and wxIpAddrCtrl, and more useful
configurations of a wxMaskedTextCtrl for integer and floating point input.
""")
label.SetForegroundColour( "Blue" )
self.sizer.Add( label, 0, wxALIGN_LEFT|wxALL, 5 )
labelMaskedCombos = wxStaticText( self, -1, """\
These are some examples of wxMaskedComboBox:""")
labelMaskedCombos.SetForegroundColour( "Blue" )
label_statecode = wxStaticText( self, -1, """\
A state selector; only
"legal" values can be
entered:""")
statecode = wxMaskedComboBox( self, -1, states[0],
choices = states,
autoformat="USSTATE")
label_statename = wxStaticText( self, -1, """\
A state name selector,
with auto-select:""")
# Create this one using factory function:
statename = wxMaskedCtrl( self, -1, state_names[0],
controlType = controlTypes.MASKEDCOMBO,
choices = state_names,
autoformat="USSTATENAME",
autoSelect=True)
statename.SetCtrlParameters(formatcodes = 'F!V_')
numerators = [ str(i) for i in range(1, 4) ]
denominators = [ string.ljust(str(i), 2) for i in [2,3,4,5,8,16,32,64] ]
@@ -343,21 +367,22 @@ configurations of a wxMaskedTextCtrl for integer and floating point input.
choices.append( '%s/%s' % (n,d) )
text1 = wxStaticText( self, -1, """\
label_fraction = wxStaticText( self, -1, """\
A masked ComboBox for fraction selection.
Choices for each side of the fraction can be
selected with PageUp/Down:""")
Choices for each side of the fraction can
be selected with PageUp/Down:""")
fraction = wxMaskedComboBox( self, -1, "",
choices = choices,
choiceRequired = True,
mask = "#/##",
formatcodes = "F_",
validRegex = "^\d\/\d\d?",
fields = fieldsDict )
fraction = wxMaskedCtrl( self, -1, "",
controlType = MASKEDCOMBO,
choices = choices,
choiceRequired = True,
mask = "#/##",
formatcodes = "F_",
validRegex = "^\d\/\d\d?",
fields = fieldsDict )
text2 = wxStaticText( self, -1, """
label_code = wxStaticText( self, -1, """\
A masked ComboBox to validate
text from a list of numeric codes:""")
@@ -368,100 +393,155 @@ text from a list of numeric codes:""")
formatcodes = "F_r",
mask = "####")
label_selector = wxStaticText( self, -1, """\
Programmatically set
choice sets:""")
self.list_selector = wxComboBox(self, -1, '', choices = ['list1', 'list2', 'list3'])
self.dynamicbox = wxMaskedCtrl( self, -1, ' ',
controlType = controlTypes.MASKEDCOMBO,
mask = 'XXXX',
formatcodes = 'F_',
# these are to give dropdown some initial height,
# as base control apparently only sets that size
# during initial construction <sigh>:
choices = ['', '1', '2', '3', '4', '5'] )
text3 = wxStaticText( self, -1, """\
A masked state selector; only "legal" values
can be entered:""")
state = wxMaskedComboBox( self, -1, states[0],
choices = states,
autoformat="USSTATE")
text4 = wxStaticText( self, -1, "An empty IP Address entry control:")
ip_addr1 = wxIpAddrCtrl( self, -1, style = wxTE_PROCESS_TAB )
self.dynamicbox.Clear() # get rid of initial choices used to size the dropdown
text5 = wxStaticText( self, -1, "An IP Address control with a restricted mask:")
ip_addr2 = wxIpAddrCtrl( self, -1, mask=" 10. 1.109.###" )
labelIpAddrs = wxStaticText( self, -1, """\
Here are some examples of wxIpAddrCtrl, a control derived from wxMaskedTextCtrl:""")
labelIpAddrs.SetForegroundColour( "Blue" )
text6 = wxStaticText( self, -1, """\
An IP Address control with restricted choices
of form: 10. (1|2) . (129..255) . (0..255)""")
ip_addr3 = wxIpAddrCtrl( self, -1, mask=" 10. #.###.###")
ip_addr3.SetFieldParameters(0, validRegex="1|2" ) # requires entry to match or not allowed
label_ipaddr1 = wxStaticText( self, -1, "An empty control:")
ipaddr1 = wxIpAddrCtrl( self, -1, style = wxTE_PROCESS_TAB )
label_ipaddr2 = wxStaticText( self, -1, "A restricted mask:")
ipaddr2 = wxIpAddrCtrl( self, -1, mask=" 10. 1.109.###" )
label_ipaddr3 = wxStaticText( self, -1, """\
A control with restricted legal values:
10. (1|2) . (129..255) . (0..255)""")
ipaddr3 = wxMaskedCtrl( self, -1,
controlType = controlTypes.IPADDR,
mask=" 10. #.###.###")
ipaddr3.SetFieldParameters(0, validRegex="1|2",validRequired=False ) # requires entry to match or not allowed
# This allows any value in penultimate field, but colors anything outside of the range invalid:
ip_addr3.SetFieldParameters(1, validRange=(129,255), validRequired=False )
ipaddr3.SetFieldParameters(1, validRange=(129,255), validRequired=False )
text7 = wxStaticText( self, -1, """\
A right-insert integer entry control:""")
intctrl = wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-r,F')
text8 = wxStaticText( self, -1, """\
labelNumerics = wxStaticText( self, -1, """\
Here are some useful configurations of a wxMaskedTextCtrl for integer and floating point input that still treat
the control as a text control. (For a true numeric control, check out the wxMaskedNumCtrl class!)""")
labelNumerics.SetForegroundColour( "Blue" )
label_intctrl1 = wxStaticText( self, -1, """\
An integer entry control with
shifting insert enabled:""")
self.intctrl1 = wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-,F>')
label_intctrl2 = wxStaticText( self, -1, """\
Right-insert integer entry:""")
self.intctrl2 = wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-,Fr')
label_floatctrl = wxStaticText( self, -1, """\
A floating point entry control
with right-insert for ordinal:""")
self.floatctrl = wxMaskedTextCtrl(self, -1, name='floatctrl', mask="#{9}.#{2}", formatcodes="F,_-R")
self.floatctrl = wxMaskedTextCtrl(self, -1, name='floatctrl', mask="#{9}.#{2}", formatcodes="F,_-R", useParensForNegatives=False)
self.floatctrl.SetFieldParameters(0, formatcodes='r<', validRequired=True) # right-insert, require explicit cursor movement to change fields
self.floatctrl.SetFieldParameters(1, defaultValue='00') # don't allow blank fraction
text9 = wxStaticText( self, -1, """\
Use this control to programmatically set
the value of the above float control:""")
number_combo = wxComboBox(self, -1, choices = [ '', '111', '222.22', '-3', '54321.666666666', '-1353.978',
'1234567', '-1234567', '123456789', '-123456789.1',
'1234567890.', '-1234567890.1' ])
label_numselect = wxStaticText( self, -1, """\
<= Programmatically set the value
of the float entry ctrl:""")
numselect = wxComboBox(self, -1, choices = [ '', '111', '222.22', '-3', '54321.666666666', '-1353.978',
'1234567', '-1234567', '123456789', '-123456789.1',
'1234567890.', '-1234567890.1' ])
grid = wxFlexGridSizer( 0, 2, vgap=10, hgap = 5 )
grid.Add( text1, 0, wxALIGN_LEFT )
grid.Add( fraction, 0, wxALIGN_LEFT )
grid.Add( text2, 0, wxALIGN_LEFT )
grid.Add( code, 0, wxALIGN_LEFT )
grid.Add( text3, 0, wxALIGN_LEFT )
grid.Add( state, 0, wxALIGN_LEFT )
grid.Add( text4, 0, wxALIGN_LEFT )
grid.Add( ip_addr1, 0, wxALIGN_LEFT )
grid.Add( text5, 0, wxALIGN_LEFT )
grid.Add( ip_addr2, 0, wxALIGN_LEFT )
grid.Add( text6, 0, wxALIGN_LEFT )
grid.Add( ip_addr3, 0, wxALIGN_LEFT )
grid.Add( text7, 0, wxALIGN_LEFT )
grid.Add( intctrl, 0, wxALIGN_LEFT )
grid.Add( text8, 0, wxALIGN_LEFT )
grid.Add( self.floatctrl, 0, wxALIGN_LEFT )
grid.Add( text9, 0, wxALIGN_LEFT )
grid.Add( number_combo, 0, wxALIGN_LEFT )
parens_check = wxCheckBox(self, -1, "Use () to indicate negatives in above controls")
gridCombos = wxFlexGridSizer( 0, 4, vgap=10, hgap = 10 )
gridCombos.Add( label_statecode, 0, wxALIGN_LEFT )
gridCombos.Add( statecode, 0, wxALIGN_LEFT )
gridCombos.Add( label_fraction, 0, wxALIGN_LEFT )
gridCombos.Add( fraction, 0, wxALIGN_LEFT )
gridCombos.Add( label_statename, 0, wxALIGN_LEFT )
gridCombos.Add( statename, 0, wxALIGN_LEFT )
gridCombos.Add( label_code, 0, wxALIGN_LEFT )
gridCombos.Add( code, 0, wxALIGN_LEFT )
gridCombos.Add( label_selector, 0, wxALIGN_LEFT)
hbox = wxBoxSizer( wxHORIZONTAL )
hbox.Add( self.list_selector, 0, wxALIGN_LEFT )
hbox.Add(wxStaticText(self, -1, ' => '), 0, wxALIGN_LEFT)
hbox.Add( self.dynamicbox, 0, wxALIGN_LEFT )
gridCombos.Add( hbox, 0, wxALIGN_LEFT )
gridIpAddrs = wxFlexGridSizer( 0, 4, vgap=10, hgap = 15 )
gridIpAddrs.Add( label_ipaddr1, 0, wxALIGN_LEFT )
gridIpAddrs.Add( ipaddr1, 0, wxALIGN_LEFT )
gridIpAddrs.Add( label_ipaddr2, 0, wxALIGN_LEFT )
gridIpAddrs.Add( ipaddr2, 0, wxALIGN_LEFT )
gridIpAddrs.Add( label_ipaddr3, 0, wxALIGN_LEFT )
gridIpAddrs.Add( ipaddr3, 0, wxALIGN_LEFT )
gridNumerics = wxFlexGridSizer( 0, 4, vgap=10, hgap = 10 )
gridNumerics.Add( label_intctrl1, 0, wxALIGN_LEFT )
gridNumerics.Add( self.intctrl1, 0, wxALIGN_LEFT )
gridNumerics.Add( label_intctrl2, 0, wxALIGN_RIGHT )
gridNumerics.Add( self.intctrl2, 0, wxALIGN_LEFT )
gridNumerics.Add( label_floatctrl, 0, wxALIGN_LEFT )
gridNumerics.Add( self.floatctrl, 0, wxALIGN_LEFT )
gridNumerics.Add( label_numselect, 0, wxALIGN_RIGHT )
gridNumerics.Add( numselect, 0, wxALIGN_LEFT )
self.sizer.Add( labelMaskedCombos, 0, wxALIGN_LEFT|wxALL, 5 )
self.sizer.Add( gridCombos, 0, wxALIGN_LEFT|wxALL, border=5 )
self.sizer.Add( wxStaticLine(self, -1), 0, wxEXPAND|wxTOP|wxBOTTOM, border=8 )
self.sizer.Add( labelIpAddrs, 0, wxALIGN_LEFT|wxALL, 5 )
self.sizer.Add( gridIpAddrs, 0, wxALIGN_LEFT|wxALL, border=5 )
self.sizer.Add( wxStaticLine(self, -1), 0, wxEXPAND|wxTOP|wxBOTTOM, border=8 )
self.sizer.Add( labelNumerics, 0, wxALIGN_LEFT|wxALL, 5 )
self.sizer.Add( gridNumerics, 0, wxALIGN_LEFT|wxALL, border=5 )
self.sizer.Add( parens_check, 0, wxALIGN_LEFT|wxALL, 5 )
self.sizer.Add( grid, 0, wxALIGN_LEFT|wxALL, border=5 )
self.SetSizer( self.sizer )
self.SetAutoLayout(1)
self.SetupScrolling()
EVT_COMBOBOX( self, fraction.GetId(), self.OnComboChange )
EVT_COMBOBOX( self, code.GetId(), self.OnComboChange )
EVT_COMBOBOX( self, state.GetId(), self.OnComboChange )
EVT_TEXT( self, fraction.GetId(), self.OnComboChange )
EVT_TEXT( self, code.GetId(), self.OnComboChange )
EVT_TEXT( self, state.GetId(), self.OnComboChange )
EVT_COMBOBOX( self, fraction.GetId(), self.OnComboSelection )
EVT_COMBOBOX( self, code.GetId(), self.OnComboSelection )
EVT_COMBOBOX( self, statecode.GetId(), self.OnComboSelection )
EVT_COMBOBOX( self, statename.GetId(), self.OnComboSelection )
EVT_TEXT( self, fraction.GetId(), self.OnTextChange )
EVT_TEXT( self, code.GetId(), self.OnTextChange )
EVT_TEXT( self, statecode.GetId(), self.OnTextChange )
EVT_TEXT( self, statename.GetId(), self.OnTextChange )
EVT_COMBOBOX( self, self.list_selector.GetId(), self.OnListSelection )
EVT_TEXT( self, ip_addr1.GetId(), self.OnIpAddrChange )
EVT_TEXT( self, ip_addr2.GetId(), self.OnIpAddrChange )
EVT_TEXT( self, ip_addr3.GetId(), self.OnIpAddrChange )
EVT_TEXT( self, intctrl.GetId(), self.OnTextChange )
EVT_TEXT( self, self.intctrl1.GetId(), self.OnTextChange )
EVT_TEXT( self, self.intctrl2.GetId(), self.OnTextChange )
EVT_TEXT( self, self.floatctrl.GetId(), self.OnTextChange )
EVT_COMBOBOX( self, number_combo.GetId(), self.OnNumberSelect )
EVT_COMBOBOX( self, numselect.GetId(), self.OnNumberSelect )
EVT_CHECKBOX( self, parens_check.GetId(), self.OnParensCheck )
EVT_TEXT( self, ipaddr1.GetId(), self.OnIpAddrChange )
EVT_TEXT( self, ipaddr2.GetId(), self.OnIpAddrChange )
EVT_TEXT( self, ipaddr3.GetId(), self.OnIpAddrChange )
def OnComboChange( self, event ):
def OnComboSelection( self, event ):
ctl = self.FindWindowById( event.GetId() )
if not ctl.IsValid():
self.log.write('current value not a valid choice')
def OnIpAddrChange( self, event ):
ip_addr = self.FindWindowById( event.GetId() )
if ip_addr.IsValid():
self.log.write('new addr = %s\n' % ip_addr.GetAddress() )
self.log.write('new value = %s' % ctl.GetValue())
def OnTextChange( self, event ):
ctl = self.FindWindowById( event.GetId() )
@@ -470,14 +550,8 @@ the value of the above float control:""")
def OnNumberSelect( self, event ):
value = event.GetString()
# Format choice to fit into format for #{9}.#{2}, with sign position reserved:
# (ordinal + fraction == 11 + decimal point + sign == 13)
#
# Note: since self.floatctrl a right-aligned control, you could also just use
# "%.2f", but this wouldn't work properly for a left-aligned control.
# (See .SetValue() documentation in Overview.)
#
if value:
floattext = "%13.2f" % float(value)
else:
@@ -489,6 +563,37 @@ the value of the above float control:""")
for line in traceback.format_exception_only(type, value):
self.log.write(line)
def OnParensCheck( self, event ):
self.intctrl1.SetCtrlParameters(useParensForNegatives=event.Checked())
self.intctrl2.SetCtrlParameters(useParensForNegatives=event.Checked())
self.floatctrl.SetCtrlParameters(useParensForNegatives=event.Checked())
def OnIpAddrChange( self, event ):
ipaddr = self.FindWindowById( event.GetId() )
if ipaddr.IsValid():
self.log.write('new addr = %s\n' % ipaddr.GetAddress() )
def OnListSelection( self, event ):
list = self.list_selector.GetStringSelection()
formatcodes = 'F_'
if list == 'list1':
choices = ['abc', 'defg', 'hi']
mask = 'aaaa'
elif list == 'list2':
choices = ['1', '2', '34', '567']
formatcodes += 'r'
mask = '###'
else:
choices = states
mask = 'AA'
formatcodes += '!'
self.dynamicbox.SetCtrlParameters( mask = mask,
choices = choices,
choiceRequired=True,
autoSelect=True,
formatcodes=formatcodes)
self.dynamicbox.SetValue(choices[0])
# ---------------------------------------------------------------------
class TestMaskedTextCtrls(wxNotebook):
def __init__(self, parent, id, log):
@@ -530,7 +635,7 @@ if __name__ == "__main__":
overview = """<html>
<PRE><FONT SIZE=-1>
""" + overviewdoc + """
""" + maskededit_doc + """
</FONT></PRE>
"""