- Implemented CheckBox drawing code
[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 Novell, Inc.
21 //
22 // Authors:
23 //      Dennis Hayes    dennish@raytek.com
24 //      Peter Bartok    pbartok@novell.com
25 //
26 //
27 // $Revision: 1.3 $
28 // $Modtime: $
29 // $Log: CheckBox.cs,v $
30 // Revision 1.3  2004/08/30 20:42:26  pbartok
31 // - Implemented CheckBox drawing code
32 //
33 // Revision 1.2  2004/08/30 15:44:20  pbartok
34 // - Updated to fix broken build. Not complete yet.
35 //
36 // Revision 1.1  2004/07/09 05:21:25  pbartok
37 // - Initial check-in
38 //
39 //
40
41 // NOT COMPLETE
42
43 using System;
44 using System.Drawing;
45
46 namespace System.Windows.Forms {
47         public class CheckBox : ButtonBase {
48                 private Appearance              appearance;
49                 private bool                    auto_check;
50                 private ContentAlignment        check_alignment;
51                 private ContentAlignment        text_alignment;
52                 private CheckState              check_state;
53                 private bool                    three_state;
54                 private int                     checkmark_size=13;              // Keep it configurable for accessability
55
56
57                 #region Public Constructors
58                 public CheckBox() {
59                         appearance = Appearance.Normal;
60                         auto_check = true;
61                         check_alignment = ContentAlignment.MiddleLeft;
62                 }
63                 #endregion      // Public Constructors
64
65                 #region Public Instance Properties
66                 public Appearance Appearance {
67                         get {
68                                 return appearance;
69                         }
70
71                         set {
72                                 if (value != appearance) {
73                                         value = appearance;
74                                         if (AppearanceChanged != null) {
75                                                 AppearanceChanged(this, EventArgs.Empty);
76                                         }
77                                 }
78                         }
79                 }
80
81                 public bool AutoCheck {
82                         get {
83                                 return auto_check;
84                         }
85
86                         set {
87                                 auto_check = value;
88                         }
89                 }
90
91                 public ContentAlignment CheckAlign {
92                         get {
93                                 return check_alignment;
94                         }
95
96                         set {
97                                 if (value != check_alignment) {
98                                         check_alignment = value;
99
100                                         CheckRedraw();
101                                 }
102                         }
103                 }
104
105                 public bool Checked {
106                         get {
107                                 if (check_state != CheckState.Unchecked) {
108                                         return true;
109                                 }
110                                 return false;
111                         }
112
113                         set {
114                                 if (value && (check_state != CheckState.Checked)) {
115                                         check_state = CheckState.Checked;
116                                         CheckRedraw();
117                                         OnCheckedChanged(EventArgs.Empty);
118                                 } else if (!value && (check_state != CheckState.Unchecked)) {
119                                         check_state = CheckState.Unchecked;
120                                         CheckRedraw();
121                                         OnCheckedChanged(EventArgs.Empty);
122                                 }
123                         }
124                 }
125
126                 public CheckState CheckState {
127                         get {
128                                 return check_state;
129                         }
130
131                         set {
132                                 if (value != check_state) {
133                                         bool    was_checked = (check_state != CheckState.Unchecked);
134
135                                         check_state = value;
136
137                                         if (was_checked != (check_state != CheckState.Unchecked)) {
138                                                 OnCheckedChanged(EventArgs.Empty);
139                                         }
140
141                                         OnCheckStateChanged(EventArgs.Empty);
142                                         CheckRedraw();
143                                 }
144                         }
145                 }
146
147                 public override ContentAlignment TextAlign {
148                         get {
149                                 return text_alignment;
150                         }
151
152                         set {
153                                 if (value != text_alignment) {
154                                         text_alignment = value;
155                                         CheckRedraw();
156                                 }
157                         }
158                 }
159
160
161                 public bool ThreeState {
162                         get {
163                                 return three_state;
164                         }
165
166                         set {
167                                 three_state = value;
168                         }
169                 }
170                 #endregion      // Public Instance Properties
171
172                 #region Protected Instance Properties
173                 protected override CreateParams CreateParams {
174                         get {
175                                 return base.CreateParams;
176                         }
177                 }
178
179                 protected override Size DefaultSize {
180                         get {
181                                 return new Size(104, 24);
182                         }
183                 }
184                 #endregion      // Protected Instance Properties
185
186                 #region Public Instance Methods
187                 public override string ToString() {
188                         if (CheckState == CheckState.Unchecked) {
189                                 return "CheckBox (unchecked)";
190                         } else if (CheckState == CheckState.Checked) {
191                                 return "CheckBox (checked)";
192                         } else {
193                                 return "CheckBox (state indeterminate)";
194                         }
195                 }
196                 #endregion      // Public Instance Methods
197
198                 #region Protected Instance Methods
199                 protected override AccessibleObject CreateAccessibilityInstance() {
200                         return base.CreateAccessibilityInstance ();
201                 }
202
203                 protected virtual void OnAppearanceChanged(EventArgs e) {
204                         if (AppearanceChanged != null) {
205                                 AppearanceChanged(this, e);
206                         }
207                 }
208
209                 protected virtual void OnCheckedChanged(EventArgs e) {
210 Console.WriteLine("Checked changed");
211                         if (CheckedChanged != null) {
212                                 CheckedChanged(this, e);
213                         }
214                 }
215
216                 protected virtual void OnCheckStateChanged(EventArgs e) {
217 Console.WriteLine("CheckState changed");
218                         if (CheckStateChanged != null) {
219                                 CheckStateChanged(this, e);
220                         }
221                 }
222
223                 protected override void OnClick(EventArgs e) {
224 Console.WriteLine("Got click event");
225                         if (auto_check) {
226                                 switch(check_state) {
227                                         case CheckState.Unchecked: {
228                                                 if (three_state) {
229                                                         CheckState = CheckState.Indeterminate;
230                                                 } else {
231                                                         CheckState = CheckState.Checked;
232                                                 }
233                                                 break;
234                                         }
235
236                                         case CheckState.Indeterminate: {
237                                                 CheckState = CheckState.Checked;
238                                                 break;
239                                         }
240
241                                         case CheckState.Checked: {
242                                                 CheckState = CheckState.Unchecked;
243                                                 break;
244                                         }
245                                 }
246                                 CheckRedraw();
247                         }
248                         base.OnClick (e);
249                 }
250
251                 protected override void OnHandleCreated(EventArgs e) {
252                         base.OnHandleCreated (e);
253                 }
254
255                 protected override void OnMouseUp(MouseEventArgs e) {
256                         base.OnMouseUp (e);
257                 }
258
259                 protected override bool ProcessMnemonic(char charCode) {
260                         return base.ProcessMnemonic (charCode);
261                 }
262                 #endregion      // Protected Instance Methods
263
264                 #region Events
265                 public event EventHandler       AppearanceChanged;
266                 public event EventHandler       CheckedChanged;
267                 public event EventHandler       CheckStateChanged;
268                 #endregion      // Events
269
270                 #region Internal drawing code
271                 internal override bool CheckRedraw() {\r
272                         return base.CheckRedraw ();\r
273                 }\r
274 \r
275                 internal override void Redraw() {\r
276                         StringFormat            text_format;
277                         Rectangle               client_rectangle;
278                         Rectangle               text_rectangle;
279                         Rectangle               checkbox_rectangle;
280                         SolidBrush              sb;
281 Console.WriteLine("REDRAWING");
282                         client_rectangle = ClientRectangle;
283                         text_rectangle = client_rectangle;
284                         checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size);
285
286                         text_format = new StringFormat();
287                         text_format.Alignment=StringAlignment.Near;
288                         text_format.LineAlignment=StringAlignment.Center;
289
290                         /* Calculate the position of text and checkbox rectangle */
291                         if (appearance!=Appearance.Button) {
292                                 switch(check_alignment) {
293                                         case ContentAlignment.BottomCenter: {
294                                                 if (client_rectangle.Height<checkmark_size*2) {
295                                                         ClientSize=new Size(client_rectangle.Width, checkmark_size*2);
296                                                         client_rectangle = ClientRectangle;
297                                                 }
298                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
299                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
300                                                 text_rectangle.X=client_rectangle.X;
301                                                 text_rectangle.Width=client_rectangle.Width;
302                                                 break;
303                                         }
304
305                                         case ContentAlignment.BottomLeft: {
306                                                 checkbox_rectangle.X=client_rectangle.Left;
307                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
308                                                 text_rectangle.X=client_rectangle.X+checkmark_size;
309                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size;
310                                                 break;
311                                         }
312
313                                         case ContentAlignment.BottomRight: {
314                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
315                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
316                                                 text_rectangle.X=client_rectangle.X;
317                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size;
318                                                 break;
319                                         }
320
321                                         case ContentAlignment.MiddleCenter: {
322                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
323                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
324                                                 text_rectangle.X=client_rectangle.X;
325                                                 text_rectangle.Width=client_rectangle.Width;
326                                                 break;
327                                         }
328
329                                         default:
330                                         case ContentAlignment.MiddleLeft: {
331                                                 checkbox_rectangle.X=client_rectangle.Left;
332                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
333                                                 text_rectangle.X=client_rectangle.X+checkmark_size;
334                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size;
335                                                 break;
336                                         }
337
338                                         case ContentAlignment.MiddleRight: {
339                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
340                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
341                                                 text_rectangle.X=client_rectangle.X;
342                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size;
343                                                 break;
344                                         }
345
346                                         case ContentAlignment.TopCenter: {
347                                                 if (client_rectangle.Height<checkmark_size*2) {
348                                                         ClientSize=new Size(client_rectangle.Width, checkmark_size*2);
349                                                         client_rectangle = ClientRectangle;
350                                                 }
351                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
352                                                 checkbox_rectangle.Y=client_rectangle.Top;
353                                                 text_rectangle.X=client_rectangle.X;
354                                                 text_rectangle.Y=checkmark_size;
355                                                 text_rectangle.Width=client_rectangle.Width;
356                                                 text_rectangle.Height=client_rectangle.Height-checkmark_size;
357                                                 break;
358                                         }
359
360                                         case ContentAlignment.TopLeft: {
361                                                 checkbox_rectangle.X=client_rectangle.Left;
362                                                 checkbox_rectangle.Y=client_rectangle.Top;
363                                                 text_rectangle.X=client_rectangle.X+checkmark_size;
364                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size;
365                                                 break;
366                                         }
367
368                                         case ContentAlignment.TopRight: {
369                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
370                                                 checkbox_rectangle.Y=client_rectangle.Top;
371                                                 text_rectangle.X=client_rectangle.X;
372                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size;
373                                                 break;
374                                         }
375                                 }
376                         } else {
377                                 text_rectangle.X=client_rectangle.X;
378                                 text_rectangle.Width=client_rectangle.Width;
379                         }
380
381                         /* Set the horizontal alignment of our text */
382                         switch(text_alignment) {
383                                 case ContentAlignment.BottomLeft:
384                                 case ContentAlignment.MiddleLeft:
385                                 case ContentAlignment.TopLeft: {
386                                         text_format.Alignment=StringAlignment.Near;
387                                         break;
388                                 }
389
390                                 case ContentAlignment.BottomCenter:
391                                 case ContentAlignment.MiddleCenter:
392                                 case ContentAlignment.TopCenter: {
393                                         text_format.Alignment=StringAlignment.Center;
394                                         break;
395                                 }
396
397                                 case ContentAlignment.BottomRight:
398                                 case ContentAlignment.MiddleRight:
399                                 case ContentAlignment.TopRight: {
400                                         text_format.Alignment=StringAlignment.Far;
401                                         break;
402                                 }
403                         }
404
405                         /* Set the vertical alignment of our text */
406                         switch(text_alignment) {
407                                 case ContentAlignment.TopLeft: 
408                                 case ContentAlignment.TopCenter: 
409                                 case ContentAlignment.TopRight: {
410                                         text_format.LineAlignment=StringAlignment.Near;
411                                         break;
412                                 }
413
414                                 case ContentAlignment.BottomLeft:
415                                 case ContentAlignment.BottomCenter:
416                                 case ContentAlignment.BottomRight: {
417                                         text_format.LineAlignment=StringAlignment.Far;
418                                         break;
419                                 }
420
421                                 case ContentAlignment.MiddleLeft:
422                                 case ContentAlignment.MiddleCenter:
423                                 case ContentAlignment.MiddleRight: {
424                                         text_format.LineAlignment=StringAlignment.Center;
425                                         break;
426                                 }
427                         }
428
429                         ButtonState state = ButtonState.Normal;
430                         if (FlatStyle == FlatStyle.Flat) {
431                                 state |= ButtonState.Flat;
432                         }
433                         
434                         if (Checked) {
435                                 state |= ButtonState.Checked;
436                         }
437                         
438                         if (ThreeState && (CheckState == CheckState.Indeterminate)) {
439                                 state |= ButtonState.Checked;
440                                 state |= ButtonState.Pushed;
441                         }
442
443                         // Start drawing
444
445                         sb=new SolidBrush(BackColor);
446                         this.DeviceContext.FillRectangle(sb, ClientRectangle);
447                         sb.Dispose();
448
449                         if (appearance!=Appearance.Button) {
450                                 ControlPaint.DrawCheckBox(this.DeviceContext, checkbox_rectangle, state);
451                         } else {
452                                 ControlPaint.DrawButton(this.DeviceContext, text_rectangle, state);
453                         }
454
455                         /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
456                         sb=new SolidBrush(ForeColor);
457                         this.DeviceContext.DrawString(Text, Font, sb, text_rectangle, text_format);
458                         sb.Dispose();
459
460                         if (Focused) {
461                                 ControlPaint.DrawFocusRectangle(this.DeviceContext, text_rectangle);
462                         }
463                 }\r
464                 #endregion      // Internal drawing code
465         }
466 }
467 #if not
468         public class CheckBox : ButtonBase {
469
470                 // private fields
471                 Appearance                      appearance;
472                 bool                                    autoCheck;
473                 ContentAlignment        checkAlign;
474                 bool                                    _checked;
475                 CheckState                      checkState;
476                 bool                                    threeState;
477                 ContentAlignment        textAlign;
478                 Rectangle                       text_rectangle;
479                 Rectangle                       checkbox_rectangle;
480                 StringFormat            textFormat;
481                 int                                     checkmark_size=13;              // Keep it configurable for accessability
482                 Graphics                                canvasDC;
483                 Bitmap                          canvasBmp;
484                 
485                 // --- Constructor ---
486                 public CheckBox() : base() 
487                 {
488
489                         appearance = Appearance.Normal;
490                         autoCheck = true;
491                         checkAlign = ContentAlignment.MiddleLeft;
492                         _checked = false;
493                         checkState = CheckState.Unchecked;
494                         threeState = false;
495
496                         canvasBmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
497                         canvasDC = Graphics.FromImage(canvasBmp);
498
499                         /* Set defaults for drawing text... */
500                         textAlign = ContentAlignment.MiddleLeft;
501                         textFormat = new StringFormat();
502                         textFormat.Alignment=StringAlignment.Near;
503                         textFormat.LineAlignment=StringAlignment.Center;
504                         text_rectangle = ClientRectangle;
505                         text_rectangle.X+=checkmark_size;
506                         text_rectangle.Width-=checkmark_size;
507
508                         /* ... and for drawing our checkbox */
509                         checkbox_rectangle.X=ClientRectangle.Left;
510                         checkbox_rectangle.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkmark_size/2;
511                         checkbox_rectangle.Width=checkmark_size;
512                         checkbox_rectangle.Height=checkmark_size;
513
514                         SizeChanged+=new System.EventHandler(CheckboxSizeChanged);
515                         GotFocus+=new System.EventHandler(CheckboxUpdate);
516                         LostFocus+=new System.EventHandler(CheckboxUpdate);
517                         TextChanged+=new System.EventHandler(CheckboxUpdate);
518
519                         SubClassWndProc_ = true;
520                         SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
521                         callWinControlProcMask &= ~(CallWinControlProcMask.MOUSE_MESSAGES | CallWinControlProcMask.KEYBOARD_MESSAGES);
522                 }
523                 
524                 // --- CheckBox Properties ---
525         
526                 public CheckState CheckState {
527                         get { return checkState; }
528                         set { 
529                                 if( checkState != value) {
530
531                                         checkState = value; 
532                                         bool oldChecked = _checked;
533
534                                         if( checkState == CheckState.Unchecked) {
535                                                 _checked = false;
536                                         }
537                                         else {
538                                                 _checked = true;
539                                         }
540
541                                         if( oldChecked != _checked) { 
542                                                 OnCheckedChanged(new EventArgs());
543                                         }
544
545                                         OnCheckStateChanged(new EventArgs());
546                                 }
547                         }
548                 }
549                 
550                 [MonoTODO]
551                 public override ContentAlignment TextAlign {
552                         get {
553                                 return textAlign;
554                         }
555                         set {
556                                 textAlign = value;
557                                 UpdateCheckbox();
558                         }
559                 }
560                 
561                 public bool ThreeState {
562                         get {
563                                 return threeState;
564                         }
565
566                         set {
567                                 threeState = value;
568                         }
569                 }       
570                 
571                 // --- CheckBox methods ---
572
573                 protected override AccessibleObject CreateAccessibilityInstance() 
574                 {
575                         throw new NotImplementedException ();
576                 }
577                 
578                 
579                 // [event methods]
580                 [MonoTODO]
581                 protected virtual void OnAppearanceChanged(EventArgs e) 
582                 {
583                         if (AppearanceChanged != null) {
584                                 AppearanceChanged(this, e);
585                         }
586                 }
587                 
588                 [MonoTODO]
589                 protected virtual void OnCheckedChanged(EventArgs e) 
590                 {
591                         //FIXME:
592                         if(CheckedChanged != null) {
593                                 CheckedChanged( this, e);
594                         }
595                 }
596                 
597                 [MonoTODO]
598                 protected virtual void OnCheckStateChanged(EventArgs e) 
599                 {
600                         //FIXME:
601                         if(CheckStateChanged != null) {
602                                 CheckStateChanged( this, e);
603                         }
604                 }
605                 
606                 [MonoTODO]
607                 protected override void OnClick(EventArgs e) 
608                 {
609                         CheckState = (CheckState)Win32.SendMessage(Handle, (int)ButtonMessages.BM_GETCHECK, 0, 0);
610                         base.OnClick(e);
611                 }
612                 
613                 [MonoTODO]
614                 protected override void OnHandleCreated(EventArgs e) 
615                 {
616                         //FIXME:
617                         base.OnHandleCreated(e);
618                         Win32.SendMessage(Handle, (int)ButtonMessages.BM_SETCHECK, (int)checkState, 0);
619                 }
620                 
621 //              protected override void OnMouseDown (MouseEventArgs e) 
622 //              {
623 //                      base.OnMouseDown (e);
624 //              }
625                 
626                 [MonoTODO]
627                 protected override void OnMouseUp(MouseEventArgs mevent) 
628                 {
629                         if (ThreeState) {
630                                 switch (CheckState) {
631                                         case CheckState.Unchecked: {
632                                                 CheckState = CheckState.Checked;
633                                                 break;
634                                         }
635
636                                         case CheckState.Indeterminate: {
637                                                 CheckState = CheckState.Unchecked;
638                                                 break;
639                                         }
640
641                                         case CheckState.Checked: {
642                                                 CheckState = CheckState.Indeterminate;
643                                                 break;
644                                         }
645                                 }
646                         } else {
647                                 Checked = Checked ? false : true;
648                         }
649                         CheckboxRedraw();
650                         Invalidate();
651                         base.OnMouseUp(mevent);
652                 }
653                 // end of [event methods]
654                 
655                 
656                 [MonoTODO]
657                 protected override bool ProcessMnemonic(char charCode) 
658                 {
659                         //FIXME:
660                         return base.ProcessMnemonic(charCode);
661                 }
662                 
663                 [MonoTODO]
664                 //FIXME: do a better tostring
665                 public override string ToString() 
666                 {
667                         if (Checked) {
668                                 return "CheckBox" + " Checked";
669                         } else {
670                                 return "CheckBox" +  " Unchecked";
671                         }
672                 }
673                 
674                 internal override void ButtonPaint (PaintEventArgs e) 
675                 {
676                         if (canvasBmp!=null) {
677                                 e.Graphics.DrawImage(canvasBmp, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel);
678                         }
679                 }
680                 
681                 /// --- CheckBox events ---
682                 public event EventHandler AppearanceChanged;
683                 public event EventHandler CheckedChanged;
684                 public event EventHandler CheckStateChanged;
685                 
686                 /// --- public class CheckBox.CheckBoxAccessibleObject : AccessibleObject ---
687                 /// the class is only used for .NET framework
688                 /// 
689                 public class CheckBoxAccessibleObject : AccessibleObject {
690                 }
691
692                 private void UpdateCheckbox() {
693                         /* Calculate the position of text and checkbox rectangle */
694                         if (appearance!=Appearance.Button) {
695                                 switch(checkAlign) {
696                                         case ContentAlignment.BottomCenter: {
697                                                 if (ClientRectangle.Height<checkmark_size*2) {
698                                                         ClientSize=new Size(ClientRectangle.Width, checkmark_size*2);
699                                                 }
700                                                 checkbox_rectangle.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkmark_size/2;
701                                                 checkbox_rectangle.Y=ClientRectangle.Bottom-checkmark_size;
702                                                 text_rectangle.X=ClientRectangle.X;
703                                                 text_rectangle.Width=ClientRectangle.Width;
704                                                 break;
705                                         }
706
707                                         case ContentAlignment.BottomLeft: {
708                                                 checkbox_rectangle.X=ClientRectangle.Left;
709                                                 checkbox_rectangle.Y=ClientRectangle.Bottom-checkmark_size;
710                                                 text_rectangle.X=ClientRectangle.X+checkmark_size;
711                                                 text_rectangle.Width=ClientRectangle.Width-checkmark_size;
712                                                 break;
713                                         }
714
715                                         case ContentAlignment.BottomRight: {
716                                                 checkbox_rectangle.X=ClientRectangle.Right-checkmark_size;
717                                                 checkbox_rectangle.Y=ClientRectangle.Bottom-checkmark_size;
718                                                 text_rectangle.X=ClientRectangle.X;
719                                                 text_rectangle.Width=ClientRectangle.Width-checkmark_size;
720                                                 break;
721                                         }
722
723                                         case ContentAlignment.MiddleCenter: {
724                                                 checkbox_rectangle.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkmark_size/2;
725                                                 checkbox_rectangle.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkmark_size/2;
726                                                 text_rectangle.X=ClientRectangle.X;
727                                                 text_rectangle.Width=ClientRectangle.Width;
728                                                 break;
729                                         }
730
731                                         default:
732                                         case ContentAlignment.MiddleLeft: {
733                                                 checkbox_rectangle.X=ClientRectangle.Left;
734                                                 checkbox_rectangle.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkmark_size/2;
735                                                 text_rectangle.X=ClientRectangle.X+checkmark_size;
736                                                 text_rectangle.Width=ClientRectangle.Width-checkmark_size;
737                                                 break;
738                                         }
739
740                                         case ContentAlignment.MiddleRight: {
741                                                 checkbox_rectangle.X=ClientRectangle.Right-checkmark_size;
742                                                 checkbox_rectangle.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkmark_size/2;
743                                                 text_rectangle.X=ClientRectangle.X;
744                                                 text_rectangle.Width=ClientRectangle.Width-checkmark_size;
745                                                 break;
746                                         }
747
748                                         case ContentAlignment.TopCenter: {
749                                                 if (ClientRectangle.Height<checkmark_size*2) {
750                                                         ClientSize=new Size(ClientRectangle.Width, checkmark_size*2);
751                                                 }
752                                                 checkbox_rectangle.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkmark_size/2;
753                                                 checkbox_rectangle.Y=ClientRectangle.Top;
754                                                 text_rectangle.X=ClientRectangle.X;
755                                                 text_rectangle.Y=checkmark_size;
756                                                 text_rectangle.Width=ClientRectangle.Width;
757                                                 text_rectangle.Height=ClientRectangle.Height-checkmark_size;
758                                                 break;
759                                         }
760
761                                         case ContentAlignment.TopLeft: {
762                                                 checkbox_rectangle.X=ClientRectangle.Left;
763                                                 checkbox_rectangle.Y=ClientRectangle.Top;
764                                                 text_rectangle.X=ClientRectangle.X+checkmark_size;
765                                                 text_rectangle.Width=ClientRectangle.Width-checkmark_size;
766                                                 break;
767                                         }
768
769                                         case ContentAlignment.TopRight: {
770                                                 checkbox_rectangle.X=ClientRectangle.Right-checkmark_size;
771                                                 checkbox_rectangle.Y=ClientRectangle.Top;
772                                                 text_rectangle.X=ClientRectangle.X;
773                                                 text_rectangle.Width=ClientRectangle.Width-checkmark_size;
774                                                 break;
775                                         }
776                                 }
777                         } else {
778                                 text_rectangle.X=ClientRectangle.X;
779                                 text_rectangle.Width=ClientRectangle.Width;
780                         }
781
782                         /* Set the horizontal alignment of our text */
783                         switch(textAlign) {
784                                 case ContentAlignment.BottomLeft:
785                                 case ContentAlignment.MiddleLeft:
786                                 case ContentAlignment.TopLeft: {
787                                         textFormat.Alignment=StringAlignment.Near;
788                                         break;
789                                 }
790
791                                 case ContentAlignment.BottomCenter:
792                                 case ContentAlignment.MiddleCenter:
793                                 case ContentAlignment.TopCenter: {
794                                         textFormat.Alignment=StringAlignment.Center;
795                                         break;
796                                 }
797
798                                 case ContentAlignment.BottomRight:
799                                 case ContentAlignment.MiddleRight:
800                                 case ContentAlignment.TopRight: {
801                                         textFormat.Alignment=StringAlignment.Far;
802                                         break;
803                                 }
804                         }
805
806                         /* Set the vertical alignment of our text */
807                         switch(textAlign) {
808                                 case ContentAlignment.TopLeft: 
809                                 case ContentAlignment.TopCenter: 
810                                 case ContentAlignment.TopRight: {
811                                         textFormat.LineAlignment=StringAlignment.Near;
812                                         break;
813                                 }
814
815                                 case ContentAlignment.BottomLeft:
816                                 case ContentAlignment.BottomCenter:
817                                 case ContentAlignment.BottomRight: {
818                                         textFormat.LineAlignment=StringAlignment.Far;
819                                         break;
820                                 }
821
822                                 case ContentAlignment.MiddleLeft:
823                                 case ContentAlignment.MiddleCenter:
824                                 case ContentAlignment.MiddleRight: {
825                                         textFormat.LineAlignment=StringAlignment.Center;
826                                         break;
827                                 }
828                         }
829                         CheckboxRedraw();
830                         Invalidate();
831                 }
832
833                 private void CheckboxRedraw() {
834                         SolidBrush      sb;
835
836                         /* Build the image representing the control */
837
838                         if (canvasDC!=null) {
839                                 canvasDC.Dispose();
840                         }
841                         if (canvasBmp!=null) {
842                                 canvasBmp.Dispose();
843                         }
844
845                         if (ClientRectangle.Width<1 || ClientRectangle.Height<1) {
846                                 return;
847                         }
848                         canvasBmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
849                         canvasDC = Graphics.FromImage(canvasBmp);
850
851                         sb=new SolidBrush(BackColor);
852                         canvasDC.FillRectangle(sb, ClientRectangle);
853                         sb.Dispose();
854
855                         ButtonState state = ButtonState.Normal;
856                         if (FlatStyle == FlatStyle.Flat) {
857                                 state |= ButtonState.Flat;
858                         }
859                         
860                         if (Checked) {
861                                 state |= ButtonState.Checked;
862                         }
863                         
864                         if (ThreeState && (CheckState == CheckState.Indeterminate)) {
865                                 state |= ButtonState.Checked;
866                                 state |= ButtonState.Pushed;
867                         }
868
869                         if (appearance!=Appearance.Button) {
870                                 ControlPaint.DrawCheckBox(canvasDC, checkbox_rectangle, state);
871                         } else {
872                                 ControlPaint.DrawButton(canvasDC, text_rectangle, state);
873                         }
874
875                         /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
876                         sb=new SolidBrush(base.foreColor);
877                         canvasDC.DrawString(Text, Font, sb, text_rectangle, textFormat);
878                         sb.Dispose();
879
880                         if (Focused) {
881                                 ControlPaint.DrawFocusRectangle(canvasDC, text_rectangle);
882                         }
883                 }
884
885                 private void CheckboxUpdate(object sender, System.EventArgs e) {
886                         /* Force recalculation of text & checkbox rectangles */
887                         UpdateCheckbox();
888                 }
889
890                 private void CheckboxSizeChanged(object sender, System.EventArgs e)
891                 {
892                         /* Force recalculation of text & checkbox rectangles */
893                         text_rectangle.Y=ClientRectangle.Y;
894                         text_rectangle.Height=ClientRectangle.Height;
895                         UpdateCheckbox();
896                 }
897         }
898
899
900 }
901 #endif