In System.Windows.Forms.VisualStyles:
[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 using System.ComponentModel;
27 using System.Drawing;
28 using System.Drawing.Text;
29 using System.Runtime.InteropServices;
30
31 namespace System.Windows.Forms {
32         [DefaultProperty("Checked")]
33         [DefaultEvent("CheckedChanged")]
34 #if NET_2_0
35         [ClassInterface (ClassInterfaceType.AutoDispatch)]
36         [ComVisible (true)]
37         [DefaultBindingProperty ("Checked")]
38 #endif
39         public class RadioButton : ButtonBase {
40                 #region Local Variables
41                 internal Appearance             appearance;
42                 internal bool                   auto_check;
43                 internal ContentAlignment       radiobutton_alignment;
44                 internal CheckState             check_state;
45                 #endregion      // Local Variables
46
47                 #region RadioButtonAccessibleObject Subclass
48                 [ComVisible(true)]
49                 public class RadioButtonAccessibleObject : ControlAccessibleObject {
50                         #region RadioButtonAccessibleObject Local Variables
51                         private RadioButton     owner;
52                         #endregion      // RadioButtonAccessibleObject Local Variables
53
54                         #region RadioButtonAccessibleObject Constructors
55                         public RadioButtonAccessibleObject(RadioButton owner) : base(owner) {
56                                 this.owner = owner;
57                         }
58                         #endregion      // RadioButtonAccessibleObject Constructors
59
60                         #region RadioButtonAccessibleObject Properties
61                         public override string DefaultAction {
62                                 get {
63                                         return "Select";
64                                 }
65                         }
66
67                         public override AccessibleRole Role {
68                                 get {
69                                         return AccessibleRole.RadioButton;
70                                 }
71                         }
72
73                         public override AccessibleStates State {
74                                 get {
75                                         AccessibleStates        retval;
76
77                                         retval = AccessibleStates.Default;
78
79                                         if (owner.check_state == CheckState.Checked) {
80                                                 retval |= AccessibleStates.Checked;
81                                         }
82
83                                         if (owner.Focused) {
84                                                 retval |= AccessibleStates.Focused;
85                                         }
86
87                                         if (owner.CanFocus) {
88                                                 retval |= AccessibleStates.Focusable;
89                                         }
90
91                                         return retval;
92                                 }
93                         }
94                         #endregion      // RadioButtonAccessibleObject Properties
95
96                         #region RadioButtonAccessibleObject Methods
97                         public override void DoDefaultAction() {
98                                 owner.PerformClick();
99                         }
100                         #endregion      // RadioButtonAccessibleObject Methods
101                 }
102                 #endregion      // RadioButtonAccessibleObject Sub-class
103
104                 #region Public Constructors
105                 public RadioButton() {
106                         appearance = Appearance.Normal;
107                         auto_check = true;
108                         radiobutton_alignment = ContentAlignment.MiddleLeft;
109                         text_alignment = ContentAlignment.MiddleLeft;
110                         TabStop = false;
111                 }
112                 #endregion      // Public Constructors
113
114                 #region Private Methods
115                 private void UpdateSiblings() {
116                         Control c;
117
118                         if (auto_check == false) {
119                                 return;
120                         }
121
122                         // Remove tabstop property from and uncheck our radio-button siblings
123                         c = this.Parent;
124                         if (c != null) {
125                                 for (int i = 0; i < c.Controls.Count; i++) {
126                                         if ((this != c.Controls[i]) && (c.Controls[i] is RadioButton)) {
127                                                 if (((RadioButton)(c.Controls[i])).auto_check) {
128                                                         c.Controls[i].TabStop = false;
129                                                         ((RadioButton)(c.Controls[i])).Checked = false;
130                                                 }
131                                         }
132                                 }
133                         }
134
135                         this.TabStop = true;
136                 }
137
138                 internal override void Draw (PaintEventArgs pe) {
139                         ThemeEngine.Current.DrawRadioButton (pe.Graphics, this.ClientRectangle, this);
140                 }
141                 #endregion      // Private Methods
142
143                 #region Public Instance Properties
144                 [DefaultValue(Appearance.Normal)]
145                 [Localizable(true)]
146                 public Appearance Appearance {
147                         get {
148                                 return appearance;
149                         }
150
151                         set {
152                                 if (value != appearance) {
153                                         appearance = value;
154                                         EventHandler eh = (EventHandler)(Events [AppearanceChangedEvent]);
155                                         if (eh != null)
156                                                 eh (this, EventArgs.Empty);
157                                         Redraw();
158                                 }
159                         }
160                 }
161
162                 [DefaultValue(true)]
163                 public bool AutoCheck {
164                         get {
165                                 return auto_check;
166                         }
167
168                         set {
169                                 auto_check = value;
170                         }
171                 }
172
173 #if !NET_2_0
174                 [Bindable(true)]
175 #endif
176                 [Localizable(true)]
177                 [DefaultValue(ContentAlignment.MiddleLeft)]
178                 public ContentAlignment CheckAlign {
179                         get {
180                                 return radiobutton_alignment;
181                         }
182
183                         set {
184                                 if (value != radiobutton_alignment) {
185                                         radiobutton_alignment = value;
186
187                                         Redraw();
188                                 }
189                         }
190                 }
191
192                 [DefaultValue(false)]
193 #if NET_2_0
194                 [SettingsBindable (true)]
195                 [Bindable (true, BindingDirection.OneWay)]
196 #endif
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 { return base.TabStop; }
222                         set { base.TabStop = value; }
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                         EventHandler eh = (EventHandler)(Events [CheckedChangedEvent]);
280                         if (eh != null)
281                                 eh (this, e);
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                 static object AppearanceChangedEvent = new object ();
321                 static object CheckedChangedEvent = new object ();
322
323                 public event EventHandler AppearanceChanged {
324                         add { Events.AddHandler (AppearanceChangedEvent, value); }
325                         remove { Events.RemoveHandler (AppearanceChangedEvent, value); }
326                 }
327
328                 public event EventHandler CheckedChanged {
329                         add { Events.AddHandler (CheckedChangedEvent, value); }
330                         remove { Events.RemoveHandler (CheckedChangedEvent, value); }
331                 }
332
333                 [Browsable(false)]
334                 [EditorBrowsable (EditorBrowsableState.Never)]
335                 public new event EventHandler DoubleClick {
336                         add { base.DoubleClick += value; }
337                         remove { base.DoubleClick -= value; }
338                 }
339                 #endregion      // Events
340         }
341 }