]>
Commit | Line | Data |
---|---|---|
8b9a4190 RD |
1 | from wxPython.wx import * |
2 | from wxPython.lib.maskednumctrl import wxMaskedNumCtrl, EVT_MASKEDNUM | |
3 | from wxPython.lib.maskednumctrl import __doc__ as overviewdoc | |
4 | from wxPython.lib.maskededit import wxMaskedTextCtrl | |
5 | import string, sys, traceback | |
6 | #---------------------------------------------------------------------- | |
7 | ||
8 | class TestPanel( wxPanel ): | |
9 | def __init__( self, parent, log ): | |
10 | ||
11 | wxPanel.__init__( self, parent, -1 ) | |
12 | self.log = log | |
13 | panel = wxPanel( self, -1 ) | |
14 | ||
15 | header = wxStaticText(panel, -1, """\ | |
16 | This shows the various options for wxMaskedNumCtrl. | |
17 | The controls at the top reconfigure the resulting control at the bottom. | |
18 | """) | |
19 | header.SetForegroundColour( "Blue" ) | |
20 | ||
21 | intlabel = wxStaticText( panel, -1, "Integer width:" ) | |
22 | self.integerwidth = wxMaskedNumCtrl( | |
23 | panel, value=10, | |
24 | integerWidth=2, | |
25 | allowNegative=False) | |
26 | ||
27 | fraclabel = wxStaticText( panel, -1, "Fraction width:" ) | |
28 | self.fractionwidth = wxMaskedNumCtrl( | |
29 | panel, value=0, | |
30 | integerWidth=2, | |
31 | allowNegative=False ) | |
32 | ||
33 | groupcharlabel = wxStaticText( panel,-1, "Grouping char:" ) | |
34 | self.groupchar = wxMaskedTextCtrl( panel, -1, | |
35 | value=',', | |
36 | mask='&', | |
37 | excludeChars = '-()', | |
38 | formatcodes='F', | |
39 | emptyInvalid=True, | |
40 | validRequired=True) | |
41 | ||
42 | decimalcharlabel = wxStaticText( panel,-1, "Decimal char:" ) | |
43 | self.decimalchar = wxMaskedTextCtrl( panel, -1, | |
44 | value='.', | |
45 | mask='&', | |
46 | excludeChars = '-()', | |
47 | formatcodes='F', | |
48 | emptyInvalid=True, | |
49 | validRequired=True) | |
50 | ||
51 | self.set_min = wxCheckBox( panel, -1, "Set minimum value:" ) | |
52 | # Create this wxMaskedNumCtrl using factory, to show how: | |
53 | self.min = wxMaskedNumCtrl( panel, integerWidth=5, fractionWidth=2 ) | |
54 | self.min.Enable( False ) | |
55 | ||
56 | self.set_max = wxCheckBox( panel, -1, "Set maximum value:" ) | |
57 | self.max = wxMaskedNumCtrl( panel, integerWidth=5, fractionWidth=2 ) | |
58 | self.max.Enable( False ) | |
59 | ||
60 | ||
61 | self.limit_target = wxCheckBox( panel, -1, "Limit control" ) | |
62 | self.allow_none = wxCheckBox( panel, -1, "Allow empty control" ) | |
63 | self.group_digits = wxCheckBox( panel, -1, "Group digits" ) | |
64 | self.group_digits.SetValue( True ) | |
65 | self.allow_negative = wxCheckBox( panel, -1, "Allow negative values" ) | |
66 | self.allow_negative.SetValue( True ) | |
67 | self.use_parens = wxCheckBox( panel, -1, "Use parentheses" ) | |
68 | self.select_on_entry = wxCheckBox( panel, -1, "Select on entry" ) | |
69 | self.select_on_entry.SetValue( True ) | |
70 | ||
71 | label = wxStaticText( panel, -1, "Resulting numeric control:" ) | |
72 | font = label.GetFont() | |
73 | font.SetWeight(wxBOLD) | |
74 | label.SetFont(font) | |
75 | ||
76 | self.target_ctl = wxMaskedNumCtrl( panel, -1, name="target control" ) | |
77 | ||
78 | label_numselect = wxStaticText( panel, -1, """\ | |
79 | Programmatically set the above | |
80 | value entry ctrl:""") | |
81 | self.numselect = wxComboBox(panel, -1, choices = [ '0', '111', '222.22', '-3', '54321.666666666', '-1353.978', | |
82 | '1234567', '-1234567', '123456789', '-123456789.1', | |
83 | '1234567890.', '-9876543210.9' ]) | |
84 | ||
85 | grid1 = wxFlexGridSizer( 0, 4, 0, 0 ) | |
86 | grid1.Add( intlabel, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5) | |
87 | grid1.Add( self.integerwidth, 0, wxALIGN_LEFT|wxALL, 5 ) | |
88 | ||
89 | grid1.Add( groupcharlabel, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5) | |
90 | grid1.Add( self.groupchar, 0, wxALIGN_LEFT|wxALL, 5 ) | |
91 | ||
92 | grid1.Add( fraclabel, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) | |
93 | grid1.Add( self.fractionwidth, 0, wxALIGN_LEFT|wxALL, 5 ) | |
94 | ||
95 | grid1.Add( decimalcharlabel, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5) | |
96 | grid1.Add( self.decimalchar, 0, wxALIGN_LEFT|wxALL, 5 ) | |
97 | ||
98 | grid1.Add( self.set_min, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) | |
99 | grid1.Add( self.min, 0, wxALIGN_LEFT|wxALL, 5 ) | |
100 | grid1.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
101 | grid1.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
102 | ||
103 | grid1.Add( self.set_max, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) | |
104 | grid1.Add( self.max, 0, wxALIGN_LEFT|wxALL, 5 ) | |
105 | grid1.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
106 | grid1.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
107 | ||
108 | ||
109 | grid1.Add( self.limit_target, 0, wxALIGN_LEFT|wxALL, 5 ) | |
110 | grid1.Add( self.allow_none, 0, wxALIGN_LEFT|wxALL, 5 ) | |
111 | hbox1 = wxBoxSizer( wxHORIZONTAL ) | |
112 | hbox1.Add( (17,5), 0, wxALIGN_LEFT|wxALL, 5) | |
113 | hbox1.Add( self.group_digits, 0, wxALIGN_LEFT|wxLEFT, 5 ) | |
114 | grid1.Add( hbox1, 0, wxALIGN_LEFT|wxALL, 5) | |
115 | grid1.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
116 | ||
117 | grid1.Add( self.allow_negative, 0, wxALIGN_LEFT|wxALL, 5 ) | |
118 | grid1.Add( self.use_parens, 0, wxALIGN_LEFT|wxALL, 5 ) | |
119 | hbox2 = wxBoxSizer( wxHORIZONTAL ) | |
120 | hbox2.Add( (17,5), 0, wxALIGN_LEFT|wxALL, 5) | |
121 | hbox2.Add( self.select_on_entry, 0, wxALIGN_LEFT|wxLEFT, 5 ) | |
122 | grid1.Add( hbox2, 0, wxALIGN_LEFT|wxALL, 5) | |
123 | grid1.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
124 | ||
125 | ||
126 | grid2 = wxFlexGridSizer( 0, 2, 0, 0 ) | |
127 | grid2.Add( label, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) | |
128 | grid2.Add( self.target_ctl, 0, wxALIGN_LEFT|wxALL, 5 ) | |
129 | grid2.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
130 | grid2.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
131 | grid2.Add( label_numselect, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) | |
132 | grid2.Add( self.numselect, 0, wxALIGN_LEFT|wxALL, 5 ) | |
133 | grid2.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
134 | grid2.Add( (5,5), 0, wxALIGN_LEFT|wxALL, 5) | |
135 | grid2.AddGrowableCol(1) | |
136 | ||
137 | self.outer_box = wxBoxSizer( wxVERTICAL ) | |
138 | self.outer_box.Add(header, 0, wxALIGN_LEFT|wxTOP|wxLEFT, 20) | |
139 | self.outer_box.Add( grid1, 0, wxALIGN_CENTRE|wxLEFT|wxBOTTOM|wxRIGHT, 20 ) | |
140 | self.outer_box.Add( grid2, 0, wxALIGN_LEFT|wxALL, 20 ) | |
141 | self.grid2 = grid2 | |
142 | ||
143 | panel.SetAutoLayout( True ) | |
144 | panel.SetSizer( self.outer_box ) | |
145 | self.outer_box.Fit( panel ) | |
146 | panel.Move( (50,10) ) | |
147 | self.panel = panel | |
148 | ||
149 | EVT_MASKEDNUM( self, self.integerwidth.GetId(), self.OnSetIntWidth ) | |
150 | EVT_MASKEDNUM( self, self.fractionwidth.GetId(), self.OnSetFractionWidth ) | |
151 | EVT_TEXT( self, self.groupchar.GetId(), self.OnSetGroupChar ) | |
152 | EVT_TEXT( self, self.decimalchar.GetId(), self.OnSetDecimalChar ) | |
153 | ||
154 | EVT_CHECKBOX( self, self.set_min.GetId(), self.OnSetMin ) | |
155 | EVT_CHECKBOX( self, self.set_max.GetId(), self.OnSetMax ) | |
156 | EVT_MASKEDNUM( self, self.min.GetId(), self.SetTargetMinMax ) | |
157 | EVT_MASKEDNUM( self, self.max.GetId(), self.SetTargetMinMax ) | |
158 | ||
159 | EVT_CHECKBOX( self, self.limit_target.GetId(), self.SetTargetMinMax ) | |
160 | EVT_CHECKBOX( self, self.allow_none.GetId(), self.OnSetAllowNone ) | |
161 | EVT_CHECKBOX( self, self.group_digits.GetId(), self.OnSetGroupDigits ) | |
162 | EVT_CHECKBOX( self, self.allow_negative.GetId(), self.OnSetAllowNegative ) | |
163 | EVT_CHECKBOX( self, self.use_parens.GetId(), self.OnSetUseParens ) | |
164 | EVT_CHECKBOX( self, self.select_on_entry.GetId(), self.OnSetSelectOnEntry ) | |
165 | ||
166 | EVT_MASKEDNUM( self, self.target_ctl.GetId(), self.OnTargetChange ) | |
167 | EVT_COMBOBOX( self, self.numselect.GetId(), self.OnNumberSelect ) | |
168 | ||
169 | ||
170 | def OnSetIntWidth(self, event ): | |
171 | width = self.integerwidth.GetValue() | |
172 | if width < 1: | |
173 | self.log.write("integer width must be positive\n") | |
174 | self.integerwidth.SetForegroundColour(wxRED) | |
175 | else: | |
176 | self.integerwidth.SetForegroundColour(wxBLACK) | |
177 | self.log.write("setting integer width to %d\n" % width) | |
178 | self.target_ctl.SetParameters( integerWidth = width) | |
179 | # Now resize and fit the dialog as appropriate: | |
180 | self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize()) | |
181 | self.outer_box.Fit( self.panel ) | |
182 | self.outer_box.SetSizeHints( self.panel ) | |
183 | ||
184 | ||
185 | def OnSetFractionWidth(self, event ): | |
186 | width = self.fractionwidth.GetValue() | |
187 | self.log.write("setting fraction width to %d\n" % width) | |
188 | self.target_ctl.SetParameters( fractionWidth = width) | |
189 | # Now resize and fit the dialog as appropriate: | |
190 | self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize()) | |
191 | self.outer_box.Fit( self.panel ) | |
192 | self.outer_box.SetSizeHints( self.panel ) | |
193 | ||
194 | ||
195 | def OnSetGroupChar( self, event ): | |
196 | char = self.groupchar.GetValue() | |
197 | if self.target_ctl.GetDecimalChar() == char: | |
198 | self.log.write("group and decimal chars must be different\n") | |
199 | self.groupchar.SetForegroundColour(wxRED) | |
200 | else: | |
201 | self.groupchar.SetForegroundColour(wxBLACK) | |
202 | self.log.write("setting group char to %s\n" % char) | |
203 | self.target_ctl.SetGroupChar( char ) | |
204 | ||
205 | def OnSetDecimalChar( self, event ): | |
206 | char = self.decimalchar.GetValue() | |
207 | if self.target_ctl.GetGroupChar() == char: | |
208 | self.log.write("group and decimal chars must be different\n") | |
209 | self.decimalchar.SetForegroundColour(wxRED) | |
210 | else: | |
211 | self.decimalchar.SetForegroundColour(wxBLACK) | |
212 | self.log.write("setting decimal char to %s\n" % char) | |
213 | self.target_ctl.SetDecimalChar( char ) | |
214 | ||
215 | ||
216 | def OnSetMin( self, event ): | |
217 | self.min.Enable( self.set_min.GetValue() ) | |
218 | self.SetTargetMinMax() | |
219 | ||
220 | def OnSetMax( self, event ): | |
221 | self.max.Enable( self.set_max.GetValue() ) | |
222 | self.SetTargetMinMax() | |
223 | ||
224 | ||
225 | def SetTargetMinMax( self, event=None ): | |
226 | min = max = None | |
227 | self.target_ctl.SetLimited( self.limit_target.GetValue() ) | |
228 | ||
229 | if self.set_min.GetValue(): | |
230 | min = self.min.GetValue() | |
231 | if self.set_max.GetValue(): | |
232 | max = self.max.GetValue() | |
233 | ||
234 | cur_min, cur_max = self.target_ctl.GetBounds() | |
235 | ||
236 | if min != cur_min and not self.target_ctl.SetMin( min ): | |
237 | if self.target_ctl.GetMax() is None and cur_max > min: | |
238 | self.log.write( "min (%d) won't fit in control -- bound not set\n" % min ) | |
239 | else: | |
240 | self.log.write( "min (%d) > current max (%d) -- bound not set\n" % ( min, self.target_ctl.GetMax() ) ) | |
241 | self.min.SetParameters( signedForegroundColour=wxRED, foregroundColour=wxRED ) | |
242 | else: | |
243 | self.min.SetParameters( signedForegroundColour=wxBLACK, foregroundColour=wxBLACK ) | |
244 | self.min.Refresh() | |
245 | ||
246 | if max != cur_max and not self.target_ctl.SetMax( max ): | |
247 | if self.target_ctl.GetMax() is None and cur_min < max: | |
248 | self.log.write( "max (%d) won't fit in control -- bound not set\n" % max ) | |
249 | else: | |
250 | self.log.write( "max (%d) < current min (%d) -- bound not set\n" % ( max, self.target_ctl.GetMin() ) ) | |
251 | self.max.SetParameters( signedForegroundColour=wxRED, foregroundColour=wxRED ) | |
252 | else: | |
253 | self.max.SetParameters( signedForegroundColour=wxBLACK, foregroundColour=wxBLACK ) | |
254 | self.max.Refresh() | |
255 | ||
256 | if min != cur_min or max != cur_max: | |
257 | new_min, new_max = self.target_ctl.GetBounds() | |
258 | self.log.write( "current min, max: (%s, %s)\n" % ( str(new_min), str(new_max) ) ) | |
259 | ||
260 | ||
261 | def OnSetAllowNone( self, event ): | |
262 | self.target_ctl.SetAllowNone( self.allow_none.GetValue() ) | |
263 | ||
264 | ||
265 | def OnSetGroupDigits( self, event ): | |
266 | self.target_ctl.SetGroupDigits( self.group_digits.GetValue() ) | |
267 | # Now resize and fit the dialog as appropriate: | |
268 | self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize()) | |
269 | self.outer_box.Fit( self.panel ) | |
270 | self.outer_box.SetSizeHints( self.panel ) | |
271 | ||
272 | ||
273 | def OnSetAllowNegative( self, event ): | |
274 | if self.allow_negative.GetValue(): | |
275 | self.use_parens.Enable(True) | |
276 | self.target_ctl.SetParameters(allowNegative=True, | |
277 | useParensForNegatives = self.use_parens.GetValue()) | |
278 | else: | |
279 | self.target_ctl.SetAllowNegative(False) | |
280 | # Now resize and fit the dialog as appropriate: | |
281 | self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize()) | |
282 | self.outer_box.Fit( self.panel ) | |
283 | self.outer_box.SetSizeHints( self.panel ) | |
284 | ||
285 | ||
286 | def OnSetUseParens( self, event ): | |
287 | self.target_ctl.SetUseParensForNegatives( self.use_parens.GetValue() ) | |
288 | # Now resize and fit the dialog as appropriate: | |
289 | self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize()) | |
290 | self.outer_box.Fit( self.panel ) | |
291 | self.outer_box.SetSizeHints( self.panel ) | |
292 | ||
293 | ||
294 | def OnSetSelectOnEntry( self, event ): | |
295 | self.target_ctl.SetSelectOnEntry( self.select_on_entry.GetValue() ) | |
296 | ||
297 | ||
298 | def OnTargetChange( self, event ): | |
299 | ctl = event.GetEventObject() | |
300 | value = ctl.GetValue() | |
301 | ib_str = [ " (out of bounds)", "" ] | |
302 | self.log.write( "value = %s (%s)%s\n" % ( repr(value), repr(type(value)), ib_str[ ctl.IsInBounds(value) ] ) ) | |
303 | ||
304 | ||
305 | def OnNumberSelect( self, event ): | |
306 | value = event.GetString() | |
307 | if value: | |
308 | if value.find('.') != -1: | |
309 | numvalue = float(value) | |
310 | else: | |
311 | numvalue = long(value) | |
312 | else: | |
313 | numvalue = value # try to clear the value again | |
314 | ||
315 | try: | |
316 | self.target_ctl.SetValue(numvalue) | |
317 | except: | |
318 | type, value, tb = sys.exc_info() | |
319 | for line in traceback.format_exception_only(type, value): | |
320 | self.log.write(line) | |
321 | ||
322 | ||
323 | #---------------------------------------------------------------------- | |
324 | ||
325 | def runTest( frame, nb, log ): | |
326 | win = TestPanel( nb, log ) | |
327 | return win | |
328 | ||
329 | #---------------------------------------------------------------------- | |
330 | overview = overviewdoc | |
331 | ||
332 | if __name__ == '__main__': | |
333 | import sys,os | |
334 | import run | |
335 | run.main(['', os.path.basename(sys.argv[0])]) |