* TabControl.cs: Show the tooltip depending on the value
[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 ("System.Windows.Forms.Design.AutoSizeToolboxItem," + Consts.AssemblySystem_Design)]
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 new 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                         TextAlign = ContentAlignment.MiddleLeft;
116                         SetStyle(ControlStyles.StandardDoubleClick, false);
117 #if NET_2_0
118                         SetAutoSizeMode (AutoSizeMode.GrowAndShrink);
119 #endif
120                 }
121                 #endregion      // Public Constructors
122
123                 #region Internal Methods
124                 internal override void Draw (PaintEventArgs pe) {
125 #if NET_2_0
126                         // FIXME: This should be called every time something that can affect it
127                         // is changed, not every paint.  Can only change so many things at a time.
128
129                         // Figure out where our text and image should go
130                         Rectangle glyph_rectangle;
131                         Rectangle text_rectangle;
132                         Rectangle image_rectangle;
133
134                         ThemeEngine.Current.CalculateCheckBoxTextAndImageLayout (this, Point.Empty, out glyph_rectangle, out text_rectangle, out image_rectangle);
135
136                         // Draw our button
137                         if (FlatStyle != FlatStyle.System)
138                                 ThemeEngine.Current.DrawCheckBox (pe.Graphics, this, glyph_rectangle, text_rectangle, image_rectangle, pe.ClipRectangle);
139                         else
140                                 ThemeEngine.Current.DrawCheckBox (pe.Graphics, this.ClientRectangle, this);
141 #else
142                         ThemeEngine.Current.DrawCheckBox (pe.Graphics, this.ClientRectangle, this);
143 #endif
144                 }
145
146 #if NET_2_0
147                 internal override Size GetPreferredSizeCore (Size proposedSize)
148                 {
149                         if (this.AutoSize)
150                                 return ThemeEngine.Current.CalculateCheckBoxAutoSize (this);
151
152                         return base.GetPreferredSizeCore (proposedSize);
153                 }
154 #endif
155
156                 internal override void HaveDoubleClick() {
157                         if (DoubleClick != null) DoubleClick(this, EventArgs.Empty);
158                 }
159                 #endregion      // Internal Methods
160
161                 #region Public Instance Properties
162                 [DefaultValue(Appearance.Normal)]
163                 [Localizable(true)]
164                 public Appearance Appearance {
165                         get {
166                                 return appearance;
167                         }
168
169                         set {
170                                 if (value != appearance) {
171                                         appearance = value;
172                                         OnAppearanceChanged (EventArgs.Empty);
173
174                                         if (Parent != null)
175                                                 Parent.PerformLayout (this, "Appearance");
176                                         Invalidate();
177                                 }
178                         }
179                 }
180
181                 [DefaultValue(true)]
182                 public bool AutoCheck {
183                         get {
184                                 return auto_check;
185                         }
186
187                         set {
188                                 auto_check = value;
189                         }
190                 }
191
192                 [Bindable(true)]
193                 [Localizable(true)]
194                 [DefaultValue(ContentAlignment.MiddleLeft)]
195                 public ContentAlignment CheckAlign {
196                         get {
197                                 return check_alignment;
198                         }
199
200                         set {
201                                 if (value != check_alignment) {
202                                         check_alignment = value;
203                                         if (Parent != null)
204                                                 Parent.PerformLayout (this, "CheckAlign");
205                                         Invalidate();
206                                 }
207                         }
208                 }
209
210                 [Bindable(true)]
211                 [RefreshProperties(RefreshProperties.All)]
212                 [DefaultValue(false)]
213 #if NET_2_0
214                 [SettingsBindable (true)]
215 #endif
216                 public bool Checked {
217                         get {
218                                 if (check_state != CheckState.Unchecked) {
219                                         return true;
220                                 }
221                                 return false;
222                         }
223
224                         set {
225                                 if (value && (check_state != CheckState.Checked)) {
226                                         check_state = CheckState.Checked;
227                                         Invalidate();
228                                         OnCheckedChanged(EventArgs.Empty);
229                                 } else if (!value && (check_state != CheckState.Unchecked)) {
230                                         check_state = CheckState.Unchecked;
231                                         Invalidate();
232                                         OnCheckedChanged(EventArgs.Empty);
233                                 }
234                         }
235                 }
236
237                 [DefaultValue(CheckState.Unchecked)]
238                 [RefreshProperties(RefreshProperties.All)]
239                 [Bindable(true)]
240                 public CheckState CheckState {
241                         get {
242                                 return check_state;
243                         }
244
245                         set {
246                                 if (value != check_state) {
247                                         bool    was_checked = (check_state != CheckState.Unchecked);
248
249                                         check_state = value;
250
251                                         if (was_checked != (check_state != CheckState.Unchecked)) {
252                                                 OnCheckedChanged(EventArgs.Empty);
253                                         }
254
255                                         OnCheckStateChanged(EventArgs.Empty);
256                                         Invalidate();
257                                 }
258                         }
259                 }
260
261                 [DefaultValue(ContentAlignment.MiddleLeft)]
262                 [Localizable(true)]
263                 public override ContentAlignment TextAlign {
264                         get { return base.TextAlign; }
265                         set { base.TextAlign = value; }
266                 }
267
268
269                 [DefaultValue(false)]
270                 public bool ThreeState {
271                         get {
272                                 return three_state;
273                         }
274
275                         set {
276                                 three_state = value;
277                         }
278                 }
279                 #endregion      // Public Instance Properties
280
281                 #region Protected Instance Properties
282                 protected override CreateParams CreateParams {
283                         get {
284                                 return base.CreateParams;
285                         }
286                 }
287
288                 protected override Size DefaultSize {
289                         get {
290                                 return new Size(104, 24);
291                         }
292                 }
293                 #endregion      // Protected Instance Properties
294
295                 #region Public Instance Methods
296                 public override string ToString() {
297                         return base.ToString() + ", CheckState: " + (int)check_state;
298                 }
299                 #endregion      // Public Instance Methods
300
301                 #region Protected Instance Methods
302                 protected override AccessibleObject CreateAccessibilityInstance() {
303                         AccessibleObject        ao;
304
305                         ao = base.CreateAccessibilityInstance ();
306                         ao.role = AccessibleRole.CheckButton;
307
308                         return ao;
309                 }
310
311                 protected virtual void OnAppearanceChanged(EventArgs e) {
312                         EventHandler eh = (EventHandler)(Events [AppearanceChangedEvent]);
313                         if (eh != null)
314                                 eh (this, e);
315                 }
316
317                 protected virtual void OnCheckedChanged(EventArgs e) {
318                         EventHandler eh = (EventHandler)(Events [CheckedChangedEvent]);
319                         if (eh != null)
320                                 eh (this, e);
321                 }
322
323                 protected virtual void OnCheckStateChanged(EventArgs e) {
324                         EventHandler eh = (EventHandler)(Events [CheckStateChangedEvent]);
325                         if (eh != null)
326                                 eh (this, e);
327                 }
328
329                 protected override void OnClick(EventArgs e) {
330                         if (auto_check) {
331                                 switch(check_state) {
332                                         case CheckState.Unchecked: {
333                                                 if (three_state) {
334                                                         CheckState = CheckState.Indeterminate;
335                                                 } else {
336                                                         CheckState = CheckState.Checked;
337                                                 }
338                                                 break;
339                                         }
340
341                                         case CheckState.Indeterminate: {
342                                                 CheckState = CheckState.Checked;
343                                                 break;
344                                         }
345
346                                         case CheckState.Checked: {
347                                                 CheckState = CheckState.Unchecked;
348                                                 break;
349                                         }
350                                 }
351                         }
352                         
353                         base.OnClick (e);
354                 }
355
356                 protected override void OnHandleCreated(EventArgs e) {
357                         base.OnHandleCreated (e);
358                 }
359
360 #if NET_2_0
361                 protected override void OnKeyDown (KeyEventArgs e)
362                 {
363                         base.OnKeyDown (e);
364                 }
365 #endif
366
367                 protected override void OnMouseUp(MouseEventArgs mevent) {
368                         base.OnMouseUp (mevent);
369                 }
370
371                 protected override bool ProcessMnemonic(char charCode) {
372                         if (IsMnemonic(charCode, Text) == true) {
373                                 Select();
374                                 OnClick(EventArgs.Empty);
375                                 return true;
376                         }
377                         
378                         return base.ProcessMnemonic(charCode);
379                 }
380                 #endregion      // Protected Instance Methods
381
382                 #region Events
383                 static object AppearanceChangedEvent = new object ();
384                 static object CheckedChangedEvent = new object ();
385                 static object CheckStateChangedEvent = new object ();
386
387                 public event EventHandler AppearanceChanged {
388                         add { Events.AddHandler (AppearanceChangedEvent, value); }
389                         remove { Events.RemoveHandler (AppearanceChangedEvent, value); }
390                 }
391
392                 public event EventHandler CheckedChanged {
393                         add { Events.AddHandler (CheckedChangedEvent, value); }
394                         remove { Events.RemoveHandler (CheckedChangedEvent, value); }
395                 }
396
397                 public event EventHandler CheckStateChanged {
398                         add { Events.AddHandler (CheckStateChangedEvent, value); }
399                         remove { Events.RemoveHandler (CheckStateChangedEvent, value); }
400                 }
401                 
402 #if NET_2_0
403                 [Browsable (false)]
404                 [EditorBrowsable (EditorBrowsableState.Never)]
405                 public new event MouseEventHandler MouseDoubleClick {
406                         add { base.MouseDoubleClick += value; }
407                         remove { base.MouseDoubleClick -= value; }
408                 }
409 #endif
410                 #endregion      // Events
411
412                 #region Events
413                 // XXX have a look at this and determine if it
414                 // manipulates base.DoubleClick, and see if
415                 // HaveDoubleClick can just call OnDoubleClick.
416                 [Browsable(false)]
417                 [EditorBrowsable (EditorBrowsableState.Never)]
418                 public new event EventHandler DoubleClick;
419                 #endregion      // Events
420         }
421 }