merge r67228-r67235, r67237, r67251 and r67256-67259 to trunk (they are
[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                 }
109                 #endregion      // Public Constructors
110
111                 #region Private Methods
112                 private void UpdateSiblings() {
113                         Control c;
114
115                         if (auto_check == false) {
116                                 return;
117                         }
118
119                         // Remove tabstop property from and uncheck our radio-button siblings
120                         c = this.parent;
121                         if (c != null) {
122                                 for (int i = 0; i < c.child_controls.Count; i++) {
123                                         if ((this != c.child_controls[i]) && (c.child_controls[i] is RadioButton)) {
124                                                 if (((RadioButton)(c.child_controls[i])).auto_check) {
125                                                         c.child_controls[i].TabStop = false;
126                                                         ((RadioButton)(c.child_controls[i])).Checked = false;
127                                                 }
128                                         }
129                                 }
130                         }
131
132                         this.TabStop = true;
133                 }
134
135                 internal override void HaveDoubleClick() {
136                         if (DoubleClick != null) DoubleClick(this, EventArgs.Empty);
137                 }
138
139                 internal override void Draw (PaintEventArgs pe) {
140                         ThemeEngine.Current.DrawRadioButton (pe.Graphics, this.ClientRectangle, this);
141                 }
142                 #endregion      // Private Methods
143
144                 #region Public Instance Properties
145                 [DefaultValue(Appearance.Normal)]
146                 [Localizable(true)]
147                 public Appearance Appearance {
148                         get {
149                                 return appearance;
150                         }
151
152                         set {
153                                 if (value != appearance) {
154                                         appearance = value;
155                                         if (AppearanceChanged != null) {
156                                                 AppearanceChanged(this, EventArgs.Empty);
157                                         }
158                                         Redraw();
159                                 }
160                         }
161                 }
162
163                 [DefaultValue(true)]
164                 public bool AutoCheck {
165                         get {
166                                 return auto_check;
167                         }
168
169                         set {
170                                 auto_check = value;
171                         }
172                 }
173
174                 [Bindable(true)]
175                 [Localizable(true)]
176                 [DefaultValue(ContentAlignment.MiddleLeft)]
177                 public ContentAlignment CheckAlign {
178                         get {
179                                 return radiobutton_alignment;
180                         }
181
182                         set {
183                                 if (value != radiobutton_alignment) {
184                                         radiobutton_alignment = value;
185
186                                         Redraw();
187                                 }
188                         }
189                 }
190
191                 [DefaultValue(false)]
192                 public bool Checked {
193                         get {
194                                 if (check_state != CheckState.Unchecked) {
195                                         return true;
196                                 }
197                                 return false;
198                         }
199
200                         set {
201                                 if (value && (check_state != CheckState.Checked)) {
202                                         UpdateSiblings();
203                                         check_state = CheckState.Checked;
204                                         Redraw();
205                                         OnCheckedChanged(EventArgs.Empty);
206                                 } else if (!value && (check_state != CheckState.Unchecked)) {
207                                         check_state = CheckState.Unchecked;
208                                         Redraw();
209                                         OnCheckedChanged(EventArgs.Empty);
210                                 }
211                         }
212                 }
213
214                 [DefaultValue(false)]
215                 public new bool TabStop {
216                         get {
217                                 return tab_stop;
218                         }
219
220                         set {
221                                 tab_stop = value;
222                         }
223                 }
224
225                 [DefaultValue(ContentAlignment.MiddleLeft)]
226                 [Localizable(true)]
227                 public override ContentAlignment TextAlign {
228                         get {
229                                 return text_alignment;
230                         }
231
232                         set {
233                                 if (value != text_alignment) {
234                                         text_alignment = value;
235                                         Redraw();
236                                 }
237                         }
238                 }
239                 #endregion      // Public Instance Properties
240
241                 #region Protected Instance Properties
242                 protected override CreateParams CreateParams {
243                         get {
244                                 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
245                                 SetStyle(ControlStyles.UserPaint, true);
246
247                                 return base.CreateParams;
248                         }
249                 }
250
251                 protected override Size DefaultSize {
252                         get {
253                                 return ThemeEngine.Current.RadioButtonDefaultSize;
254                         }
255                 }
256                 #endregion      // Protected Instance Properties
257
258                 #region Public Instance Methods
259                 public void PerformClick() {
260                         OnClick(EventArgs.Empty);
261                 }
262
263                 public override string ToString() {
264                         return base.ToString() + ", Checked: " + this.Checked;
265                 }
266                 #endregion      // Public Instance Methods
267
268                 #region Protected Instance Methods
269                 protected override AccessibleObject CreateAccessibilityInstance() {
270                         AccessibleObject        ao;
271
272                         ao = base.CreateAccessibilityInstance ();
273                         ao.role = AccessibleRole.RadioButton;
274
275                         return ao;
276                 }
277
278                 protected virtual void OnCheckedChanged(EventArgs e) {
279                         if (CheckedChanged != null) {
280                                 CheckedChanged(this, e);
281                         }
282                 }
283
284                 protected override void OnClick(EventArgs e) {
285                         if (auto_check) {
286                                 if (!Checked) {
287                                         Checked = true;
288                                 }
289                         } else {
290                                 Checked = !Checked;
291                         }
292                         
293                         base.OnClick (e);
294                 }
295
296                 protected override void OnEnter(EventArgs e) {
297                         base.OnEnter(e);
298                 }
299
300                 protected override void OnHandleCreated(EventArgs e) {
301                         base.OnHandleCreated(e);
302                 }
303
304                 protected override void OnMouseUp(MouseEventArgs mevent) {
305                         base.OnMouseUp(mevent);
306                 }
307
308                 protected override bool ProcessMnemonic(char charCode) {
309                         if (IsMnemonic(charCode, Text) == true) {
310                                 Select();
311                                 PerformClick();
312                                 return true;
313                         }
314                         
315                         return base.ProcessMnemonic(charCode);
316                 }
317                 #endregion      // Protected Instance Methods
318
319                 #region Events
320                 public event EventHandler       AppearanceChanged;
321                 public event EventHandler       CheckedChanged;
322
323                 [Browsable(false)]
324                 [EditorBrowsable (EditorBrowsableState.Never)]
325                 public event EventHandler       DoubleClick;
326                 #endregion      // Events
327         }
328 }