X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Windows.Forms%2FSystem.Windows.Forms%2FRadioButton.cs;h=4290a1e262057ce0120f4efa20f4bb4f83e10af1;hb=bb4b0ff4fc2877a3fd5d784348368ec832fb82c7;hp=36ed2692fd1b64fe13d36795fb981be31708e383;hpb=242d710a1e316d12758cde47345a9b85f31f8ab5;p=mono.git diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/RadioButton.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/RadioButton.cs index 36ed2692fd1..4290a1e2620 100644 --- a/mcs/class/System.Windows.Forms/System.Windows.Forms/RadioButton.cs +++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/RadioButton.cs @@ -1,213 +1,389 @@ +// 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.RadioButton.cs +// Copyright (c) 2004-2005 Novell, Inc. // -// Author: -// stubbed out by Daniel Carrera (dcarrera@math.toronto.edu) -// Dennis Hayes (dennish@raytek.com) -// implemented by Aleksey Ryabchuk (ryabchuk@yahoo.com) -// (C) 2002/3 Ximian, Inc +// Authors: +// Peter Bartok pbartok@novell.com // -using System.Drawing; + using System.ComponentModel; +using System.Drawing; +using System.Drawing.Text; +using System.Runtime.InteropServices; namespace System.Windows.Forms { + [DefaultProperty("Checked")] + [DefaultEvent("CheckedChanged")] + [ClassInterface (ClassInterfaceType.AutoDispatch)] + [ComVisible (true)] + [DefaultBindingProperty ("Checked")] + [ToolboxItem ("System.Windows.Forms.Design.AutoSizeToolboxItem," + Consts.AssemblySystem_Design)] + [Designer ("System.Windows.Forms.Design.RadioButtonDesigner, " + Consts.AssemblySystem_Design)] + public class RadioButton : ButtonBase { + #region Local Variables + internal Appearance appearance; + internal bool auto_check; + internal ContentAlignment radiobutton_alignment; + internal CheckState check_state; + #endregion // Local Variables + + #region RadioButtonAccessibleObject Subclass + [ComVisible(true)] + public class RadioButtonAccessibleObject : ButtonBaseAccessibleObject { + #region RadioButtonAccessibleObject Local Variables + private new RadioButton owner; + #endregion // RadioButtonAccessibleObject Local Variables + + #region RadioButtonAccessibleObject Constructors + public RadioButtonAccessibleObject(RadioButton owner) : base(owner) { + this.owner = owner; + } + #endregion // RadioButtonAccessibleObject Constructors + + #region RadioButtonAccessibleObject Properties + public override string DefaultAction { + get { + return "Select"; + } + } + + public override AccessibleRole Role { + get { + return AccessibleRole.RadioButton; + } + } - // - // Represents a Windows radio button - // + public override AccessibleStates State { + get { + AccessibleStates retval; - public class RadioButton : ButtonBase { + retval = AccessibleStates.Default; - Appearance appearance; - bool autoCheck; - ContentAlignment checkAlign; - bool checked_; + if (owner.check_state == CheckState.Checked) { + retval |= AccessibleStates.Checked; + } - public RadioButton() - { + if (owner.Focused) { + retval |= AccessibleStates.Focused; + } + + if (owner.CanFocus) { + retval |= AccessibleStates.Focusable; + } + + return retval; + } + } + #endregion // RadioButtonAccessibleObject Properties + + #region RadioButtonAccessibleObject Methods + public override void DoDefaultAction() { + owner.PerformClick(); + } + #endregion // RadioButtonAccessibleObject Methods + } + #endregion // RadioButtonAccessibleObject Sub-class + + #region Public Constructors + public RadioButton() { appearance = Appearance.Normal; - autoCheck = true; - checkAlign = ContentAlignment.MiddleLeft; - checked_ = false; + auto_check = true; + radiobutton_alignment = ContentAlignment.MiddleLeft; + TextAlign = ContentAlignment.MiddleLeft; + TabStop = false; } + #endregion // Public Constructors + + #region Private Methods + + // When getting OnEnter we need to set Checked as true in case none of the sibling radio + // buttons is checked. + private void PerformDefaultCheck () + { + // if we are already checked, no need to check the other controls + if (!auto_check || Checked) + return; + + bool is_any_selected = false; + Control c = Parent; + if (c != null) { + for (int i = 0; i < c.Controls.Count; i++) { + RadioButton rb = c.Controls [i] as RadioButton; + if (rb == null || !rb.auto_check) + continue; + + if (rb.check_state == CheckState.Checked) { + is_any_selected = true; + break; + } + } + } + if (!is_any_selected) + Checked = true; + } + + private void UpdateSiblings() { + Control c; + + if (auto_check == false) { + return; + } + + // Remove tabstop property from and uncheck our radio-button siblings + c = this.Parent; + if (c != null) { + for (int i = 0; i < c.Controls.Count; i++) { + if ((this != c.Controls[i]) && (c.Controls[i] is RadioButton)) { + if (((RadioButton)(c.Controls[i])).auto_check) { + c.Controls[i].TabStop = false; + ((RadioButton)(c.Controls[i])).Checked = false; + } + } + } + } + + this.TabStop = true; + } + + internal override void Draw (PaintEventArgs pe) { + // FIXME: This should be called every time something that can affect it + // is changed, not every paint. Can only change so many things at a time. + + // Figure out where our text and image should go + Rectangle glyph_rectangle; + Rectangle text_rectangle; + Rectangle image_rectangle; + + ThemeEngine.Current.CalculateRadioButtonTextAndImageLayout (this, Point.Empty, out glyph_rectangle, out text_rectangle, out image_rectangle); + + // Draw our button + if (FlatStyle != FlatStyle.System && Appearance != Appearance.Button) + ThemeEngine.Current.DrawRadioButton (pe.Graphics, this, glyph_rectangle, text_rectangle, image_rectangle, pe.ClipRectangle); + else + ThemeEngine.Current.DrawRadioButton (pe.Graphics, this.ClientRectangle, this); + } + + internal override Size GetPreferredSizeCore (Size proposedSize) + { + if (this.AutoSize) + return ThemeEngine.Current.CalculateRadioButtonAutoSize (this); + + return base.GetPreferredSizeCore (proposedSize); + } + #endregion // Private Methods + + #region Public Instance Properties + [DefaultValue(Appearance.Normal)] + [Localizable(true)] public Appearance Appearance { - get { return appearance; } - set { - if ( !Enum.IsDefined ( typeof(Appearance), value ) ) - throw new InvalidEnumArgumentException( "Appearance", - (int)value, - typeof(Appearance)); + get { + return appearance; + } - if ( appearance != value ) { - int oldStyle = AppearanceStyle; + set { + if (value != appearance) { appearance = value; - - if ( IsHandleCreated ) - Win32.UpdateWindowStyle ( Handle, oldStyle, AppearanceStyle ); - - if ( AppearanceChanged != null ) - AppearanceChanged ( this, EventArgs.Empty ); + EventHandler eh = (EventHandler)(Events [AppearanceChangedEvent]); + if (eh != null) + eh (this, EventArgs.Empty); + if (Parent != null) + Parent.PerformLayout (this, "Appearance"); + Invalidate(); } } } + [DefaultValue(true)] public bool AutoCheck { - get { return autoCheck; } - set { - if ( autoCheck != value ) { - int oldStyle = AutoCheckStyle; - autoCheck = value; + get { + return auto_check; + } - if ( IsHandleCreated ) - Win32.UpdateWindowStyle ( Handle, oldStyle, AutoCheckStyle ); - } + set { + auto_check = value; } } - [MonoTODO] + [Localizable(true)] + [DefaultValue(ContentAlignment.MiddleLeft)] public ContentAlignment CheckAlign { - get { return checkAlign; } + get { + return radiobutton_alignment; + } + set { - if ( !Enum.IsDefined ( typeof(ContentAlignment), value ) ) - throw new InvalidEnumArgumentException( "CheckAlign", - (int)value, - typeof(Appearance)); + if (value != radiobutton_alignment) { + radiobutton_alignment = value; - if ( checkAlign != value ) { - checkAlign = value; + Invalidate(); } } } + [DefaultValue(false)] + [SettingsBindable (true)] + [Bindable (true, BindingDirection.OneWay)] public bool Checked { - get { return checked_; } - set { - if ( checked_ != value ) { - checked_ = value; - - updateCheck ( ); - OnCheckedChanged ( EventArgs.Empty ); + get { + if (check_state != CheckState.Unchecked) { + return true; } + return false; } - } - [MonoTODO] - public override ContentAlignment TextAlign { - get { return base.TextAlign; } - set { base.TextAlign = value; } + set { + if (value && (check_state != CheckState.Checked)) { + check_state = CheckState.Checked; + Invalidate(); + UpdateSiblings(); + OnCheckedChanged(EventArgs.Empty); + } else if (!value && (check_state != CheckState.Unchecked)) { + TabStop = false; + check_state = CheckState.Unchecked; + Invalidate(); + OnCheckedChanged(EventArgs.Empty); + } + } } - public void PerformClick() - { - Checked = !Checked; - OnClick ( EventArgs.Empty ); + [DefaultValue(false)] + public new bool TabStop { + get { return base.TabStop; } + set { base.TabStop = value; } } - public override string ToString() - { - return GetType().FullName.ToString () + ", Checked: " + Checked.ToString ( ); + [DefaultValue(ContentAlignment.MiddleLeft)] + [Localizable(true)] + public override ContentAlignment TextAlign { + get { return base.TextAlign; } + set { base.TextAlign = value; } } + #endregion // Public Instance Properties - public event EventHandler AppearanceChanged; - public event EventHandler CheckedChanged; - - [MonoTODO] + #region Protected Instance Properties protected override CreateParams CreateParams { get { - CreateParams createParams = base.CreateParams; - - createParams.ClassName = "BUTTON"; - - createParams.Style = (int) ( - (int)WindowStyles.WS_CHILD | - (int)WindowStyles.WS_VISIBLE ); - - createParams.Style |= AutoCheckStyle | AppearanceStyle; - createParams.Style |= (int)Win32.ContentAlignment2SystemButtonStyle( TextAlign ); + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + SetStyle(ControlStyles.UserPaint, true); - return createParams; + return base.CreateParams; } } - protected override ImeMode DefaultImeMode { - get { return ImeMode.Disable; } - } - protected override Size DefaultSize { - get { return new Size(104,24); } + get { + return ThemeEngine.Current.RadioButtonDefaultSize; + } } + #endregion // Protected Instance Properties - [MonoTODO] - protected override AccessibleObject CreateAccessibilityInstance() - { - throw new NotImplementedException (); + #region Public Instance Methods + public void PerformClick() { + OnClick(EventArgs.Empty); } - protected virtual void OnCheckedChanged(EventArgs e) - { - if ( CheckedChanged != null ) - CheckedChanged ( this, e ); + public override string ToString() { + return base.ToString() + ", Checked: " + this.Checked; } + #endregion // Public Instance Methods - [MonoTODO] - protected override void OnClick(EventArgs e) - { - int res = Win32.SendMessage ( Handle, (int)ButtonMessages.BM_GETCHECK, 0, 0); + #region Protected Instance Methods + protected override AccessibleObject CreateAccessibilityInstance() { + AccessibleObject ao; - bool check = Checked; + ao = base.CreateAccessibilityInstance (); + ao.role = AccessibleRole.RadioButton; - if ( res == (int) NativeButtonState.BST_CHECKED ) - check = true; - else if ( res == (int) NativeButtonState.BST_UNCHECKED ) - check = false; + return ao; + } - if ( checked_ != check ) { - checked_ = check; - OnCheckedChanged ( EventArgs.Empty ); - } + protected virtual void OnCheckedChanged(EventArgs e) { + EventHandler eh = (EventHandler)(Events [CheckedChangedEvent]); + if (eh != null) + eh (this, e); + } - base.OnClick ( e ); + protected override void OnClick(EventArgs e) { + if (auto_check) { + if (!Checked) { + Checked = true; + } + } else { + Checked = !Checked; + } + + base.OnClick (e); } - [MonoTODO] - protected override void OnEnter(EventArgs e) - { - throw new NotImplementedException (); + protected override void OnEnter(EventArgs e) { + PerformDefaultCheck (); + base.OnEnter(e); } - [MonoTODO] - protected override void OnHandleCreated(EventArgs e) - { - base.OnHandleCreated ( e ); - updateCheck ( ); + + protected override void OnHandleCreated(EventArgs e) { + base.OnHandleCreated(e); } - [MonoTODO] - protected override void OnMouseUp(MouseEventArgs mevent) - { - throw new NotImplementedException (); + protected override void OnMouseUp(MouseEventArgs mevent) { + base.OnMouseUp(mevent); } - [MonoTODO] - protected override bool ProcessMnemonic(char charCode) - { - throw new NotImplementedException (); + + protected override bool ProcessMnemonic(char charCode) { + if (IsMnemonic(charCode, Text) == true) { + Select(); + PerformClick(); + return true; + } + + return base.ProcessMnemonic(charCode); } + #endregion // Protected Instance Methods - private int AutoCheckStyle - { - get { return (int) ( AutoCheck ? ButtonStyles.BS_AUTORADIOBUTTON : ButtonStyles.BS_RADIOBUTTON ); } + #region Events + static object AppearanceChangedEvent = new object (); + static object CheckedChangedEvent = new object (); + + public event EventHandler AppearanceChanged { + add { Events.AddHandler (AppearanceChangedEvent, value); } + remove { Events.RemoveHandler (AppearanceChangedEvent, value); } } - private int AppearanceStyle - { - get { return (int) ( Appearance == Appearance.Normal ? 0 : ButtonStyles.BS_PUSHLIKE ); } + public event EventHandler CheckedChanged { + add { Events.AddHandler (CheckedChangedEvent, value); } + remove { Events.RemoveHandler (CheckedChangedEvent, value); } } - private void updateCheck ( ) { - if ( IsHandleCreated ) - Win32.SendMessage ( Handle, (int) ButtonMessages.BM_SETCHECK, - Checked ? (int) NativeButtonState.BST_CHECKED : - ( int ) NativeButtonState.BST_UNCHECKED, 0 ); + [Browsable(false)] + [EditorBrowsable (EditorBrowsableState.Never)] + public new event EventHandler DoubleClick { + add { base.DoubleClick += value; } + remove { base.DoubleClick -= value; } + } + + [Browsable (false)] + [EditorBrowsable (EditorBrowsableState.Never)] + public new event MouseEventHandler MouseDoubleClick { + add { base.MouseDoubleClick += value; } + remove { base.MouseDoubleClick -= value; } } - } + #endregion // Events + } }