+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// System.Windows.Forms.NumericUpDown.cs
+// Copyright (c) 2005 Novell, Inc.
//
-// Author:
-// stubbed out by Paul Osman (paul.osman@sympatico.ca)
-// Dennis Hayes (dennish@raytek.com)
-// Alexandre Pigolkine (pigolkine@gxm.de)
+// Authors:
+// Jonathan Gilbert <logic@deltaq.org>
//
-// (C) 2002 Ximian, Inc
+// Integration into MWF:
+// Peter Bartok <pbartok@novell.com>
//
+
+using System;
+using System.Collections;
using System.ComponentModel;
+using System.Drawing;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Windows.Forms;
+
namespace System.Windows.Forms {
+ [DefaultEvent("ValueChanged")]
+ [DefaultProperty("Value")]
+ [DefaultBindingProperty ("Value")]
+ [ClassInterface (ClassInterfaceType.AutoDispatch)]
+ [ComVisible (true)]
+ public class NumericUpDown : UpDownBase, ISupportInitialize {
+ #region Local Variables
+ private bool suppress_validation;
+ private int decimal_places;
+ private bool hexadecimal;
+ private decimal increment;
+ private decimal maximum;
+ private decimal minimum;
+ private bool thousands_separator;
+ private decimal dvalue;
+
+
+ NumericUpDownAccelerationCollection accelerations;
+// private long buttonPressedTicks;
+ //private bool isSpinning;
+ #endregion // Local Variables
+
+ #region UIA FrameWork Events
+ static object UIAMinimumChangedEvent = new object ();
+
+ internal event EventHandler UIAMinimumChanged {
+ add { Events.AddHandler (UIAMinimumChangedEvent, value); }
+ remove { Events.RemoveHandler (UIAMinimumChangedEvent, value); }
+ }
- // <summary>
- //
- // </summary>
-
- public class NumericUpDown : UpDownBase, ISupportInitialize {
-
- private decimal Value_ = 0;
- private int DecimalPlaces_;
- private bool Hexadecimal_ = false;
- private decimal Increment_ = 1;
- private decimal Maximum_ = 100;
- private decimal Minimum_ = 0;
- //
- // --- Constructor
- //
- [MonoTODO]
- public NumericUpDown()
+ internal void OnUIAMinimumChanged (EventArgs e)
{
-
+ EventHandler eh = (EventHandler) Events [UIAMinimumChangedEvent];
+ if (eh != null)
+ eh (this, e);
}
- public override void DownButton(){
- if( Value_ > Minimum_) {
- Value = Math.Max(Value_ - Increment_, Minimum_);
- }
+ static object UIAMaximumChangedEvent = new object ();
+
+ internal event EventHandler UIAMaximumChanged {
+ add { Events.AddHandler (UIAMaximumChangedEvent, value); }
+ remove { Events.RemoveHandler (UIAMaximumChangedEvent, value); }
+ }
+
+ internal void OnUIAMaximumChanged (EventArgs e)
+ {
+ EventHandler eh = (EventHandler) Events [UIAMaximumChangedEvent];
+ if (eh != null)
+ eh (this, e);
}
- //
- // --- Public Properties
- //
+ static object UIASmallChangeChangedEvent = new object ();
+
+ internal event EventHandler UIASmallChangeChanged {
+ add { Events.AddHandler (UIASmallChangeChangedEvent, value); }
+ remove { Events.RemoveHandler (UIASmallChangeChangedEvent, value); }
+ }
+
+ internal void OnUIASmallChangeChanged (EventArgs e)
+ {
+ EventHandler eh = (EventHandler) Events [UIASmallChangeChangedEvent];
+ if (eh != null)
+ eh (this, e);
+ }
+ #endregion
+
+ #region Public Constructors
+ public NumericUpDown() {
+ suppress_validation = false;
+ decimal_places = 0;
+ hexadecimal = false;
+ increment = 1M;
+ maximum = 100M;
+ minimum = 0M;
+ thousands_separator = false;
+
+ Text = "0";
+ }
+ #endregion // Public Constructors
+
+ #region Public Instance Properties
+
+ [Browsable (false)]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ public NumericUpDownAccelerationCollection Accelerations {
+ get {
+ if (accelerations == null)
+ accelerations = new NumericUpDownAccelerationCollection ();
+ return accelerations;
+ }
+ }
- [MonoTODO]
- public int DecimalPlaces {
+ [DefaultValue(0)]
+ public int DecimalPlaces {
get {
- return DecimalPlaces_;
+ return decimal_places;
}
+
set {
- //FIXME:
- DecimalPlaces_ = value;
+ decimal_places = value;
+ UpdateEditText();
}
}
- [MonoTODO]
- public bool Hexadecimal {
+ [DefaultValue(false)]
+ public bool Hexadecimal {
get {
- return Hexadecimal_;
+ return hexadecimal;
}
+
set {
- //FIXME:
- Hexadecimal_ = value;
+ hexadecimal = value;
+ UpdateEditText();
}
}
public decimal Increment {
get {
- return Increment_;
- }
+
+ return increment;
+ }
+
set {
- Increment_ = value;
+ if (value < 0) {
+ throw new ArgumentOutOfRangeException("value", value, "NumericUpDown increment cannot be negative");
+ }
+
+ increment = value;
+
+ // UIA Framework Event: SmallChange Changed
+ OnUIASmallChangeChanged (EventArgs.Empty);
}
}
-
- [MonoTODO]
- public decimal Maximum {
+
+ [RefreshProperties(RefreshProperties.All)]
+ public decimal Maximum {
get {
- return Maximum_;
+ return maximum;
}
+
set {
- //FIXME:
- if( Maximum_ != value) {
- Maximum_ = value;
- Minimum = Math.Min(Maximum_,Minimum_);
- Value = Math.Min(Value_,Minimum_);
- }
+ maximum = value;
+
+ if (minimum > maximum)
+ minimum = maximum;
+
+ if (dvalue > maximum)
+ Value = maximum;
+
+ // UIA Framework Event: Maximum Changed
+ OnUIAMaximumChanged (EventArgs.Empty);
}
}
- [MonoTODO]
- public decimal Minimum {
+ [RefreshProperties(RefreshProperties.All)]
+ public decimal Minimum {
get {
- return Minimum_;
+ return minimum;
}
+
set {
- //FIXME:
- if( Minimum_ != value) {
- Minimum_ = value;
- Maximum = Math.Max(Maximum_,Minimum_);
- Value = Math.Max(Value_,Minimum_);
- }
+ minimum = value;
+
+ if (maximum < minimum)
+ maximum = minimum;
+
+ if (dvalue < minimum)
+ Value = minimum;
+
+ // UIA Framework Event: Minimum Changed
+ OnUIAMinimumChanged (EventArgs.Empty);
}
}
- [MonoTODO]
- public override string Text {
- //FIXME: just to get it to run
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ public new Padding Padding {
+ get { return Padding.Empty; }
+ set { }
+ }
+
+ [Bindable(false)]
+ [Browsable(false)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override string Text {
get {
- return Value_.ToString();
+ return base.Text;
}
+
set {
- Value = Decimal.Parse(value);
+ base.Text = value;
}
}
- [MonoTODO]
- public bool ThousandsSeparator {
+ [DefaultValue(false)]
+ [Localizable(true)]
+ public bool ThousandsSeparator {
get {
- throw new NotImplementedException ();
+ return thousands_separator;
}
+
set {
- //FIXME:
+ thousands_separator = value;
+ UpdateEditText();
}
}
- [MonoTODO]
- public decimal Value {
+ [Bindable(true)]
+ public decimal Value {
get {
- return Value_;
+ if (UserEdit)
+ ValidateEditText ();
+ return dvalue;
}
+
set {
- //FIXME:
- if( Value_ != value) {
- Value_ = value;
- UpdateEditText();
+ if (value != dvalue) {
+ if (!suppress_validation && ((value < minimum) || (value > maximum))) {
+ throw new ArgumentOutOfRangeException ("value", "NumericUpDown.Value must be within the specified Minimum and Maximum values");
+ }
+
+ dvalue = value;
+ OnValueChanged (EventArgs.Empty);
+ UpdateEditText ();
}
}
}
+ #endregion // Public Instance Properties
- //
- // --- Public Methods
- //
+ #region Public Instance Methods
+ public void BeginInit() {
+ suppress_validation = true;
+ }
- [MonoTODO]
- public override string ToString()
- {
- //FIXME:
- return base.ToString();
+ public void EndInit() {
+ suppress_validation = false;
+ Value = Check (dvalue);
+ UpdateEditText ();
}
- [MonoTODO]
- public override void UpButton()
- {
- if( Value_ != Maximum_) {
- Value = Math.Min(Value_ + Increment_, Maximum_);
+ public override string ToString() {
+ return string.Format("{0}, Minimum = {1}, Maximum = {2}", base.ToString(), minimum, maximum);
+ }
+
+ public override void DownButton() {
+ if (UserEdit) {
+ ParseEditText ();
}
+
+ Value = Math.Max (minimum, unchecked (dvalue - increment));
+
+ // UIA Framework Event: DownButton Click
+ OnUIADownButtonClick (EventArgs.Empty);
}
- //
- // --- Public Events
- //
+ public override void UpButton() {
+ if (UserEdit) {
+ ParseEditText ();
+ }
- public event EventHandler ValueChanged;
+ Value = Math.Min (maximum, unchecked (dvalue + increment));
- //
- // --- Protected Methods
- //
- [MonoTODO]
- protected override AccessibleObject CreateAccessibilityInstance()
- {
- //FIXME:
- return base.CreateAccessibilityInstance();
+ // UIA Framework Event: UpButton Click
+ OnUIAUpButtonClick (EventArgs.Empty);
}
+ #endregion // Public Instance Methods
+
+ #region Protected Instance Methods
+ protected override AccessibleObject CreateAccessibilityInstance() {
+ AccessibleObject acc;
+
+ acc = new AccessibleObject(this);
+ acc.role = AccessibleRole.SpinButton;
+
+ return acc;
+ }
+
+ protected override void OnTextBoxKeyPress(object source, KeyPressEventArgs e) {
+ if ((ModifierKeys & ~Keys.Shift) != Keys.None) {
+ return;
+ }
+
+ NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
+ string pressedKey = e.KeyChar.ToString ();
+
+ if ((pressedKey != nfi.NegativeSign) && (pressedKey != nfi.NumberDecimalSeparator) &&
+ (pressedKey != nfi.NumberGroupSeparator)) {
+ string acceptable = hexadecimal ? "\b0123456789abcdefABCDEF" : "\b0123456789";
+ if (acceptable.IndexOf (e.KeyChar) == -1) {
+ // FIXME: produce beep to signal that "invalid" key was pressed
+ // prevent the key from reaching the text box
+ e.Handled = true;
+ }
+ }
- [MonoTODO]
- protected override void OnTextBoxKeyPress(object source, KeyPressEventArgs e)
- {
- //FIXME:
base.OnTextBoxKeyPress(source, e);
}
- [MonoTODO]
- protected virtual void OnValueChanged(EventArgs e)
- {
- //FIXME:
+ protected virtual void OnValueChanged(EventArgs e) {
+ EventHandler eh = (EventHandler)(Events [ValueChangedEvent]);
+ if (eh != null)
+ eh (this, e);
}
- [MonoTODO]
- protected void ParseEditText()
+ protected void ParseEditText () {
+ try {
+ if (!hexadecimal) {
+ Value = Check (decimal.Parse (Text, CultureInfo.CurrentCulture));
+ } else {
+ Value = Check (Convert.ToDecimal (Convert.ToInt32 (Text, 16)));
+ }
+ }
+ catch { }
+ finally {
+ UserEdit = false;
+ }
+ }
+
+ private decimal Check (decimal val)
{
- //FIXME:
+ decimal ret = val;
+ if (ret < minimum) {
+ ret = minimum;
+ }
+
+ if (ret > maximum) {
+ ret = maximum;
+ }
+
+ return ret;
+ }
+
+ protected override void UpdateEditText () {
+ if (suppress_validation)
+ return;
+
+ if (UserEdit)
+ ParseEditText ();
+
+ ChangingText = true;
+ if (!hexadecimal) {
+ // "N" and "F" differ only in that "N" includes commas
+ // every 3 digits to the left of the decimal and "F"
+ // does not.
+
+ string format_string;
+
+ if (thousands_separator) {
+ format_string = "N";
+ } else {
+ format_string = "F";
+ }
+
+ format_string += decimal_places;
+
+ Text = dvalue.ToString (format_string, CultureInfo.CurrentCulture);
+
+ } else {
+ // Cast to Int64 to be able to use the "X" formatter.
+ // If the value is below Int64.MinValue or above Int64.MaxValue,
+ // then an OverflowException will be thrown, as with .NET.
+ Text = ((Int64)dvalue).ToString("X", CultureInfo.CurrentCulture);
+ }
+ }
+
+
+ protected override void ValidateEditText() {
+ ParseEditText ();
+ UpdateEditText ();
+ }
+
+ protected override void OnLostFocus(EventArgs e) {
+ base.OnLostFocus(e);
+ if (UserEdit)
+ UpdateEditText();
}
- [MonoTODO]
- protected override void UpdateEditText()
+ protected override void OnKeyUp (KeyEventArgs e)
{
- //FIXME:
- base.Text = Value_.ToString();
+// isSpinning = false;
+ base.OnKeyUp (e);
}
- [MonoTODO]
- protected override void ValidateEditText()
+ protected override void OnKeyDown (KeyEventArgs e)
{
- //FIXME:
- base.ValidateEditText();
+// buttonPressedTicks = DateTime.Now.Ticks;
+// isSpinning = true;
+ base.OnKeyDown (e);
}
+ #endregion // Protected Instance Methods
- void ISupportInitialize.BeginInit(){
- //FIXME:
+ #region Events
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+ public new event EventHandler PaddingChanged {
+ add { base.PaddingChanged += value; }
+ remove { base.PaddingChanged -= value; }
}
- void ISupportInitialize.EndInit(){
- //FIXME:
+ static object ValueChangedEvent = new object ();
+
+ public event EventHandler ValueChanged {
+ add { Events.AddHandler (ValueChangedEvent, value); }
+ remove { Events.RemoveHandler (ValueChangedEvent, value); }
}
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public new event EventHandler TextChanged {
+ add { base.TextChanged += value; }
+ remove { base.TextChanged -= value; }
+ }
+ #endregion // Events
}
}