svn path=/branches/mono-1-1-9/mcs/; revision=50439
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / RadioButton.cs
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.
19 //
20 // Copyright (c) 2004-2005 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25
26 // COMPLETE
27
28 using System.ComponentModel;
29 using System.Drawing;
30 using System.Drawing.Text;
31 using System.Runtime.InteropServices;
32
33 namespace System.Windows.Forms {
34         [DefaultProperty("Checked")]
35         [DefaultEvent("CheckedChanged")]
36         public class RadioButton : ButtonBase {
37                 #region Local Variables
38                 internal Appearance             appearance;
39                 internal bool                   auto_check;
40                 internal ContentAlignment       radiobutton_alignment;
41                 internal CheckState             check_state;
42                 #endregion      // Local Variables
43
44                 #region RadioButtonAccessibleObject Subclass
45                 [ComVisible(true)]
46                 public class RadioButtonAccessibleObject : ControlAccessibleObject {
47                         #region RadioButtonAccessibleObject Local Variables
48                         private RadioButton     owner;
49                         #endregion      // RadioButtonAccessibleObject Local Variables
50
51                         #region RadioButtonAccessibleObject Constructors
52                         public RadioButtonAccessibleObject(RadioButton owner) : base(owner) {
53                                 this.owner = owner;
54                         }
55                         #endregion      // RadioButtonAccessibleObject Constructors
56
57                         #region RadioButtonAccessibleObject Properties
58                         public override string DefaultAction {
59                                 get {
60                                         return "Select";
61                                 }
62                         }
63
64                         public override AccessibleRole Role {
65                                 get {
66                                         return AccessibleRole.RadioButton;
67                                 }
68                         }
69
70                         public override AccessibleStates State {
71                                 get {
72                                         AccessibleStates        retval;
73
74                                         retval = AccessibleStates.Default;
75
76                                         if (owner.check_state == CheckState.Checked) {
77                                                 retval |= AccessibleStates.Checked;
78                                         }
79
80                                         if (owner.Focused) {
81                                                 retval |= AccessibleStates.Focused;
82                                         }
83
84                                         if (owner.CanFocus) {
85                                                 retval |= AccessibleStates.Focusable;
86                                         }
87
88                                         return retval;
89                                 }
90                         }
91                         #endregion      // RadioButtonAccessibleObject Properties
92
93                         #region RadioButtonAccessibleObject Methods
94                         public override void DoDefaultAction() {
95                                 owner.PerformClick();
96                         }
97                         #endregion      // RadioButtonAccessibleObject Methods
98                 }
99                 #endregion      // RadioButtonAccessibleObject Sub-class
100
101                 #region Public Constructors
102                 public RadioButton() {
103                         appearance = Appearance.Normal;
104                         auto_check = true;
105                         radiobutton_alignment = ContentAlignment.MiddleLeft;
106                         text_alignment = ContentAlignment.MiddleLeft;
107                         tab_stop = false;
108                         GotFocus +=new EventHandler(ReceivedFocus);
109                 }
110                 #endregion      // Public Constructors
111
112                 #region Private Methods
113                 private void UpdateSiblings() {
114                         Control c;
115
116                         if (auto_check == false) {
117                                 return;
118                         }
119
120                         // Remove tabstop property from and uncheck our radio-button siblings
121                         c = this.parent;
122                         if (c != null) {
123                                 for (int i = 0; i < c.child_controls.Count; i++) {
124                                         if ((this != c.child_controls[i]) && (c.child_controls[i] is RadioButton)) {
125                                                 if (((RadioButton)(c.child_controls[i])).auto_check) {
126                                                         c.child_controls[i].TabStop = false;
127                                                         ((RadioButton)(c.child_controls[i])).Checked = false;
128                                                 }
129                                         }
130                                 }
131                         }
132
133                         this.TabStop = true;
134                 }
135
136                 internal override void HaveDoubleClick() {
137                         if (DoubleClick != null) DoubleClick(this, EventArgs.Empty);
138                 }
139
140                 internal override void Draw (PaintEventArgs pe) {
141                         ThemeEngine.Current.DrawRadioButton (pe.Graphics, this.ClientRectangle, this);
142                 }
143
144                 private void ReceivedFocus(object sender, EventArgs e) {
145                         OnClick(e);
146                 }
147                 #endregion      // Private Methods
148
149                 #region Public Instance Properties
150                 [DefaultValue(Appearance.Normal)]
151                 [Localizable(true)]
152                 public Appearance Appearance {
153                         get {
154                                 return appearance;
155                         }
156
157                         set {
158                                 if (value != appearance) {
159                                         appearance = value;
160                                         if (AppearanceChanged != null) {
161                                                 AppearanceChanged(this, EventArgs.Empty);
162                                         }
163                                         Redraw();
164                                 }
165                         }
166                 }
167
168                 [DefaultValue(true)]
169                 public bool AutoCheck {
170                         get {
171                                 return auto_check;
172                         }
173
174                         set {
175                                 auto_check = value;
176                         }
177                 }
178
179                 [Bindable(true)]
180                 [Localizable(true)]
181                 [DefaultValue(ContentAlignment.MiddleLeft)]
182                 public ContentAlignment CheckAlign {
183                         get {
184                                 return radiobutton_alignment;
185                         }
186
187                         set {
188                                 if (value != radiobutton_alignment) {
189                                         radiobutton_alignment = value;
190
191                                         Redraw();
192                                 }
193                         }
194                 }
195
196                 [DefaultValue(false)]
197                 public bool Checked {
198                         get {
199                                 if (check_state != CheckState.Unchecked) {
200                                         return true;
201                                 }
202                                 return false;
203                         }
204
205                         set {
206                                 if (value && (check_state != CheckState.Checked)) {
207                                         UpdateSiblings();
208                                         check_state = CheckState.Checked;
209                                         Redraw();
210                                         OnCheckedChanged(EventArgs.Empty);
211                                 } else if (!value && (check_state != CheckState.Unchecked)) {
212                                         check_state = CheckState.Unchecked;
213                                         Redraw();
214                                         OnCheckedChanged(EventArgs.Empty);
215                                 }
216                         }
217                 }
218
219                 [DefaultValue(false)]
220                 public new bool TabStop {
221                         get {
222                                 return tab_stop;
223                         }
224
225                         set {
226                                 tab_stop = value;
227                         }
228                 }
229
230                 [DefaultValue(ContentAlignment.MiddleLeft)]
231                 [Localizable(true)]
232                 public override ContentAlignment TextAlign {
233                         get {
234                                 return text_alignment;
235                         }
236
237                         set {
238                                 if (value != text_alignment) {
239                                         text_alignment = value;
240                                         Redraw();
241                                 }
242                         }
243                 }
244                 #endregion      // Public Instance Properties
245
246                 #region Protected Instance Properties
247                 protected override CreateParams CreateParams {
248                         get {
249                                 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
250                                 SetStyle(ControlStyles.UserPaint, true);
251
252                                 return base.CreateParams;
253                         }
254                 }
255
256                 protected override Size DefaultSize {
257                         get {
258                                 return ThemeEngine.Current.RadioButtonDefaultSize;
259                         }
260                 }
261                 #endregion      // Protected Instance Properties
262
263                 #region Public Instance Methods
264                 public void PerformClick() {
265                         OnClick(EventArgs.Empty);
266                 }
267
268                 public override string ToString() {
269                         return base.ToString() + ", Checked: " + this.Checked;
270                 }
271                 #endregion      // Public Instance Methods
272
273                 #region Protected Instance Methods
274                 protected override AccessibleObject CreateAccessibilityInstance() {
275                         AccessibleObject        ao;
276
277                         ao = base.CreateAccessibilityInstance ();
278                         ao.role = AccessibleRole.RadioButton;
279
280                         return ao;
281                 }
282
283                 protected virtual void OnCheckedChanged(EventArgs e) {
284                         if (CheckedChanged != null) {
285                                 CheckedChanged(this, e);
286                         }
287                 }
288
289                 protected override void OnClick(EventArgs e) {
290                         if (auto_check) {
291                                 if (!Checked) {
292                                         Checked = true;
293                                 }
294                         } else {
295                                 Checked = !Checked;
296                         }
297                         
298                         base.OnClick (e);
299                 }
300
301                 protected override void OnEnter(EventArgs e) {
302                         base.OnEnter(e);
303                 }
304
305                 protected override void OnHandleCreated(EventArgs e) {
306                         base.OnHandleCreated(e);
307                 }
308
309                 protected override void OnMouseUp(MouseEventArgs mevent) {
310                         base.OnMouseUp(mevent);
311                 }
312
313                 protected override bool ProcessMnemonic(char charCode) {
314                         if (IsMnemonic(charCode, Text) == true) {
315                                 Select();
316                                 PerformClick();
317                                 return true;
318                         }
319                         
320                         return base.ProcessMnemonic(charCode);
321                 }
322                 #endregion      // Protected Instance Methods
323
324                 #region Events
325                 public event EventHandler       AppearanceChanged;
326                 public event EventHandler       CheckedChanged;
327
328                 [Browsable(false)]
329                 [EditorBrowsable (EditorBrowsableState.Never)]
330                 public event EventHandler       DoubleClick;
331                 #endregion      // Events
332         }
333 }