[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / NumericUpDown.cs
blob856137cb17e051cd2f72513bbc16b7ea7c2ea4ac
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc.
22 // Authors:
23 // Jonathan Gilbert <logic@deltaq.org>
25 // Integration into MWF:
26 // Peter Bartok <pbartok@novell.com>
29 using System;
30 using System.Collections;
31 using System.ComponentModel;
32 using System.Drawing;
33 using System.Globalization;
34 using System.Runtime.InteropServices;
35 using System.Text;
36 using System.Windows.Forms;
38 namespace System.Windows.Forms {
39 [DefaultEvent("ValueChanged")]
40 [DefaultProperty("Value")]
41 [DefaultBindingProperty ("Value")]
42 [ClassInterface (ClassInterfaceType.AutoDispatch)]
43 [ComVisible (true)]
44 public class NumericUpDown : UpDownBase, ISupportInitialize {
45 #region Local Variables
46 private bool suppress_validation;
47 private int decimal_places;
48 private bool hexadecimal;
49 private decimal increment;
50 private decimal maximum;
51 private decimal minimum;
52 private bool thousands_separator;
53 private decimal dvalue;
56 NumericUpDownAccelerationCollection accelerations;
57 // private long buttonPressedTicks;
58 //private bool isSpinning;
59 #endregion // Local Variables
61 #region UIA FrameWork Events
62 static object UIAMinimumChangedEvent = new object ();
64 internal event EventHandler UIAMinimumChanged {
65 add { Events.AddHandler (UIAMinimumChangedEvent, value); }
66 remove { Events.RemoveHandler (UIAMinimumChangedEvent, value); }
69 internal void OnUIAMinimumChanged (EventArgs e)
71 EventHandler eh = (EventHandler) Events [UIAMinimumChangedEvent];
72 if (eh != null)
73 eh (this, e);
76 static object UIAMaximumChangedEvent = new object ();
78 internal event EventHandler UIAMaximumChanged {
79 add { Events.AddHandler (UIAMaximumChangedEvent, value); }
80 remove { Events.RemoveHandler (UIAMaximumChangedEvent, value); }
83 internal void OnUIAMaximumChanged (EventArgs e)
85 EventHandler eh = (EventHandler) Events [UIAMaximumChangedEvent];
86 if (eh != null)
87 eh (this, e);
90 static object UIASmallChangeChangedEvent = new object ();
92 internal event EventHandler UIASmallChangeChanged {
93 add { Events.AddHandler (UIASmallChangeChangedEvent, value); }
94 remove { Events.RemoveHandler (UIASmallChangeChangedEvent, value); }
97 internal void OnUIASmallChangeChanged (EventArgs e)
99 EventHandler eh = (EventHandler) Events [UIASmallChangeChangedEvent];
100 if (eh != null)
101 eh (this, e);
103 #endregion
105 #region Public Constructors
106 public NumericUpDown() {
107 suppress_validation = false;
108 decimal_places = 0;
109 hexadecimal = false;
110 increment = 1M;
111 maximum = 100M;
112 minimum = 0M;
113 thousands_separator = false;
115 Text = "0";
117 #endregion // Public Constructors
119 #region Public Instance Properties
121 [Browsable (false)]
122 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
123 public NumericUpDownAccelerationCollection Accelerations {
124 get {
125 if (accelerations == null)
126 accelerations = new NumericUpDownAccelerationCollection ();
127 return accelerations;
131 [DefaultValue(0)]
132 public int DecimalPlaces {
133 get {
134 return decimal_places;
137 set {
138 decimal_places = value;
139 UpdateEditText();
143 [DefaultValue(false)]
144 public bool Hexadecimal {
145 get {
146 return hexadecimal;
149 set {
150 hexadecimal = value;
151 UpdateEditText();
155 public decimal Increment {
156 get {
158 return increment;
161 set {
162 if (value < 0) {
163 throw new ArgumentOutOfRangeException("value", value, "NumericUpDown increment cannot be negative");
166 increment = value;
168 // UIA Framework Event: SmallChange Changed
169 OnUIASmallChangeChanged (EventArgs.Empty);
173 [RefreshProperties(RefreshProperties.All)]
174 public decimal Maximum {
175 get {
176 return maximum;
179 set {
180 maximum = value;
182 if (minimum > maximum)
183 minimum = maximum;
185 if (dvalue > maximum)
186 Value = maximum;
188 // UIA Framework Event: Maximum Changed
189 OnUIAMaximumChanged (EventArgs.Empty);
193 [RefreshProperties(RefreshProperties.All)]
194 public decimal Minimum {
195 get {
196 return minimum;
199 set {
200 minimum = value;
202 if (maximum < minimum)
203 maximum = minimum;
205 if (dvalue < minimum)
206 Value = minimum;
208 // UIA Framework Event: Minimum Changed
209 OnUIAMinimumChanged (EventArgs.Empty);
213 [Browsable (false)]
214 [EditorBrowsable (EditorBrowsableState.Never)]
215 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
216 public new Padding Padding {
217 get { return Padding.Empty; }
218 set { }
221 [Bindable(false)]
222 [Browsable(false)]
223 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
224 [EditorBrowsable(EditorBrowsableState.Never)]
225 public override string Text {
226 get {
227 return base.Text;
230 set {
231 base.Text = value;
235 [DefaultValue(false)]
236 [Localizable(true)]
237 public bool ThousandsSeparator {
238 get {
239 return thousands_separator;
242 set {
243 thousands_separator = value;
244 UpdateEditText();
248 [Bindable(true)]
249 public decimal Value {
250 get {
251 if (UserEdit)
252 ValidateEditText ();
253 return dvalue;
256 set {
257 if (value != dvalue) {
258 if (!suppress_validation && ((value < minimum) || (value > maximum))) {
259 throw new ArgumentOutOfRangeException ("value", "NumericUpDown.Value must be within the specified Minimum and Maximum values");
262 dvalue = value;
263 OnValueChanged (EventArgs.Empty);
264 UpdateEditText ();
268 #endregion // Public Instance Properties
270 #region Public Instance Methods
271 public void BeginInit() {
272 suppress_validation = true;
275 public void EndInit() {
276 suppress_validation = false;
277 Value = Check (dvalue);
278 UpdateEditText ();
281 public override string ToString() {
282 return string.Format("{0}, Minimum = {1}, Maximum = {2}", base.ToString(), minimum, maximum);
285 public override void DownButton() {
286 if (UserEdit) {
287 ParseEditText ();
290 Value = Math.Max (minimum, unchecked (dvalue - increment));
292 // UIA Framework Event: DownButton Click
293 OnUIADownButtonClick (EventArgs.Empty);
296 public override void UpButton() {
297 if (UserEdit) {
298 ParseEditText ();
301 Value = Math.Min (maximum, unchecked (dvalue + increment));
303 // UIA Framework Event: UpButton Click
304 OnUIAUpButtonClick (EventArgs.Empty);
306 #endregion // Public Instance Methods
308 #region Protected Instance Methods
309 protected override AccessibleObject CreateAccessibilityInstance() {
310 AccessibleObject acc;
312 acc = new AccessibleObject(this);
313 acc.role = AccessibleRole.SpinButton;
315 return acc;
318 protected override void OnTextBoxKeyPress(object source, KeyPressEventArgs e) {
319 if ((ModifierKeys & ~Keys.Shift) != Keys.None) {
320 return;
323 NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
324 string pressedKey = e.KeyChar.ToString ();
326 if ((pressedKey != nfi.NegativeSign) && (pressedKey != nfi.NumberDecimalSeparator) &&
327 (pressedKey != nfi.NumberGroupSeparator)) {
328 string acceptable = hexadecimal ? "\b0123456789abcdefABCDEF" : "\b0123456789";
329 if (acceptable.IndexOf (e.KeyChar) == -1) {
330 // FIXME: produce beep to signal that "invalid" key was pressed
331 // prevent the key from reaching the text box
332 e.Handled = true;
336 base.OnTextBoxKeyPress(source, e);
339 protected virtual void OnValueChanged(EventArgs e) {
340 EventHandler eh = (EventHandler)(Events [ValueChangedEvent]);
341 if (eh != null)
342 eh (this, e);
345 protected void ParseEditText () {
346 try {
347 if (!hexadecimal) {
348 Value = Check (decimal.Parse (Text, CultureInfo.CurrentCulture));
349 } else {
350 Value = Check (Convert.ToDecimal (Convert.ToInt32 (Text, 16)));
353 catch { }
354 finally {
355 UserEdit = false;
359 private decimal Check (decimal val)
361 decimal ret = val;
362 if (ret < minimum) {
363 ret = minimum;
366 if (ret > maximum) {
367 ret = maximum;
370 return ret;
373 protected override void UpdateEditText () {
374 if (suppress_validation)
375 return;
377 if (UserEdit)
378 ParseEditText ();
380 ChangingText = true;
381 if (!hexadecimal) {
382 // "N" and "F" differ only in that "N" includes commas
383 // every 3 digits to the left of the decimal and "F"
384 // does not.
386 string format_string;
388 if (thousands_separator) {
389 format_string = "N";
390 } else {
391 format_string = "F";
394 format_string += decimal_places;
396 Text = dvalue.ToString (format_string, CultureInfo.CurrentCulture);
398 } else {
399 // Cast to Int64 to be able to use the "X" formatter.
400 // If the value is below Int64.MinValue or above Int64.MaxValue,
401 // then an OverflowException will be thrown, as with .NET.
402 Text = ((Int64)dvalue).ToString("X", CultureInfo.CurrentCulture);
407 protected override void ValidateEditText() {
408 ParseEditText ();
409 UpdateEditText ();
412 protected override void OnLostFocus(EventArgs e) {
413 base.OnLostFocus(e);
414 if (UserEdit)
415 UpdateEditText();
418 protected override void OnKeyUp (KeyEventArgs e)
420 // isSpinning = false;
421 base.OnKeyUp (e);
424 protected override void OnKeyDown (KeyEventArgs e)
426 // buttonPressedTicks = DateTime.Now.Ticks;
427 // isSpinning = true;
428 base.OnKeyDown (e);
430 #endregion // Protected Instance Methods
432 #region Events
433 [Browsable (false)]
434 [EditorBrowsable (EditorBrowsableState.Never)]
435 public new event EventHandler PaddingChanged {
436 add { base.PaddingChanged += value; }
437 remove { base.PaddingChanged -= value; }
440 static object ValueChangedEvent = new object ();
442 public event EventHandler ValueChanged {
443 add { Events.AddHandler (ValueChangedEvent, value); }
444 remove { Events.RemoveHandler (ValueChangedEvent, value); }
447 [Browsable(false)]
448 [EditorBrowsable(EditorBrowsableState.Never)]
449 public new event EventHandler TextChanged {
450 add { base.TextChanged += value; }
451 remove { base.TextChanged -= value; }
453 #endregion // Events