2007-02-27 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / CheckBox.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 //      Dennis Hayes    dennish@raytek.com
24 //      Peter Bartok    pbartok@novell.com
25 //
26
27 using System;
28 using System.ComponentModel;
29 using System.Drawing;
30 using System.Runtime.InteropServices;
31
32 namespace System.Windows.Forms {
33         [DefaultProperty("Checked")]
34         [DefaultEvent("CheckedChanged")]
35 #if NET_2_0
36         [ComVisible (true)]
37         [ClassInterface (ClassInterfaceType.AutoDispatch)]
38         [DefaultBindingProperty ("CheckState")]
39         [ToolboxItem ("")]
40 #endif
41         public class CheckBox : ButtonBase {
42                 #region Local Variables
43                 internal Appearance             appearance;
44                 internal bool                   auto_check;
45                 internal ContentAlignment       check_alignment;
46                 internal CheckState             check_state;
47                 internal bool                   three_state;
48                 #endregion      // Local Variables
49
50                 #region CheckBoxAccessibleObject Subclass
51                 [ComVisible(true)]
52                 public class CheckBoxAccessibleObject : ButtonBaseAccessibleObject {
53                         #region CheckBoxAccessibleObject Local Variables
54                         private CheckBox owner;
55                         #endregion      // CheckBoxAccessibleObject Local Variables
56
57                         #region CheckBoxAccessibleObject Constructors
58                         public CheckBoxAccessibleObject(Control owner) : base(owner) {
59                                 this.owner = (CheckBox)owner;
60                         }
61                         #endregion      // CheckBoxAccessibleObject Constructors
62
63                         #region CheckBoxAccessibleObject Properties
64                         public override string DefaultAction {
65                                 get {
66                                         return "Select";
67                                 }
68                         }
69
70                         public override AccessibleRole Role {
71                                 get {
72                                         return AccessibleRole.CheckButton;
73                                 }
74                         }
75
76                         public override AccessibleStates State {
77                                 get {
78                                         AccessibleStates        retval;
79
80                                         retval = AccessibleStates.Default;
81
82                                         if (owner.check_state == CheckState.Checked) {
83                                                 retval |= AccessibleStates.Checked;
84                                         }
85
86                                         if (owner.Focused) {
87                                                 retval |= AccessibleStates.Focused;
88                                         }
89
90                                         if (owner.CanFocus) {
91                                                 retval |= AccessibleStates.Focusable;
92                                         }
93
94                                         return retval;
95                                 }
96                         }
97                         #endregion      // CheckBoxAccessibleObject Properties
98
99 #if NET_2_0
100                         #region CheckBoxAccessibleObject Methods
101                         public override void DoDefaultAction ()
102                         {
103                                 owner.Checked = !owner.Checked;
104                         }
105                         #endregion      // CheckBoxAccessibleObject Methods
106 #endif
107                 }
108                 #endregion      // CheckBoxAccessibleObject Sub-class
109
110                 #region Public Constructors
111                 public CheckBox() {
112                         appearance = Appearance.Normal;
113                         auto_check = true;
114                         check_alignment = ContentAlignment.MiddleLeft;
115                         text_alignment = ContentAlignment.MiddleLeft;
116                         SetStyle(ControlStyles.StandardDoubleClick, false);
117                 }
118                 #endregion      // Public Constructors
119
120                 #region Internal Methods
121                 internal override void Draw (PaintEventArgs pe) {
122                         ThemeEngine.Current.DrawCheckBox (pe.Graphics, this.ClientRectangle, this);
123                 }
124
125                 internal override void HaveDoubleClick() {
126                         if (DoubleClick != null) DoubleClick(this, EventArgs.Empty);
127                 }
128                 #endregion      // Internal Methods
129
130                 #region Public Instance Properties
131                 [DefaultValue(Appearance.Normal)]
132                 [Localizable(true)]
133                 public Appearance Appearance {
134                         get {
135                                 return appearance;
136                         }
137
138                         set {
139                                 if (value != appearance) {
140                                         appearance = value;
141                                         OnAppearanceChanged (EventArgs.Empty);
142                                         Redraw();
143                                 }
144                         }
145                 }
146
147                 [DefaultValue(true)]
148                 public bool AutoCheck {
149                         get {
150                                 return auto_check;
151                         }
152
153                         set {
154                                 auto_check = value;
155                         }
156                 }
157
158                 [Bindable(true)]
159                 [Localizable(true)]
160                 [DefaultValue(ContentAlignment.MiddleLeft)]
161                 public ContentAlignment CheckAlign {
162                         get {
163                                 return check_alignment;
164                         }
165
166                         set {
167                                 if (value != check_alignment) {
168                                         check_alignment = value;
169
170                                         Redraw();
171                                 }
172                         }
173                 }
174
175                 [Bindable(true)]
176                 [RefreshProperties(RefreshProperties.All)]
177                 [DefaultValue(false)]
178 #if NET_2_0
179                 [SettingsBindable (true)]
180 #endif
181                 public bool Checked {
182                         get {
183                                 if (check_state != CheckState.Unchecked) {
184                                         return true;
185                                 }
186                                 return false;
187                         }
188
189                         set {
190                                 if (value && (check_state != CheckState.Checked)) {
191                                         check_state = CheckState.Checked;
192                                         Redraw();
193                                         OnCheckedChanged(EventArgs.Empty);
194                                 } else if (!value && (check_state != CheckState.Unchecked)) {
195                                         check_state = CheckState.Unchecked;
196                                         Redraw();
197                                         OnCheckedChanged(EventArgs.Empty);
198                                 }
199                         }
200                 }
201
202                 [DefaultValue(CheckState.Unchecked)]
203                 [RefreshProperties(RefreshProperties.All)]
204                 [Bindable(true)]
205                 public CheckState CheckState {
206                         get {
207                                 return check_state;
208                         }
209
210                         set {
211                                 if (value != check_state) {
212                                         bool    was_checked = (check_state != CheckState.Unchecked);
213
214                                         check_state = value;
215
216                                         if (was_checked != (check_state != CheckState.Unchecked)) {
217                                                 OnCheckedChanged(EventArgs.Empty);
218                                         }
219
220                                         OnCheckStateChanged(EventArgs.Empty);
221                                         Redraw();
222                                 }
223                         }
224                 }
225
226                 [DefaultValue(ContentAlignment.MiddleLeft)]
227                 [Localizable(true)]
228                 public override ContentAlignment TextAlign {
229                         get {
230                                 return text_alignment;
231                         }
232
233                         set {
234                                 if (value != text_alignment) {
235                                         text_alignment = value;
236                                         Redraw();
237                                 }
238                         }
239                 }
240
241
242                 [DefaultValue(false)]
243                 public bool ThreeState {
244                         get {
245                                 return three_state;
246                         }
247
248                         set {
249                                 three_state = value;
250                         }
251                 }
252                 #endregion      // Public Instance Properties
253
254                 #region Protected Instance Properties
255                 protected override CreateParams CreateParams {
256                         get {
257                                 return base.CreateParams;
258                         }
259                 }
260
261                 protected override Size DefaultSize {
262                         get {
263                                 return new Size(104, 24);
264                         }
265                 }
266                 #endregion      // Protected Instance Properties
267
268                 #region Public Instance Methods
269                 public override string ToString() {
270                         return base.ToString() + ", CheckState: " + (int)check_state;
271                 }
272                 #endregion      // Public Instance Methods
273
274                 #region Protected Instance Methods
275                 protected override AccessibleObject CreateAccessibilityInstance() {
276                         AccessibleObject        ao;
277
278                         ao = base.CreateAccessibilityInstance ();
279                         ao.role = AccessibleRole.CheckButton;
280
281                         return ao;
282                 }
283
284                 protected virtual void OnAppearanceChanged(EventArgs e) {
285                         EventHandler eh = (EventHandler)(Events [AppearanceChangedEvent]);
286                         if (eh != null)
287                                 eh (this, e);
288                 }
289
290                 protected virtual void OnCheckedChanged(EventArgs e) {
291                         EventHandler eh = (EventHandler)(Events [CheckedChangedEvent]);
292                         if (eh != null)
293                                 eh (this, e);
294                 }
295
296                 protected virtual void OnCheckStateChanged(EventArgs e) {
297                         EventHandler eh = (EventHandler)(Events [CheckStateChangedEvent]);
298                         if (eh != null)
299                                 eh (this, e);
300                 }
301
302                 protected override void OnClick(EventArgs e) {
303                         if (auto_check) {
304                                 switch(check_state) {
305                                         case CheckState.Unchecked: {
306                                                 if (three_state) {
307                                                         CheckState = CheckState.Indeterminate;
308                                                 } else {
309                                                         CheckState = CheckState.Checked;
310                                                 }
311                                                 break;
312                                         }
313
314                                         case CheckState.Indeterminate: {
315                                                 CheckState = CheckState.Checked;
316                                                 break;
317                                         }
318
319                                         case CheckState.Checked: {
320                                                 CheckState = CheckState.Unchecked;
321                                                 break;
322                                         }
323                                 }
324                         }
325                         
326                         base.OnClick (e);
327                 }
328
329                 protected override void OnHandleCreated(EventArgs e) {
330                         base.OnHandleCreated (e);
331                 }
332
333 #if NET_2_0
334                 protected override void OnKeyDown (KeyEventArgs kevent)
335                 {
336                         base.OnKeyDown (kevent);
337                 }
338 #endif
339
340                 protected override void OnMouseUp(MouseEventArgs mevent) {
341                         base.OnMouseUp (mevent);
342                 }
343
344                 protected override bool ProcessMnemonic(char charCode) {
345                         if (IsMnemonic(charCode, Text) == true) {
346                                 Select();
347                                 OnClick(EventArgs.Empty);
348                                 return true;
349                         }
350                         
351                         return base.ProcessMnemonic(charCode);
352                 }
353                 #endregion      // Protected Instance Methods
354
355                 #region Events
356                 static object AppearanceChangedEvent = new object ();
357                 static object CheckedChangedEvent = new object ();
358                 static object CheckStateChangedEvent = new object ();
359
360                 public event EventHandler AppearanceChanged {
361                         add { Events.AddHandler (AppearanceChangedEvent, value); }
362                         remove { Events.RemoveHandler (AppearanceChangedEvent, value); }
363                 }
364
365                 public event EventHandler CheckedChanged {
366                         add { Events.AddHandler (CheckedChangedEvent, value); }
367                         remove { Events.RemoveHandler (CheckedChangedEvent, value); }
368                 }
369
370                 public event EventHandler CheckStateChanged {
371                         add { Events.AddHandler (CheckStateChangedEvent, value); }
372                         remove { Events.RemoveHandler (CheckStateChangedEvent, value); }
373                 }
374                 
375 #if NET_2_0
376                 public event MouseEventHandler MouseDoubleClick {
377                         add { base.MouseDoubleClick += value; }
378                         remove { base.MouseDoubleClick -= value; }
379                 }
380 #endif
381                 #endregion      // Events
382
383                 #region Events
384                 // XXX have a look at this and determine if it
385                 // manipulates base.DoubleClick, and see if
386                 // HaveDoubleClick can just call OnDoubleClick.
387                 [Browsable(false)]
388                 [EditorBrowsable (EditorBrowsableState.Never)]
389                 public new event EventHandler DoubleClick;
390                 #endregion      // Events
391         }
392 }