* StatusBar.cs: Statusbar handles its fore/back colours on it's
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeWin32Classic.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 //      Jordi Mas i Hernandez, jordi@ximian.com
24 //      Peter Bartok, pbartok@novell.com
25 //      John BouAntoun, jba-mono@optusnet.com.au
26 //  Marek Safar, marek.safar@seznam.cz
27 //
28
29
30 using System.Drawing;
31 using System.Drawing.Drawing2D;
32 using System.Drawing.Imaging;
33 using System.Drawing.Text;
34
35 namespace System.Windows.Forms
36 {
37
38         internal class ThemeWin32Classic : Theme
39         {               
40                 public override Version Version {
41                         get {
42                                 return new Version(0, 1, 0, 0);
43                         }
44                 }
45
46                 /* Hardcoded colour values not exposed in the API constants in all configurations */
47                 protected static readonly Color arrow_color = Color.Black;
48                 protected static readonly Color pen_ticks_color = Color.Black;
49                 protected static readonly Color progressbarblock_color = Color.FromArgb (255, 0, 0, 128);
50                 protected static StringFormat string_format_menu_text;
51                 protected static StringFormat string_format_menu_shortcut;
52                 protected static StringFormat string_format_menu_menubar_text;
53                 static readonly Rectangle checkbox_rect = new Rectangle (2, 2, 11,11); // Position of the checkbox relative to the item
54                 static ImageAttributes imagedisabled_attributes = null;
55                 const int SEPARATOR_HEIGHT = 5;
56                 const int SM_CXBORDER = 1;
57                 const int SM_CYBORDER = 1;              
58                 const int MENU_TAB_SPACE = 8;           // Pixels added to the width of an item because of a tab
59                 const int MENU_BAR_ITEMS_SPACE = 8;     // Space between menu bar items
60
61                 #region Principal Theme Methods
62                 public ThemeWin32Classic ()
63                 {                       
64                         defaultWindowBackColor = this.ColorWindow;
65                         defaultWindowForeColor = this.ColorControlText;
66                         default_font =  new Font (FontFamily.GenericSansSerif, 8.25f);
67                         
68                         /* Menu string formats */
69                         string_format_menu_text = new StringFormat ();
70                         string_format_menu_text.LineAlignment = StringAlignment.Center;
71                         string_format_menu_text.Alignment = StringAlignment.Near;
72                         string_format_menu_text.HotkeyPrefix = HotkeyPrefix.Show;
73
74                         string_format_menu_shortcut = new StringFormat ();      
75                         string_format_menu_shortcut.LineAlignment = StringAlignment.Center;
76                         string_format_menu_shortcut.Alignment = StringAlignment.Far;
77
78                         string_format_menu_menubar_text = new StringFormat ();
79                         string_format_menu_menubar_text.LineAlignment = StringAlignment.Center;
80                         string_format_menu_menubar_text.Alignment = StringAlignment.Center;
81                         string_format_menu_menubar_text.HotkeyPrefix = HotkeyPrefix.Show;
82                         always_draw_hotkeys = false;
83                 }       
84
85                 public override void ResetDefaults() {
86                         throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
87                 }
88
89                 public override bool DoubleBufferingSupported {
90                         get {return true; }
91                 }
92                 #endregion      // Principal Theme Methods
93
94                 #region Internal Methods
95                 protected SolidBrush GetControlBackBrush (Color c) {
96                         if (c == DefaultControlBackColor)
97                                 return ResPool.GetSolidBrush (ColorControl);
98                         return new SolidBrush (c);
99                 }
100
101                 protected SolidBrush GetControlForeBrush (Color c) {
102                         if (c == DefaultControlForeColor)
103                                 return ResPool.GetSolidBrush (ColorControlText);
104                         return new SolidBrush (c);
105                 }
106                 #endregion      // Internal Methods
107
108                 #region OwnerDraw Support
109                 public  override void DrawOwnerDrawBackground (DrawItemEventArgs e)
110                 {
111                         if (e.State == DrawItemState.Selected) {
112                                 e.Graphics.FillRectangle (SystemBrushes.Highlight, e.Bounds);
113                                 return;
114                         }
115
116                         e.Graphics.FillRectangle (GetControlBackBrush (e.BackColor), e.Bounds);
117                 }
118
119                 public  override void DrawOwnerDrawFocusRectangle (DrawItemEventArgs e)
120                 {
121                         if (e.State == DrawItemState.Focus)
122                                 CPDrawFocusRectangle (e.Graphics, e.Bounds, e.ForeColor, e.BackColor);
123                 }
124                 #endregion      // OwnerDraw Support
125
126                 #region ButtonBase
127                 public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button) {
128                         // Draw the button: fill rectangle, draw border, etc.
129                         ButtonBase_DrawButton(button, dc);
130                         
131                         // First, draw the image
132                         if ((button.image != null) || (button.image_list != null))
133                                 ButtonBase_DrawImage(button, dc);
134                         
135                         // Draw the focus rectangle
136                         if (button.has_focus)
137                                 ButtonBase_DrawFocus(button, dc);
138                         
139                         // Now the text
140                         if (button.text != null && button.text != String.Empty)
141                                 ButtonBase_DrawText(button, dc);
142                 }
143
144                 protected virtual void ButtonBase_DrawButton(ButtonBase button, Graphics dc)
145                 {
146                         Rectangle buttonRectangle;
147                         Rectangle borderRectangle;
148                         
149                         dc.FillRectangle(ResPool.GetSolidBrush (button.BackColor), button.ClientRectangle);
150                         
151                         // set up the button rectangle
152                         buttonRectangle = button.ClientRectangle;
153                         if (button.has_focus) {
154                                 // shrink the rectangle for the normal button drawing inside the focus rectangle
155                                 borderRectangle = Rectangle.Inflate(buttonRectangle, -1, -1);
156                         } else {
157                                 borderRectangle = buttonRectangle;
158                         }
159
160                         if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
161                                 DrawFlatStyleButton (dc, borderRectangle, button);
162                         } else {
163                                 CPDrawButton(dc, borderRectangle, button.ButtonState);
164                                 if (button.has_focus) {
165                                         dc.DrawRectangle(ResPool.GetPen(button.ForeColor), borderRectangle);
166                                 }
167                         }
168                 }
169
170                 protected virtual void ButtonBase_DrawImage(ButtonBase button, Graphics dc)
171                 {
172                         // Need to draw a picture
173                         Image   i;
174                         int     image_x;
175                         int     image_y;
176                         int     image_width;
177                         int     image_height;
178                         
179                         int width = button.ClientSize.Width;
180                         int height = button.ClientSize.Height;
181                         
182                         if (button.ImageIndex != -1) {   // We use ImageIndex instead of image_index since it will return -1 if image_list is null
183                                 i = button.image_list.Images[button.image_index];
184                         } else {
185                                 i = button.image;
186                         }
187                         
188                         image_width = button.image.Width;
189                         image_height = button.image.Height;
190                         
191                         switch (button.image_alignment) {
192                                 case ContentAlignment.TopLeft: {
193                                         image_x=0;
194                                         image_y=0;
195                                         break;
196                                 }
197                                         
198                                 case ContentAlignment.TopCenter: {
199                                         image_x=(width-image_width)/2;
200                                         image_y=0;
201                                         break;
202                                 }
203                                         
204                                 case ContentAlignment.TopRight: {
205                                         image_x=width-image_width;
206                                         image_y=0;
207                                         break;
208                                 }
209                                         
210                                 case ContentAlignment.MiddleLeft: {
211                                         image_x=0;
212                                         image_y=(height-image_height)/2;
213                                         break;
214                                 }
215                                         
216                                 case ContentAlignment.MiddleCenter: {
217                                         image_x=(width-image_width)/2;
218                                         image_y=(height-image_height)/2;
219                                         break;
220                                 }
221                                         
222                                 case ContentAlignment.MiddleRight: {
223                                         image_x=width-image_width;
224                                         image_y=(height-image_height)/2;
225                                         break;
226                                 }
227                                         
228                                 case ContentAlignment.BottomLeft: {
229                                         image_x=0;
230                                         image_y=height-image_height;
231                                         break;
232                                 }
233                                         
234                                 case ContentAlignment.BottomCenter: {
235                                         image_x=(width-image_width)/2;
236                                         image_y=height-image_height;
237                                         break;
238                                 }
239                                         
240                                 case ContentAlignment.BottomRight: {
241                                         image_x=width-image_width;
242                                         image_y=height-image_height;
243                                         break;
244                                 }
245                                         
246                                 default: {
247                                         image_x=0;
248                                         image_y=0;
249                                         break;
250                                 }
251                         }
252                         
253                         if (button.is_pressed) {
254                                 image_x+=1;
255                                 image_y+=1;
256                         }
257                         
258                         if (button.is_enabled) {
259                                 dc.DrawImage(i, image_x, image_y); 
260                         }
261                         else {
262                                 CPDrawImageDisabled(dc, i, image_x, image_y, ColorControl);
263                         }
264                 }
265                 
266                 protected virtual void ButtonBase_DrawFocus(ButtonBase button, Graphics dc)
267                 {
268                         if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
269                                 DrawFlatStyleFocusRectangle (dc, button.ClientRectangle, button, button.ForeColor, button.BackColor);
270                         } else { 
271                                 Rectangle rect = button.ClientRectangle;
272                                 rect.Inflate (-4, -4);
273                                 CPDrawFocusRectangle(dc, rect, button.ForeColor, button.BackColor);
274                         }
275                 }
276                 
277                 protected virtual void ButtonBase_DrawText(ButtonBase button, Graphics dc)
278                 {
279                         Rectangle buttonRectangle = button.ClientRectangle;
280                         Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4);
281                         
282                         if (button.is_pressed) {
283                                 text_rect.X++;
284                                 text_rect.Y++;
285                         }
286                         
287                         if (button.is_enabled) {                                        
288                                 dc.DrawString(button.text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format);
289                         } else {
290                                 if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
291                                         dc.DrawString(button.text, button.Font, ResPool.GetSolidBrush (ControlPaint.DarkDark (this.ColorControl)), text_rect, button.text_format);
292                                 } else {
293                                         CPDrawStringDisabled(dc, button.text, button.Font, ColorControlText, text_rect, button.text_format);
294                                 }
295                         }
296                 }
297                 
298                 // draw the flat style part of the rectangle
299                 public void DrawFlatStyleButton (Graphics graphics, Rectangle rectangle, ButtonBase button) {
300                         Color rect_back_color = button.BackColor;
301                         Color rect_fore_color = button.ForeColor;
302                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
303                                 
304                         if (button.Enabled) {
305                                 if (button.Capture || button.is_entered) {
306                                         if (button.FlatStyle == FlatStyle.Flat) {
307                                                 // fill the rectangle
308                                                 graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
309                                                 
310                                                 // now draw the outer border
311                                                 if (button.Capture && button.is_entered) {
312                                                         rect_back_color = ControlPaint.LightLight (rect_back_color);
313                                                 } else {
314                                                         rect_back_color = ControlPaint.Light (rect_back_color);
315                                                 }
316                                                 
317                                                 // draw rectangle and fill it
318                                                 graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
319                                                 graphics.DrawRectangle(ResPool.GetPen (rect_fore_color), trace_rectangle);
320                                         } else {
321                                                 // else it must be a popup button
322                                                 
323                                                 if (button.Capture && button.is_entered) {
324                                                         graphics.DrawRectangle(ResPool.GetPen (this.ColorControlText), trace_rectangle);
325                                                 } else {
326                                                         // draw a 3d border
327                                                         CPDrawBorder3D (graphics, rectangle, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top, button.BackColor); 
328                                                         graphics.DrawLine ( ResPool.GetPen (this.ColorControlText), trace_rectangle.X, trace_rectangle.Bottom, trace_rectangle.Right, trace_rectangle.Bottom);
329                                                         graphics.DrawLine ( ResPool.GetPen (this.ColorControlText), trace_rectangle.Right, trace_rectangle.Y, trace_rectangle.Right, trace_rectangle.Bottom);
330                                                 }
331                                         }
332                                         
333                                         // TODO: draw inner focus rectangle
334                                         
335                                 } else {
336                                         // popup has a ButtonColorText forecolor, not a button.ForeCOlor
337                                         if (button.FlatStyle == FlatStyle.Popup) {
338                                                 rect_fore_color = this.ColorControlText;
339                                         }
340                                         
341                                         // fill then draw outer rect
342                                         graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
343                                         graphics.DrawRectangle(ResPool.GetPen (rect_fore_color), trace_rectangle);
344                                 }
345                                 
346                                 // finally some small tweaks to render radiobutton and checkbox
347                                 CheckBox checkbox = button as CheckBox;
348                                 RadioButton radiobutton = button as RadioButton;
349                                 if ((checkbox != null && checkbox.Checked) ||
350                                         (radiobutton != null && radiobutton.Checked)) {
351                                         if (button.FlatStyle == FlatStyle.Flat && button.is_entered && !button.Capture) {
352                                                 // render the hover for flat flatstyle and cheked
353                                                 graphics.DrawRectangle(ResPool.GetPen (this.ColorControlText), trace_rectangle);
354                                         } else if (!button.is_entered && !button.Capture) {
355                                                 // render the checked state for popup when unhovered
356                                                 CPDrawBorder3D (graphics, rectangle, Border3DStyle.SunkenInner, Border3DSide.Right | Border3DSide.Bottom, button.BackColor); 
357                                         }
358                                 }
359                         } else {
360                                 // rendering checkbox or radio button style buttons
361                                 CheckBox checkbox = button as CheckBox;
362                                 RadioButton radiobutton = button as RadioButton;
363                                 bool draw_popup_checked = false;
364                                 
365                                 if (button.FlatStyle == FlatStyle.Popup) {
366                                         rect_fore_color = this.ColorControlText;
367                                 
368                                         // see if we should draw a disabled checked popup button
369                                         draw_popup_checked = ((checkbox != null && checkbox.Checked) ||
370                                                 (radiobutton != null && radiobutton.Checked));
371                                 }
372                                 
373                                 graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
374                                 graphics.DrawRectangle(ResPool.GetPen (rect_fore_color), trace_rectangle);
375                                 
376                                 // finally draw the flatstyle checked effect if need
377                                 if (draw_popup_checked) {
378                                         // render the checked state for popup when unhovered
379                                         CPDrawBorder3D (graphics, rectangle, Border3DStyle.SunkenInner, Border3DSide.Right | Border3DSide.Bottom, button.BackColor);
380                                 }
381                         }
382                 }
383
384                 public override Size ButtonBaseDefaultSize {
385                         get {
386                                 return new Size (75, 23);
387                         }
388                 }
389                 #endregion      // ButtonBase
390
391                 #region CheckBox
392                 public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) {
393                         StringFormat            text_format;
394                         Rectangle               client_rectangle;
395                         Rectangle               text_rectangle;
396                         Rectangle               checkbox_rectangle;
397                         int                     checkmark_size=13;
398                         int                     checkmark_space = 4;
399
400                         client_rectangle = checkbox.ClientRectangle;
401                         text_rectangle = client_rectangle;
402                         checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size);
403
404                         text_format = new StringFormat();
405                         text_format.Alignment=StringAlignment.Near;
406                         text_format.LineAlignment=StringAlignment.Center;
407                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
408
409                         /* Calculate the position of text and checkbox rectangle */
410                         if (checkbox.appearance!=Appearance.Button) {
411                                 switch(checkbox.check_alignment) {
412                                         case ContentAlignment.BottomCenter: {
413                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
414                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
415                                                 text_rectangle.X=client_rectangle.X;
416                                                 text_rectangle.Width=client_rectangle.Width;
417                                                 text_rectangle.Height=client_rectangle.Height-checkbox_rectangle.Y-checkmark_space;
418                                                 break;
419                                         }
420
421                                         case ContentAlignment.BottomLeft: {
422                                                 checkbox_rectangle.X=client_rectangle.Left;
423                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
424                                                 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
425                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;                                             
426                                                 break;
427                                         }
428
429                                         case ContentAlignment.BottomRight: {
430                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
431                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
432                                                 text_rectangle.X=client_rectangle.X;
433                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;                                             
434                                                 break;
435                                         }
436
437                                         case ContentAlignment.MiddleCenter: {
438                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
439                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
440                                                 text_rectangle.X=client_rectangle.X;
441                                                 text_rectangle.Width=client_rectangle.Width;
442                                                 break;
443                                         }
444
445                                         default:
446                                         case ContentAlignment.MiddleLeft: {
447                                                 checkbox_rectangle.X=client_rectangle.Left;
448                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
449                                                 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
450                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;                                                                                             
451                                                 break;
452                                         }
453
454                                         case ContentAlignment.MiddleRight: {
455                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
456                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
457                                                 text_rectangle.X=client_rectangle.X;
458                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
459                                                 break;
460                                         }
461
462                                         case ContentAlignment.TopCenter: {
463                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
464                                                 checkbox_rectangle.Y=client_rectangle.Top;
465                                                 text_rectangle.X=client_rectangle.X;
466                                                 text_rectangle.Width=client_rectangle.Width;
467                                                 text_rectangle.Y=checkmark_size+checkmark_space;
468                                                 text_rectangle.Height=client_rectangle.Height-checkmark_size-checkmark_space;
469                                                 break;
470                                         }
471
472                                         case ContentAlignment.TopLeft: {
473                                                 checkbox_rectangle.X=client_rectangle.Left;
474                                                 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
475                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
476                                                 break;
477                                         }
478
479                                         case ContentAlignment.TopRight: {
480                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
481                                                 text_rectangle.X=client_rectangle.X;
482                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
483                                                 break;
484                                         }
485                                 }
486                         } else {
487                                 text_rectangle.X=client_rectangle.X;
488                                 text_rectangle.Width=client_rectangle.Width;
489                         }
490                         
491                         /* Set the horizontal alignment of our text */
492                         switch(checkbox.text_alignment) {
493                                 case ContentAlignment.BottomLeft:
494                                 case ContentAlignment.MiddleLeft:
495                                 case ContentAlignment.TopLeft: {
496                                         text_format.Alignment=StringAlignment.Near;
497                                         break;
498                                 }
499
500                                 case ContentAlignment.BottomCenter:
501                                 case ContentAlignment.MiddleCenter:
502                                 case ContentAlignment.TopCenter: {
503                                         text_format.Alignment=StringAlignment.Center;
504                                         break;
505                                 }
506
507                                 case ContentAlignment.BottomRight:
508                                 case ContentAlignment.MiddleRight:
509                                 case ContentAlignment.TopRight: {
510                                         text_format.Alignment=StringAlignment.Far;
511                                         break;
512                                 }
513                         }
514
515                         /* Set the vertical alignment of our text */
516                         switch(checkbox.text_alignment) {
517                                 case ContentAlignment.TopLeft: 
518                                 case ContentAlignment.TopCenter: 
519                                 case ContentAlignment.TopRight: {
520                                         text_format.LineAlignment=StringAlignment.Near;
521                                         break;
522                                 }
523
524                                 case ContentAlignment.BottomLeft:
525                                 case ContentAlignment.BottomCenter:
526                                 case ContentAlignment.BottomRight: {
527                                         text_format.LineAlignment=StringAlignment.Far;
528                                         break;
529                                 }
530
531                                 case ContentAlignment.MiddleLeft:
532                                 case ContentAlignment.MiddleCenter:
533                                 case ContentAlignment.MiddleRight: {
534                                         text_format.LineAlignment=StringAlignment.Center;
535                                         break;
536                                 }
537                         }
538
539                         ButtonState state = ButtonState.Normal;
540                         if (checkbox.FlatStyle == FlatStyle.Flat) {
541                                 state |= ButtonState.Flat;
542                         }
543                         
544                         if (checkbox.Checked) {
545                                 state |= ButtonState.Checked;
546                         }
547                         
548                         if (checkbox.ThreeState && (checkbox.CheckState == CheckState.Indeterminate)) {
549                                 state |= ButtonState.Checked;
550                                 state |= ButtonState.Pushed;                            
551                         }
552                         
553                         // finally make sure the pushed and inavtive states are rendered
554                         if (!checkbox.Enabled) {
555                                 state |= ButtonState.Inactive;
556                         }
557                         else if (checkbox.is_pressed) {
558                                 state |= ButtonState.Pushed;
559                         }
560                         
561                         
562                         // Start drawing
563                         
564                         CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle);
565                         
566                         CheckBox_DrawText(checkbox, text_rectangle, dc, text_format);
567
568                         CheckBox_DrawFocus(checkbox, dc, text_rectangle);
569
570                         text_format.Dispose ();
571                 }
572
573                 protected virtual void CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle )
574                 {
575                         dc.FillRectangle (ResPool.GetSolidBrush (checkbox.BackColor), checkbox.ClientRectangle);                        
576                         // render as per normal button
577                         if (checkbox.appearance==Appearance.Button) {
578                                 if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
579                                         DrawFlatStyleButton(dc, checkbox.ClientRectangle, checkbox);
580                                 } else {
581                                         CPDrawButton(dc, checkbox.ClientRectangle, state);
582                                 }
583                         } else {
584                                 // establish if we are rendering a flat style of some sort
585                                 if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
586                                         DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox);
587                                 } else {
588                                         ControlPaint.DrawCheckBox(dc, checkbox_rectangle, state);
589                                 }
590                         }
591                 }
592                 
593                 protected virtual void CheckBox_DrawText( CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format )
594                 {
595                         SolidBrush sb;
596                         
597                         // offset the text if it's pressed and a button
598                         if (checkbox.Appearance == Appearance.Button) {
599                                 if (checkbox.Checked || (checkbox.Capture && checkbox.FlatStyle != FlatStyle.Flat)) {
600                                         text_rectangle.X ++;
601                                         text_rectangle.Y ++;
602                                 }
603                                 
604                                 text_rectangle.Inflate(-4, -4);
605                         }
606                         
607                         /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
608                         if (checkbox.Enabled) {
609                                 sb = ResPool.GetSolidBrush(checkbox.ForeColor);
610                                 dc.DrawString(checkbox.Text, checkbox.Font, sb, text_rectangle, text_format);                   
611                         } else if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
612                                 dc.DrawString(checkbox.Text, checkbox.Font, ResPool.GetSolidBrush (ControlPaint.DarkDark (this.ColorControl)), text_rectangle, text_format);
613                         } else {
614                                 CPDrawStringDisabled(dc, checkbox.Text, checkbox.Font, ColorControlText, text_rectangle, text_format);
615                         }
616                 }
617                 
618                 protected virtual void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle )
619                 {
620                         if (checkbox.Focused) {
621                                 if (checkbox.FlatStyle != FlatStyle.Flat) {
622                                         DrawInnerFocusRectangle (dc, Rectangle.Inflate (text_rectangle, -1, -1), checkbox.BackColor);
623                                 } else {
624                                         dc.DrawRectangle (ResPool.GetPen (checkbox.ForeColor), Rectangle.Inflate (text_rectangle, -1, -1));
625                                 }
626                         }
627                 }
628
629                 // renders a checkBox with the Flat and Popup FlatStyle
630                 protected virtual void DrawFlatStyleCheckBox (Graphics graphics, Rectangle rectangle, CheckBox checkbox)
631                 {
632                         Pen                     pen;                    
633                         Rectangle       rect;
634                         Rectangle       checkbox_rectangle;
635                         Rectangle       fill_rectangle;
636                         int                     lineWidth;
637                         int                     Scale;
638                         
639                         // set up our rectangles first
640                         if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered) {
641                                 // clip one pixel from bottom right for non popup rendered checkboxes
642                                 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-1, 0), Math.Max(rectangle.Height-1,0));
643                                 fill_rectangle = new Rectangle(checkbox_rectangle.X+1, checkbox_rectangle.Y+1, Math.Max(checkbox_rectangle.Width-3, 0), Math.Max(checkbox_rectangle.Height-3,0));
644                         } else {
645                                 // clip two pixels from bottom right for non popup rendered checkboxes
646                                 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-2, 0), Math.Max(rectangle.Height-2,0));
647                                 fill_rectangle = new Rectangle(checkbox_rectangle.X+1, checkbox_rectangle.Y+1, Math.Max(checkbox_rectangle.Width-2, 0), Math.Max(checkbox_rectangle.Height-2,0));
648                         }       
649                                 
650                         // if disabled render in disabled state
651                         if (checkbox.Enabled) {
652                                 // process the state of the checkbox
653                                 if (checkbox.is_entered || checkbox.Capture) {
654                                         // decide on which background color to use
655                                         if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered && checkbox.Capture) {
656                                                 graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
657                                         } else if (checkbox.FlatStyle == FlatStyle.Flat && !(checkbox.is_entered && checkbox.Capture)) {
658                                                 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.Light(checkbox.BackColor)), fill_rectangle);
659                                         } else {
660                                                 // use regular window background color
661                                                 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
662                                         }
663                                         
664                                         // render the outer border
665                                         if (checkbox.FlatStyle == FlatStyle.Flat) {
666                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
667                                         } else {
668                                                 // draw sunken effect
669                                                 CPDrawBorder3D (graphics, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.All, checkbox.BackColor);
670                                         }
671                                 } else {
672                                         graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);                           
673                                         
674                                         if (checkbox.FlatStyle == FlatStyle.Flat) {
675                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
676                                         } else {
677                                                 // draw the outer border
678                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ControlPaint.DarkDark (checkbox.BackColor), ButtonBorderStyle.Solid);
679                                         }                       
680                                 }
681                         } else {
682                                 if (checkbox.FlatStyle == FlatStyle.Popup) {
683                                         graphics.FillRectangle(SystemBrushes.Control, fill_rectangle);
684                                 }       
685                         
686                                 // draw disabled state,
687                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ColorControlDark, ButtonBorderStyle.Solid);
688                         }               
689                         
690                         /* Make sure we've got at least a line width of 1 */
691                         lineWidth = Math.Max(3, fill_rectangle.Width/3);
692                         Scale=Math.Max(1, fill_rectangle.Width/9);
693                         
694                         // flat style check box is rendered inside a rectangle shifted down by one
695                         rect=new Rectangle(fill_rectangle.X, fill_rectangle.Y+1, fill_rectangle.Width, fill_rectangle.Height);
696                         if (checkbox.Enabled) {
697                                 pen=ResPool.GetPen(checkbox.ForeColor);
698                         } else {
699                                 pen=SystemPens.ControlDark;
700                         }
701
702                         if (checkbox.Checked) {
703                                 /* Need to draw a check-mark */
704                                 for (int i=0; i<lineWidth; i++) {
705                                         graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
706                                         graphics.DrawLine(pen, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i, rect.Left+lineWidth/2+6*Scale, rect.Top+lineWidth-2*Scale+i);
707                                 }
708                         }                                       
709                 }
710
711
712                 #endregion      // CheckBox
713                 
714                 #region CheckedListBox
715                 
716                 public override Rectangle CheckedListBoxCheckRectangle ()
717                 {
718                         return checkbox_rect;
719                 }
720                 
721                 public override void DrawCheckedListBoxItem (CheckedListBox ctrl, DrawItemEventArgs e)
722                 {                       
723                         Color back_color, fore_color;
724                         Rectangle item_rect = e.Bounds;
725                         ButtonState state;
726                         StringFormat string_format = ctrl.GetFormatString ();
727
728                         /* Draw checkbox */             
729
730                         if ((ctrl.Items.GetListBoxItem (e.Index)).State == CheckState.Checked)
731                                 state = ButtonState.Checked;
732                         else
733                                 state = ButtonState.Normal;
734
735                         if (ctrl.ThreeDCheckBoxes == false)
736                                 state |= ButtonState.Flat;
737
738                         ControlPaint.DrawCheckBox (e.Graphics,
739                                 item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y,
740                                 checkbox_rect.Width, checkbox_rect.Height,
741                                 state);
742
743                         item_rect.X += checkbox_rect.Width + checkbox_rect.X * 2;
744                         item_rect.Width -= checkbox_rect.Width + checkbox_rect.X * 2;
745                         
746                         /* Draw text*/
747                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
748                                 back_color = ThemeEngine.Current.ColorHighlight;
749                                 fore_color = ThemeEngine.Current.ColorHighlightText;
750                         }
751                         else {
752                                 back_color = e.BackColor;
753                                 fore_color = e.ForeColor;
754                         }
755                         
756                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
757                                 (back_color), item_rect);
758
759                         e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
760                                 ThemeEngine.Current.ResPool.GetSolidBrush (fore_color),
761                                 item_rect, string_format);
762                                         
763                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
764                                 ThemeEngine.Current.CPDrawFocusRectangle (e.Graphics, item_rect,
765                                         fore_color, back_color);
766                         }
767                 }
768                 
769                 #endregion // CheckedListBox
770                 
771                 #region ComboBox
772                 
773                 // Drawing
774                 
775                 public override void DrawComboBoxEditDecorations (Graphics dc, ComboBox ctrl, Rectangle cl)
776                 {                               
777                         dc.DrawLine (ResPool.GetPen (ColorControlDark), cl.X, cl.Y, cl.X + cl.Width, cl.Y); //top 
778                         dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), cl.X + 1, cl.Y + 1, cl.X + cl.Width - 2, cl.Y + 1);
779                         dc.DrawLine (ResPool.GetPen (ColorControl), cl.X, cl.Y + cl.Height - 2, cl.X + cl.Width, cl.Y + cl.Height - 2); //down
780                         dc.DrawLine (ResPool.GetPen (ColorControlLight), cl.X, cl.Y + cl.Height - 1, cl.X + cl.Width, cl.Y + cl.Height - 1);
781                         dc.DrawLine (ResPool.GetPen (ColorControlDark), cl.X, cl.Y, cl.X, cl.Y + cl.Height); //left
782                         dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), cl.X + 1, cl.Y + 1, cl.X + 1, cl.Y + cl.Height - 2); 
783                         dc.DrawLine (ResPool.GetPen (ColorControl), cl.X + cl.Width - 2, cl.Y, cl.X + cl.Width - 2, cl.Y + cl.Height); //right
784                         dc.DrawLine (ResPool.GetPen (ColorControlLight), cl.X + cl.Width - 1, cl.Y + 1 , cl.X + cl.Width - 1, cl.Y + cl.Height - 1);                            
785                 }               
786                 
787                 // Sizing                               
788                 public override int DrawComboBoxEditDecorationTop () { return 2;}
789                 public override int DrawComboBoxEditDecorationBottom () { return 2;}
790                 public override int DrawComboBoxEditDecorationRight () { return 2;}
791                 public override int DrawComboBoxEditDecorationLeft () { return 2;}
792                 
793                 private int DrawComboListBoxDecoration (ComboBoxStyle style)
794                 {
795                         if (style == ComboBoxStyle.Simple)
796                                 return 2;
797                         else
798                                 return 1;
799                 }
800                                 
801                 public override int DrawComboListBoxDecorationTop (ComboBoxStyle style) 
802                 {
803                         return DrawComboListBoxDecoration (style);
804                 }
805                 
806                 public override int DrawComboListBoxDecorationBottom (ComboBoxStyle style)
807                 {
808                         return DrawComboListBoxDecoration (style);
809                 }
810                 
811                 public override int DrawComboListBoxDecorationRight (ComboBoxStyle style)
812                 {
813                         return DrawComboListBoxDecoration (style);
814                 }
815                 
816                 public override int DrawComboListBoxDecorationLeft (ComboBoxStyle style)
817                 {
818                         return DrawComboListBoxDecoration (style);
819                 }
820                 
821                 public override void DrawComboListBoxDecorations (Graphics dc, ComboBox ctrl, Rectangle cl)
822                 {
823                         if (ctrl.DropDownStyle == ComboBoxStyle.Simple) {
824                                 DrawComboBoxEditDecorations (dc, ctrl, cl);
825                         }
826                         else {                  
827                                 dc.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorWindowFrame),
828                                         cl.X, cl.Y, cl.Width - 1, cl.Height - 1);
829                         }                       
830                 }
831                 
832                 public override void DrawComboBoxItem (ComboBox ctrl, DrawItemEventArgs e)
833                 {
834                         Color back_color, fore_color;
835                         Rectangle text_draw = e.Bounds;
836                         StringFormat string_format = new StringFormat ();
837                         string_format.FormatFlags = StringFormatFlags.LineLimit;
838                         
839                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
840                                 back_color = ThemeEngine.Current.ColorHighlight;
841                                 fore_color = ThemeEngine.Current.ColorHighlightText;
842                         }
843                         else {
844                                 back_color = e.BackColor;
845                                 fore_color = e.ForeColor;
846                         }                       
847                                                         
848                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (back_color), e.Bounds);
849
850                         if (e.Index != -1) {
851                                 e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
852                                         ThemeEngine.Current.ResPool.GetSolidBrush (fore_color),
853                                         text_draw, string_format);
854                         }
855                         
856                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
857                                 ThemeEngine.Current.CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
858                         }
859
860                         string_format.Dispose ();
861                 }
862                 
863                 #endregion ComboBox
864                 
865                 #region Datagrid
866                 public override int DataGridPreferredColumnWidth { get { return 75;} }
867                 public override int DataGridMinimumColumnCheckBoxHeight { get { return 16;} }
868                 public override int DataGridMinimumColumnCheckBoxWidth { get { return 16;} }
869                 public override Color DataGridAlternatingBackColor { get { return ColorWindow;} }
870                 public override Color DataGridBackColor { get  { return  ColorWindow;} }                
871                 public override Color DataGridBackgroundColor { get  { return  ColorAppWorkspace;} }
872                 public override Color DataGridCaptionBackColor { get  { return ColorActiveCaption;} }
873                 public override Color DataGridCaptionForeColor { get  { return ColorActiveCaptionText;} }
874                 public override Color DataGridGridLineColor { get { return ColorControl;} }
875                 public override Color DataGridHeaderBackColor { get  { return ColorControl;} }
876                 public override Color DataGridHeaderForeColor { get  { return ColorControlText;} }
877                 public override Color DataGridLinkColor { get  { return ColorHotTrack;} }
878                 public override Color DataGridLinkHoverColor { get  { return ColorHotTrack;} }
879                 public override Color DataGridParentRowsBackColor { get  { return ColorControl;} }
880                 public override Color DataGridParentRowsForeColor { get  { return ColorWindowText;} }
881                 public override Color DataGridSelectionBackColor { get  { return ColorActiveCaption;} }
882                 public override Color DataGridSelectionForeColor { get  { return ColorActiveCaptionText;} }
883                 
884                 public override void DataGridPaint (PaintEventArgs pe, DataGrid grid)
885                 {
886                         // Draw parent rows
887                         if (pe.ClipRectangle.IntersectsWith (grid.grid_drawing.parent_rows)) {
888                                 pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor), grid.grid_drawing.parent_rows);
889                         }
890
891                         DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid);
892                         DataGridPaintColumnsHdrs (pe.Graphics, pe.ClipRectangle, grid);
893                         DataGridPaintRowsHeaders (pe.Graphics, pe.ClipRectangle, grid);
894                         DataGridPaintRows (pe.Graphics, grid.grid_drawing.cells_area, pe.ClipRectangle, grid);
895
896                         // Paint scrollBar corner
897                         if (grid.vert_scrollbar.Visible && grid.horiz_scrollbar.Visible) {
898
899                                 Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.horiz_scrollbar.Height,
900                                          grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.horiz_scrollbar.Height,
901                                          grid.horiz_scrollbar.Height, grid.horiz_scrollbar.Height);
902
903                                 if (pe.ClipRectangle.IntersectsWith (corner)) {
904                                         pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
905                                                 corner);
906                                 }
907                         }
908                 }
909                 
910                 public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid)
911                 {
912                         Rectangle modified_area = clip;
913                         modified_area.Intersect (grid.grid_drawing.caption_area);
914
915                         g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor),
916                                 modified_area);
917
918                         g.DrawString (grid.CaptionText, grid.CaptionFont,
919                                 ThemeEngine.Current.ResPool.GetSolidBrush (grid.CaptionForeColor),
920                                 grid.grid_drawing.caption_area);                
921                 }
922
923                 public override void DataGridPaintColumnsHdrs (Graphics g, Rectangle clip, DataGrid grid)
924                 {
925                         Rectangle columns_area = grid.grid_drawing.columnshdrs_area;
926
927                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { // Paint corner shared between row and column header
928                                 Rectangle rect_bloc = grid.grid_drawing.columnshdrs_area;
929                                 rect_bloc.Width = grid.RowHeaderWidth;
930                                 rect_bloc.Height = grid.grid_drawing.columnshdrs_area.Height;
931                                 if (clip.IntersectsWith (rect_bloc)) {
932                                         if (grid.visiblecolumn_count > 0) {
933                                                 g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc);
934                                         }else {
935                                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), rect_bloc);
936                                         }
937                                 }
938
939                                 columns_area.X += grid.RowHeaderWidth;
940                                 columns_area.Width -= grid.RowHeaderWidth;
941                         }
942
943                         // Set unused area
944                         Rectangle columnshdrs_area_complete = columns_area;
945                         columnshdrs_area_complete.Width = grid.grid_drawing.columnshdrs_maxwidth;
946                         
947                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
948                                 columnshdrs_area_complete.Width -= grid.RowHeaderWidth;
949                         }               
950
951                         // Set column painting
952                         Rectangle rect_columnhdr = new Rectangle ();
953                         int col_pixel;
954                         Region current_clip;
955                         rect_columnhdr.Y = columns_area.Y;
956                         rect_columnhdr.Height = columns_area.Height;
957                         
958                         current_clip = new Region (columns_area);
959                         g.Clip = current_clip;
960                         int column_cnt = grid.first_visiblecolumn + grid.visiblecolumn_count;
961                         for (int column = grid.first_visiblecolumn; column < column_cnt; column++) {
962                                 
963                                 col_pixel = grid.grid_drawing.GetColumnStartingPixel (column);
964                                 rect_columnhdr.X = columns_area.X + col_pixel - grid.horz_pixeloffset;
965                                 rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
966
967                                 if (clip.IntersectsWith (rect_columnhdr) == false)
968                                         continue;
969
970                                 grid.CurrentTableStyle.GridColumnStyles[column].PaintHeader (g, rect_columnhdr, column);
971
972                                 
973                         }
974
975                         current_clip.Dispose ();
976                         g.ResetClip ();
977                         
978                         // This fills with background colour the unused part in the row headers
979                         if (rect_columnhdr.X + rect_columnhdr.Height < grid.ClientRectangle.X + grid.ClientRectangle.Width) {
980                                 
981                                 Rectangle not_usedarea = columnshdrs_area_complete;                             
982                                 not_usedarea.X = rect_columnhdr.X + rect_columnhdr.Width;
983                                 not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - rect_columnhdr.X - rect_columnhdr.Height;
984                         
985                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
986                                         not_usedarea);
987                         }
988                 }
989
990                 public override void DataGridPaintRowsHeaders (Graphics g, Rectangle clip, DataGrid grid)
991                 {
992                         Rectangle rowshdrs_area_complete = grid.grid_drawing.rowshdrs_area;
993                         rowshdrs_area_complete.Height = grid.grid_drawing.rowshdrs_maxheight;
994                         Rectangle rect_row = new Rectangle ();
995                         rect_row.X = grid.grid_drawing.rowshdrs_area.X;
996                         int last_y = 0;
997                         int rowcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
998
999                         if (rowcnt < grid.RowsCount) { // Paint one row more for partial rows
1000                                 rowcnt++;
1001                         }
1002
1003                         g.SetClip (grid.grid_drawing.rowshdrs_area);
1004                         for (int row = grid.FirstVisibleRow; row < rowcnt; row++) {
1005
1006                                 rect_row.Width = grid.grid_drawing.rowshdrs_area.Width;
1007                                 rect_row.Height = grid.RowHeight;
1008                                 rect_row.Y = grid.grid_drawing.rowshdrs_area.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
1009
1010                                 if (clip.IntersectsWith (rect_row)) {
1011                                         DataGridPaintRowHeader (g, rect_row, row, grid);
1012                                         last_y = rect_row.Y;
1013                                 }
1014                         }
1015                         
1016                         g.ResetClip ();
1017
1018                         // This fills with background colour the unused part in the row headers
1019                         if (last_y > 0 && rect_row.Y + rect_row.Height < grid.grid_drawing.cells_area.Y + grid.grid_drawing.cells_area.Height) {
1020                                 Rectangle not_usedarea = clip;
1021                                 not_usedarea.Intersect (rowshdrs_area_complete);
1022                                 
1023                                 not_usedarea.Y = rect_row.Y + rect_row.Height;
1024                                 not_usedarea.Height = rowshdrs_area_complete.Y + rowshdrs_area_complete.Height - rect_row.Height - rect_row.Y;
1025                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
1026                                         not_usedarea);
1027                         }                       
1028
1029                         
1030                 }
1031                 
1032                 public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid) 
1033                 {               
1034                         Point[] arrow = new Point[3];
1035                         Point P1, P2, P3;
1036                         int centerX, centerY, shiftX;                   
1037                         Rectangle rect;
1038                         
1039                         rect = new Rectangle (bounds.X + bounds.Width /4, 
1040                                 bounds.Y + bounds.Height/4, bounds.Width / 2, bounds.Height / 2);
1041                         
1042                         centerX = rect.Left + rect.Width / 2;
1043                         centerY = rect.Top + rect.Height / 2;
1044                         shiftX = Math.Max (1, rect.Width / 8);                  
1045                         rect.X -= shiftX;
1046                         centerX -= shiftX;                      
1047                         P1 = new Point (centerX, rect.Top - 1);
1048                         P2 = new Point (centerX, rect.Bottom);
1049                         P3 = new Point (rect.Right, centerY);                   
1050                         arrow[0] = P1;
1051                         arrow[1] = P2;
1052                         arrow[2] = P3;
1053                         
1054                         g.FillPolygon (ThemeEngine.Current.ResPool.GetSolidBrush 
1055                                 (grid.CurrentTableStyle.CurrentHeaderForeColor), arrow, FillMode.Winding);
1056                 }
1057
1058                 public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid)
1059                 {
1060                         // Background
1061                         g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor),
1062                                 bounds);
1063                                 
1064                         if (grid.FlatMode == false) {
1065                                 
1066                                 // Paint Borders
1067                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
1068                                         bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
1069         
1070                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
1071                                         bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
1072         
1073                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
1074                                         bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
1075         
1076                                 g.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
1077                                         bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
1078                         }
1079
1080                         if (grid.ShowEditRow && row == grid.RowsCount  && !(row == grid.CurrentCell.RowNumber && grid.is_changing == true)) {
1081                                 
1082                                 g.DrawString ("*", grid.grid_drawing.font_newrow, ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
1083                                         bounds);
1084                                 
1085                         } else {
1086                                 // Draw arrow
1087                                 if (row == grid.CurrentCell.RowNumber) {
1088         
1089                                         if (grid.is_changing == true) {
1090                                                 g.DrawString ("...", grid.Font,
1091                                                         ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
1092                                                         bounds);
1093         
1094                                         } else {
1095                                                 
1096                                                 Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);                                                                                        
1097                                                 DataGridPaintRowHeaderArrow (g, rect, grid);
1098                                         }
1099                                 }
1100                         }
1101                 }
1102                 
1103                 public override void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid)
1104                 {
1105                         Rectangle rect_row = new Rectangle ();
1106                         Rectangle not_usedarea = new Rectangle ();
1107                         rect_row.X = cells.X;
1108
1109                         int rowcnt = grid.FirstVisibleRow + grid.VisibleRowCount;
1110                         
1111                         if (grid.ShowEditRow) {
1112                                 rowcnt--;
1113                         }                       
1114
1115                         if (rowcnt < grid.RowsCount) { // Paint one row more for partial rows
1116                                 rowcnt++;
1117                         }                       
1118                         
1119                         rect_row.Height = grid.RowHeight;
1120                         rect_row.Width = cells.Width;
1121                         for (int row = grid.FirstVisibleRow; row < rowcnt; row++) {                                                             
1122                                 rect_row.Y = cells.Y + ((row - grid.FirstVisibleRow) * grid.RowHeight);
1123                                 if (clip.IntersectsWith (rect_row)) {
1124                                         DataGridPaintRow (g, row, rect_row, false, grid);
1125                                 }
1126                         }
1127                         
1128                         if (grid.ShowEditRow && grid.FirstVisibleRow + grid.VisibleRowCount == grid.RowsCount + 1) {
1129                                 rect_row.Y = cells.Y + ((rowcnt - grid.FirstVisibleRow) * grid.RowHeight);
1130                                 if (clip.IntersectsWith (rect_row)) {
1131                                         DataGridPaintRow (g, rowcnt, rect_row, true, grid);
1132                                 }
1133                         }
1134                         
1135                         not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height;
1136                         not_usedarea.Y = rect_row.Y + rect_row.Height;
1137                         not_usedarea.Width = rect_row.Width = cells.Width;
1138                         not_usedarea.X = cells.X;                       
1139
1140                         g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.BackgroundColor),
1141                                 not_usedarea);                  
1142                 }
1143                 
1144                 public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow, DataGrid grid)
1145                 {                       
1146                         Rectangle rect_cell = new Rectangle ();
1147                         int col_pixel;
1148                         Color backcolor, forecolor;
1149                         Region prev_clip = g.Clip;
1150                         Region current_clip;
1151                         Rectangle not_usedarea = new Rectangle ();
1152
1153                         rect_cell.Y = row_rect.Y;
1154                         rect_cell.Height = row_rect.Height;
1155
1156                         // PaintCells at row, column
1157                         int column_cnt = grid.first_visiblecolumn + grid.visiblecolumn_count;
1158                         for (int column = grid.first_visiblecolumn; column < column_cnt; column++) {
1159
1160                                 col_pixel = grid.grid_drawing.GetColumnStartingPixel (column);
1161
1162                                 rect_cell.X = row_rect.X + col_pixel - grid.horz_pixeloffset;
1163                                 rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
1164
1165                                 current_clip = new Region (row_rect);
1166                                 g.Clip = current_clip;
1167
1168                                 if (grid.IsSelected (row)) {
1169                                         backcolor =  grid.SelectionBackColor;
1170                                         forecolor =  grid.SelectionForeColor;
1171                                 } else {
1172                                         if (row % 2 == 0) {
1173                                                 backcolor =  grid.BackColor;
1174                                         } else {
1175                                                 backcolor =  grid.AlternatingBackColor;
1176                                         }
1177                                         
1178                                         forecolor =  grid.ForeColor;
1179                                 }                       
1180
1181                                 if (is_newrow) {
1182                                         grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, 
1183                                                 ThemeEngine.Current.ResPool.GetSolidBrush (backcolor),
1184                                                 ThemeEngine.Current.ResPool.GetSolidBrush (forecolor));                                         
1185                                         
1186                                 } else {
1187                                         grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
1188                                                 ThemeEngine.Current.ResPool.GetSolidBrush (backcolor),
1189                                                 ThemeEngine.Current.ResPool.GetSolidBrush (forecolor),
1190                                                 grid.RightToLeft == RightToLeft.Yes);
1191                                 }
1192
1193                                 g.Clip = prev_clip;
1194                                 current_clip.Dispose ();
1195                         }
1196                         
1197                         if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
1198
1199                                 not_usedarea.X = rect_cell.X + rect_cell.Width;
1200                                 not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
1201                                 not_usedarea.Y = row_rect.Y;
1202                                 not_usedarea.Height = row_rect.Height;
1203                                 g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.BackgroundColor),
1204                                         not_usedarea);
1205                         }
1206                 }
1207                 
1208                 #endregion // Datagrid
1209                 
1210                 #region DateTimePicker
1211         
1212                 public override void DrawDateTimePicker (Graphics dc,  Rectangle clip_rectangle, DateTimePicker dtp) {
1213                         // if not showing the numeric updown control then render border
1214                         if (!dtp.ShowUpDown && clip_rectangle.IntersectsWith (dtp.ClientRectangle)) {
1215                                 // draw the outer border
1216                                 Rectangle button_bounds = dtp.ClientRectangle;
1217                                 this.CPDrawBorder3D (dc, button_bounds, Border3DStyle.Sunken, Border3DSide.All, dtp.BackColor);
1218                                 
1219                                 // deflate by the border width
1220                                 if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) {
1221                                         button_bounds.Inflate (-2,-2);
1222                                         ButtonState state = dtp.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal;
1223                                         this.CPDrawComboButton ( 
1224                                           dc, 
1225                                           dtp.drop_down_arrow_rect, 
1226                                           state);
1227                                 }
1228                         }
1229
1230                         // render the date part
1231                         if (clip_rectangle.IntersectsWith (dtp.date_area_rect)) {
1232                                 // fill the background
1233                                 dc.FillRectangle (ResPool.GetSolidBrush (ThemeEngine.Current.ColorWindow), dtp.date_area_rect);
1234                                 
1235                                 // fill the currently highlighted area
1236                                 if (dtp.hilight_date_area != Rectangle.Empty) {
1237                                         dc.FillRectangle (ResPool.GetSolidBrush (ThemeEngine.Current.ColorHighlight), dtp.hilight_date_area);
1238                                 }
1239                                 
1240                                 // draw the text part
1241                                 // TODO: if date format is CUstom then we need to draw the dates as separate parts
1242                                 StringFormat text_format = new StringFormat();
1243                                 text_format.LineAlignment = StringAlignment.Center;
1244                                 text_format.Alignment = StringAlignment.Near;                                   
1245                                 dc.DrawString (dtp.Text, dtp.Font, ResPool.GetSolidBrush (dtp.ForeColor), Rectangle.Inflate(dtp.date_area_rect, -1, -1), text_format);
1246                                 text_format.Dispose ();
1247                         }
1248                 }
1249                 
1250                 #endregion // DateTimePicker
1251
1252                 #region GroupBox
1253                 public override void DrawGroupBox (Graphics dc,  Rectangle area, GroupBox box) {
1254                         StringFormat    text_format;
1255                         SizeF           size;
1256                         int             width;
1257                         int             y;
1258                         Rectangle       rect;
1259
1260                         rect = box.ClientRectangle;
1261
1262                         // Needed once the Dark/Light code below is enabled again
1263                         //Color disabled = ColorGrayText;
1264                         
1265                         Pen pen_light = ResPool.GetPen (Color.FromArgb (255,255,255,255));
1266                         Pen pen_dark = ResPool.GetPen (Color.FromArgb (255, 128, 128,128));
1267                         
1268                         // TODO: When the Light and Dark methods work this code should be activate it
1269                         //Pen pen_light = new Pen (ControlPaint.Light (disabled, 1));
1270                         //Pen pen_dark = new Pen (ControlPaint.Dark (disabled, 0));
1271
1272                         dc.FillRectangle (ResPool.GetSolidBrush (box.BackColor), rect);
1273
1274                         text_format = new StringFormat();
1275                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
1276
1277                         size = dc.MeasureString (box.Text, box.Font);
1278                         width = (int) size.Width;
1279                         
1280                         if (width > box.Width - 16)
1281                                 width = box.Width - 16;
1282                         
1283                         y = box.Font.Height / 2;
1284                         
1285                         /* Draw group box*/
1286                         dc.DrawLine (pen_dark, 0, y, 8, y); // top 
1287                         dc.DrawLine (pen_light, 0, y + 1, 8, y + 1);                    
1288                         dc.DrawLine (pen_dark, 8 + width, y, box.Width, y);                     
1289                         dc.DrawLine (pen_light, 8 + width, y + 1, box.Width, y + 1);
1290                         
1291                         dc.DrawLine (pen_dark, 0, y + 1, 0, box.Height); // left
1292                         dc.DrawLine (pen_light, 1, y + 1, 1, box.Height);                       
1293                         
1294                         dc.DrawLine (pen_dark, 0, box.Height - 2, box.Width,  box.Height - 2); // bottom
1295                         dc.DrawLine (pen_light, 0, box.Height - 1, box.Width,  box.Height - 1);
1296                         
1297                         dc.DrawLine (pen_dark, box.Width - 2, y,  box.Width - 2, box.Height - 2); // right
1298                         dc.DrawLine (pen_light, box.Width - 1, y, box.Width - 1, box.Height - 2);
1299                         
1300                         
1301                         /* Text */
1302                         if (box.Enabled) {
1303                                 dc.DrawString (box.Text, box.Font, ResPool.GetSolidBrush (box.ForeColor), 10, 0, text_format);
1304                         } else {
1305                                 CPDrawStringDisabled (dc, box.Text, box.Font, box.ForeColor, 
1306                                         new RectangleF (10, 0, width,  box.Font.Height), text_format);
1307                         }
1308                         text_format.Dispose (); 
1309                 }
1310
1311                 public override Size GroupBoxDefaultSize {
1312                         get {
1313                                 return new Size (200,100);
1314                         }
1315                 }
1316                 #endregion
1317
1318                 #region HScrollBar
1319                 public override Size HScrollBarDefaultSize {
1320                         get {
1321                                 return new Size (80, this.ScrollBarButtonSize);
1322                         }
1323                 }
1324
1325                 #endregion      // HScrollBar
1326
1327                 #region Label
1328                 public  override void DrawLabel (Graphics dc, Rectangle clip_rectangle, Label label) 
1329                 {               
1330                         dc.FillRectangle (ResPool.GetSolidBrush (label.BackColor), clip_rectangle);
1331
1332                         if (label.Enabled) {
1333                                 dc.DrawString (label.Text, label.Font, ResPool.GetSolidBrush (label.ForeColor), clip_rectangle, label.string_format);
1334                         } else {
1335                                 ControlPaint.DrawStringDisabled (dc, label.Text, label.Font, label.ForeColor, clip_rectangle, label.string_format);
1336                         }
1337                 
1338                 }
1339
1340                 public override Size LabelDefaultSize {
1341                         get {
1342                                 return new Size (100, 23);
1343                         }
1344                 }
1345                 #endregion      // Label
1346
1347                 #region LinkLabel
1348                 public  override void DrawLinkLabel (Graphics dc, Rectangle clip_rectangle, LinkLabel label)
1349                 {
1350                         Color color;
1351
1352                         dc.FillRectangle (ResPool.GetSolidBrush (label.BackColor), clip_rectangle);
1353
1354                         for (int i = 0; i < label.num_pieces; i++) {
1355                                 
1356                                 if (clip_rectangle.IntersectsWith (label.pieces[i].rect) == false) {
1357                                         continue;
1358                                 }                               
1359                                 
1360                                 color = label.GetLinkColor (label.pieces[i], i);
1361
1362                                 if (label.pieces[i].link == null)
1363                                         dc.DrawString (label.pieces[i].text, label.GetPieceFont (label.pieces[i]), ResPool.GetSolidBrush (Color.Black),
1364                                                 label.pieces[i].rect.X, label.pieces[i].rect.Y);
1365                                 else
1366                                         dc.DrawString (label.pieces[i].text, label.GetPieceFont (label.pieces[i]), ResPool.GetSolidBrush (color),
1367                                                 label.pieces[i].rect.X, label.pieces[i].rect.Y);
1368                                                 
1369                                 if (label.pieces[i].focused) {                                  
1370                                         CPDrawFocusRectangle (dc, label.pieces[i].rect, label.ForeColor, label.BackColor);
1371                                 }
1372                         }                       
1373                         
1374                 }
1375                 #endregion      // LinkLabel
1376                 #region ListBox
1377                 
1378                 // Drawing              
1379                 
1380                 private int DrawListBoxDecorationSize (BorderStyle border_style)
1381                 {
1382                         switch (border_style) {
1383                                 case BorderStyle.Fixed3D:
1384                                         return 2;
1385                                 case BorderStyle.FixedSingle:                                   
1386                                         return 1;
1387                                 case BorderStyle.None:
1388                                 default:
1389                                         break;
1390                                 }
1391                                 
1392                         return 0;
1393                 }                       
1394                 
1395                 // Sizing                               
1396                 public override void DrawListBoxItem (ListBox ctrl, DrawItemEventArgs e)
1397                 {
1398                         Color back_color, fore_color;
1399                         StringFormat string_format = ctrl.GetFormatString ();
1400                         
1401                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1402                                 back_color = ThemeEngine.Current.ColorHighlight;
1403                                 fore_color = ThemeEngine.Current.ColorHighlightText;
1404                         }
1405                         else {
1406                                 back_color = e.BackColor;
1407                                 fore_color = e.ForeColor;
1408                         }
1409                         
1410                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
1411                                 (back_color), e.Bounds);
1412
1413                         e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1414                                 ThemeEngine.Current.ResPool.GetSolidBrush (fore_color),
1415                                 e.Bounds.X, e.Bounds.Y, string_format);
1416                                         
1417                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1418                                 ThemeEngine.Current.CPDrawFocusRectangle (e.Graphics, e.Bounds,
1419                                         fore_color, back_color);
1420                         }
1421                 }
1422                 
1423                 #endregion ListBox
1424
1425                 #region ListView
1426                 // Drawing
1427                 public override void DrawListView (Graphics dc, Rectangle clip, ListView control)
1428                 {
1429                         bool details = (control.View == View.Details);
1430                         Rectangle client_area_nohdrs;                   
1431                         DrawListViewHeader (dc, clip, control);
1432                         
1433                         if (details && control.Columns.Count > 0) {
1434                                 client_area_nohdrs = control.client_area;
1435                                 client_area_nohdrs.Y += control.Columns[0].Ht;
1436                                 client_area_nohdrs.Height -= control.Columns[0].Ht;
1437                                 dc.SetClip (client_area_nohdrs);                                
1438                         } else
1439                                 dc.SetClip (control.client_area);
1440                         
1441                         dc.FillRectangle (ResPool.GetSolidBrush (control.BackColor), clip);                                             
1442                                                 
1443                         // In case of details view draw the items only if
1444                         // columns are non-zero                 
1445                         if (!details || control.Columns.Count > 0) {
1446                                 int first = control.FirstVisibleIndex;  
1447                                 
1448                                 for (int i = first; i <= control.LastItemIndex; i ++) {                                 
1449                                         if (clip.IntersectsWith (control.Items[i].GetBounds (ItemBoundsPortion.Entire)))
1450                                                 DrawListViewItem (dc, control, control.Items[i]);
1451                                 }                               
1452                         }       
1453                         
1454                         // draw the gridlines
1455                         if (details && control.GridLines) {
1456                                 int top = (control.HeaderStyle == ColumnHeaderStyle.None) ?
1457                                         2 : control.Font.Height + 2;
1458
1459                                 // draw vertical gridlines
1460                                 foreach (ColumnHeader col in control.Columns)
1461                                         dc.DrawLine (this.ResPool.GetPen (this.ColorControl),
1462                                                      col.Rect.Right, top,
1463                                                      col.Rect.Right, control.TotalHeight);
1464                                 // draw horizontal gridlines
1465                                 ListViewItem last_item = null;
1466                                 foreach (ListViewItem item in control.Items) {
1467                                         dc.DrawLine (this.ResPool.GetPen (this.ColorControl),
1468                                                      item.GetBounds (ItemBoundsPortion.Entire).Left, item.GetBounds (ItemBoundsPortion.Entire).Top,
1469                                                      control.TotalWidth, item.GetBounds (ItemBoundsPortion.Entire).Top);
1470                                         last_item = item;
1471                                 }
1472
1473                                 // draw a line after at the bottom of the last item
1474                                 if (last_item != null) {
1475                                         dc.DrawLine (this.ResPool.GetPen (this.ColorControl),
1476                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Left,
1477                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Bottom,
1478                                                      control.TotalWidth,
1479                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Bottom);
1480                                 }
1481                         }                       
1482                         
1483                         dc.ResetClip ();
1484                         
1485                         // Draw corner between the two scrollbars
1486                         if (control.h_scroll.Visible == true && control.h_scroll.Visible == true) {
1487                                 Rectangle rect = new Rectangle ();
1488                                 rect.X = control.h_scroll.Location.X + control.h_scroll.Width;
1489                                 rect.Width = control.v_scroll.Width;
1490                                 rect.Y = control.v_scroll.Location.Y + control.v_scroll.Height;
1491                                 rect.Height = control.h_scroll.Height;
1492                                 dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), rect);
1493                         }
1494
1495                 }
1496                 
1497                 private void DrawListViewHeader (Graphics dc, Rectangle clip, ListView control)
1498                 {       
1499                         bool details = (control.View == View.Details);
1500                                 
1501                         // border is drawn directly in the Paint method
1502                         if (details && control.HeaderStyle != ColumnHeaderStyle.None) {                         
1503                                 dc.FillRectangle (ResPool.GetSolidBrush (control.BackColor),
1504                                                   0, 0, control.TotalWidth, control.Font.Height + 5);
1505                                 if (control.Columns.Count > 0) {
1506                                         if (control.HeaderStyle == ColumnHeaderStyle.Clickable) {
1507                                                 foreach (ColumnHeader col in control.Columns) {
1508                                                         Rectangle rect = col.Rect;
1509                                                         rect.X -= control.h_marker;
1510                                                         this.CPDrawButton (dc, rect,
1511                                                                            (col.Pressed ?
1512                                                                             ButtonState.Pushed :
1513                                                                             ButtonState.Normal));
1514                                                         dc.DrawString (col.Text, ThemeEngine.Current.DefaultFont,
1515                                                                        ResPool.GetSolidBrush
1516                                                                        (this.ColorControlText),
1517                                                                         rect.X + 3,
1518                                                                         rect.Y + rect.Height/2 + 1,
1519                                                                         col.Format);
1520                                                 }
1521                                         }
1522                                         // Non-clickable columns
1523                                         else {
1524                                                 foreach (ColumnHeader col in control.Columns) {
1525                                                         Rectangle rect = col.Rect;
1526                                                         rect.X -= control.h_marker;
1527                                                         this.CPDrawButton (dc, rect, ButtonState.Flat);
1528                                                         dc.DrawString (col.Text, ThemeEngine.Current.DefaultFont,
1529                                                                        ResPool.GetSolidBrush
1530                                                                        (this.ColorControlText),
1531                                                                         rect.X + 3,
1532                                                                         rect.Y + rect.Height/2 + 1,
1533                                                                         col.Format);
1534                                                 }
1535                                         }
1536                                 }
1537                         }
1538                 }
1539
1540                 // draws the ListViewItem of the given index
1541                 private void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
1542                 {                               
1543                         Rectangle rect_checkrect = item.CheckRectReal;
1544                         Rectangle rect_iconrect = item.GetBounds (ItemBoundsPortion.Icon);
1545                         Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire);
1546                         Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);                 
1547                         
1548                         if (control.CheckBoxes) {
1549                                 if (control.StateImageList == null) {
1550                                         // Make sure we've got at least a line width of 1
1551                                         int check_wd = Math.Max (3, rect_checkrect.Width / 6);
1552                                         int scale = Math.Max (1, rect_checkrect.Width / 12);
1553
1554                                         // set the checkbox background
1555                                         dc.FillRectangle (this.ResPool.GetSolidBrush (this.ColorWindow),
1556                                                           rect_checkrect);
1557                                         // define a rectangle inside the border area
1558                                         Rectangle rect = new Rectangle (rect_checkrect.X + 2,
1559                                                                         rect_checkrect.Y + 2,
1560                                                                         rect_checkrect.Width - 4,
1561                                                                         rect_checkrect.Height - 4);
1562                                         Pen pen = new Pen (this.ColorWindowText, 2);
1563                                         dc.DrawRectangle (pen, rect);
1564
1565                                         // Need to draw a check-mark
1566                                         if (item.Checked) {
1567                                                 pen.Width = 1;
1568                                                 // adjustments to get the check-mark at the right place
1569                                                 rect.X ++; rect.Y ++;
1570                                                 // following logic is taken from DrawFrameControl method
1571                                                 for (int i = 0; i < check_wd; i++) {
1572                                                         dc.DrawLine (pen, rect.Left + check_wd / 2,
1573                                                                      rect.Top + check_wd + i,
1574                                                                      rect.Left + check_wd / 2 + 2 * scale,
1575                                                                      rect.Top + check_wd + 2 * scale + i);
1576                                                         dc.DrawLine (pen,
1577                                                                      rect.Left + check_wd / 2 + 2 * scale,
1578                                                                      rect.Top + check_wd + 2 * scale + i,
1579                                                                      rect.Left + check_wd / 2 + 6 * scale,
1580                                                                      rect.Top + check_wd - 2 * scale + i);
1581                                                 }
1582                                         }
1583                                 }
1584                                 else {
1585                                         if (item.Checked && control.StateImageList.Images.Count > 1)
1586                                                 control.StateImageList.Draw (dc,
1587                                                                              rect_checkrect.Location, 1);
1588                                         else if (! item.Checked && control.StateImageList.Images.Count > 0)
1589                                                 control.StateImageList.Draw (dc,
1590                                                                              rect_checkrect.Location, 0);
1591                                 }
1592                         }
1593
1594                         // Item is drawn as a special case, as it is not just text
1595                         if (control.View == View.LargeIcon) {
1596                                 if (item.ImageIndex > -1 &&
1597                                     control.LargeImageList != null &&
1598                                     item.ImageIndex < control.LargeImageList.Images.Count)
1599                                         control.LargeImageList.Draw (dc, rect_iconrect.Location,
1600                                                                      item.ImageIndex);
1601                         }
1602                         else {
1603                                 if (item.ImageIndex > -1 &&
1604                                     control.SmallImageList != null &&
1605                                     item.ImageIndex < control.SmallImageList.Images.Count)
1606                                         control.SmallImageList.Draw (dc, rect_iconrect.Location,
1607                                                                      item.ImageIndex);
1608                         }
1609
1610                         // draw the item text                   
1611                         // format for the item text
1612                         StringFormat format = new StringFormat ();
1613                         format.LineAlignment = StringAlignment.Center;
1614                         if (control.View == View.LargeIcon)
1615                                 format.Alignment = StringAlignment.Center;
1616                         else
1617                                 format.Alignment = StringAlignment.Near;
1618                         
1619                         if (!control.LabelWrap)
1620                                 format.FormatFlags = StringFormatFlags.NoWrap;
1621                         
1622                         if (item.Selected) {
1623                                 if (control.View == View.Details) {
1624                                         if (control.FullRowSelect) {
1625                                                 // fill the entire rect excluding the checkbox                                          
1626                                                 full_rect.Location = item.LabelRect.Location;
1627                                                 dc.FillRectangle (this.ResPool.GetSolidBrush
1628                                                                   (this.ColorHighlight), full_rect);
1629                                         }
1630                                         else {
1631                                                 Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
1632                                                                                                 item.Font));
1633                                                 text_rect.Width = text_size.Width;
1634                                                 dc.FillRectangle (this.ResPool.GetSolidBrush
1635                                                                   (this.ColorHighlight), text_rect);
1636                                         }
1637                                 }
1638                                 else {
1639                                         /*Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
1640                                           item.Font));
1641                                           Point loc = text_rect.Location;
1642                                           loc.X += (text_rect.Width - text_size.Width) / 2;
1643                                           text_rect.Width = text_size.Width;*/
1644                                         dc.FillRectangle (this.ResPool.GetSolidBrush (this.ColorHighlight),
1645                                                           text_rect);
1646                                 }
1647                         }
1648                         else
1649                                 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
1650
1651                         if (item.Text != null && item.Text.Length > 0) {
1652                                 if (item.Selected)
1653                                         dc.DrawString (item.Text, item.Font, this.ResPool.GetSolidBrush
1654                                                        (this.ColorHighlightText), text_rect, format);
1655                                 else
1656                                         dc.DrawString (item.Text, item.Font, this.ResPool.GetSolidBrush
1657                                                        (item.ForeColor), text_rect, format);
1658                         }
1659
1660                         if (control.View == View.Details && control.Columns.Count > 0) {
1661                                 // draw subitems for details view
1662                                 ListViewItem.ListViewSubItemCollection subItems = item.SubItems;
1663                                 int count = (control.Columns.Count < subItems.Count ? 
1664                                              control.Columns.Count : subItems.Count);
1665
1666                                 if (count > 0) {
1667                                         ColumnHeader col;
1668                                         ListViewItem.ListViewSubItem subItem;
1669                                         Rectangle sub_item_rect = text_rect; 
1670
1671                                         // set the format for subitems
1672                                         format.FormatFlags = StringFormatFlags.NoWrap;
1673                                         format.Alignment = StringAlignment.Near;
1674
1675                                         // 0th subitem is the item already drawn
1676                                         for (int index = 1; index < count; index++) {
1677                                                 subItem = subItems [index];
1678                                                 col = control.Columns [index];
1679                                                 sub_item_rect.X = col.Rect.Left;
1680                                                 sub_item_rect.Width = col.Wd;
1681                                                 sub_item_rect.X -= control.h_marker;
1682
1683                                                 SolidBrush sub_item_back_br = null;
1684                                                 SolidBrush sub_item_fore_br = null;
1685                                                 Font sub_item_font = null;
1686
1687                                                 if (item.UseItemStyleForSubItems) {
1688                                                         sub_item_back_br = this.ResPool.GetSolidBrush
1689                                                                 (item.BackColor);
1690                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
1691                                                                 (item.ForeColor);
1692                                                         sub_item_font = item.Font;
1693                                                 }
1694                                                 else {
1695                                                         sub_item_back_br = this.ResPool.GetSolidBrush
1696                                                                 (subItem.BackColor);
1697                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
1698                                                                 (subItem.ForeColor);
1699                                                         sub_item_font = subItem.Font;
1700                                                 }
1701
1702                                                 // In case of fullrowselect, background is filled
1703                                                 // for the entire rect above
1704                                                 if (item.Selected && control.FullRowSelect) {
1705                                                         if (subItem.Text != null && subItem.Text.Length > 0)
1706                                                                 dc.DrawString (subItem.Text, sub_item_font,
1707                                                                                this.ResPool.GetSolidBrush
1708                                                                                (this.ColorHighlightText),
1709                                                                                sub_item_rect, format);
1710                                                 }
1711                                                 else {
1712                                                         dc.FillRectangle (sub_item_back_br, sub_item_rect);
1713                                                         if (subItem.Text != null && subItem.Text.Length > 0)
1714                                                                 dc.DrawString (subItem.Text, sub_item_font,
1715                                                                                sub_item_fore_br,
1716                                                                                sub_item_rect, format);
1717                                                 }
1718                                                 sub_item_rect.X += col.Wd;
1719                                         }
1720                                 }
1721                         }
1722                         
1723                         if (item.Focused) {                             
1724                                 if (item.Selected)
1725                                         CPDrawFocusRectangle (dc, text_rect, ColorHighlightText, ColorHighlight);
1726                                 else
1727                                         CPDrawFocusRectangle (dc, text_rect, control.ForeColor, control.BackColor);
1728                         }
1729
1730                         format.Dispose ();
1731                 }
1732
1733                 // Sizing
1734                 public override Size ListViewCheckBoxSize {
1735                         get { return new Size (16, 16); }
1736                 }
1737
1738                 public override int ListViewColumnHeaderHeight {
1739                         get { return 16; }
1740                 }
1741
1742                 public override int ListViewDefaultColumnWidth {
1743                         get { return 60; }
1744                 }
1745
1746                 public override int ListViewVerticalSpacing {
1747                         get { return 22; }
1748                 }
1749
1750                 public override int ListViewEmptyColumnWidth {
1751                         get { return 10; }
1752                 }
1753
1754                 public override int ListViewHorizontalSpacing {
1755                         get { return 10; }
1756                 }
1757
1758                 public override Size ListViewDefaultSize {
1759                         get { return new Size (121, 97); }
1760                 }
1761                 #endregion      // ListView
1762                 
1763                 #region Menus
1764                 public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
1765                 {
1766                         item.X = x;
1767                         item.Y = y;
1768
1769                         if (item.Visible == false)
1770                                 return;
1771
1772                         if (item.Separator == true) {
1773                                 item.Height = SEPARATOR_HEIGHT / 2;
1774                                 item.Width = -1;
1775                                 return;
1776                         }
1777                         
1778                         if (item.MeasureEventDefined) {
1779                                 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
1780                                 item.PerformMeasureItem (mi);
1781                                 item.Height = mi.ItemHeight;
1782                                 item.Width = mi.ItemWidth;
1783                                 return;
1784                         } else {                
1785                                 SizeF size;
1786                                 size =  dc.MeasureString (item.Text, ThemeEngine.Current.MenuFont);
1787                                 item.Width = (int) size.Width;
1788                                 item.Height = (int) size.Height;
1789         
1790                                 if (!menuBar) {
1791                                         if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
1792                                                 item.XTab = ThemeEngine.Current.MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
1793                                                 size =  dc.MeasureString (" " + item.GetShortCutText (), ThemeEngine.Current.MenuFont);
1794                                                 item.Width += MENU_TAB_SPACE + (int) size.Width;
1795                                         }
1796         
1797                                         item.Width += 4 + (ThemeEngine.Current.MenuCheckSize.Width * 2);
1798                                 } else {
1799                                         item.Width += MENU_BAR_ITEMS_SPACE;
1800                                         x += item.Width;
1801                                 }
1802         
1803                                 if (item.Height < ThemeEngine.Current.MenuHeight)
1804                                         item.Height = ThemeEngine.Current.MenuHeight;
1805                         }
1806                 }
1807                 
1808                 // Updates the menu rect and returns the height
1809                 public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
1810                 {
1811                         int x = 0;
1812                         int y = 0;
1813                         menu.Height = 0;
1814
1815                         foreach (MenuItem item in menu.MenuItems) {
1816
1817                                 CalcItemSize (dc, item, y, x, true);
1818
1819                                 if (x + item.Width > width) {
1820                                         item.X = 0;
1821                                         y += item.Height;
1822                                         item.Y = y;
1823                                         x = 0;
1824                                 }
1825
1826                                 x += item.Width;
1827                                 item.MenuBar = true;                            
1828
1829                                 if (y + item.Height > menu.Height)
1830                                         menu.Height = item.Height + y;
1831                         }
1832
1833                         menu.Width = width;                                             
1834                         return menu.Height;
1835                 }
1836
1837                 public override void CalcPopupMenuSize (Graphics dc, Menu menu)
1838                 {
1839                         int x = 3;
1840                         int start = 0;
1841                         int i, n, y, max;
1842
1843                         menu.Height = 0;
1844
1845                         while (start < menu.MenuItems.Count) {
1846                                 y = 2;
1847                                 max = 0;
1848                                 for (i = start; i < menu.MenuItems.Count; i++) {
1849                                         MenuItem item = menu.MenuItems [i];
1850
1851                                         if ((i != start) && (item.Break || item.BarBreak))
1852                                                 break;
1853
1854                                         CalcItemSize (dc, item, y, x, false);
1855                                         y += item.Height;
1856
1857                                         if (item.Width > max)
1858                                                 max = item.Width;
1859                                 }
1860
1861                                 // Replace the -1 by the menu width (separators)
1862                                 for (n = start; n < i; n++, start++)
1863                                         menu.MenuItems [n].Width = max;
1864
1865                                 if (y > menu.Height)
1866                                         menu.Height = y;
1867
1868                                 x+= max;
1869                         }
1870
1871                         menu.Width = x;
1872
1873                         //space for border
1874                         menu.Width += 2;
1875                         menu.Height += 2;
1876
1877                         menu.Width += SM_CXBORDER;
1878                         menu.Height += SM_CYBORDER;
1879                 }
1880                 
1881                 // Draws a menu bar in a window
1882                 public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
1883                 {
1884                         if (menu.Height == 0)
1885                                 ThemeEngine.Current.CalcMenuBarSize (dc, menu, rect.Width);
1886                                 
1887                         bool keynav = (menu as MainMenu).tracker.Navigating;
1888                         HotkeyPrefix hp = always_draw_hotkeys || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
1889                         string_format_menu_menubar_text.HotkeyPrefix = hp;
1890                         string_format_menu_text.HotkeyPrefix = hp;
1891
1892                         rect.Height = menu.Height;
1893                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (menu.Wnd.BackColor), rect);
1894                                                 
1895                         for (int i = 0; i < menu.MenuItems.Count; i++) {
1896                                 MenuItem item = menu.MenuItems [i];
1897                                 Rectangle item_rect = item.bounds;
1898                                 item_rect.X += rect.X;
1899                                 item_rect.Y += rect.Y;
1900                                 item.MenuHeight = menu.Height;
1901                                 item.PerformDrawItem (new DrawItemEventArgs (dc, ThemeEngine.Current.MenuFont, item_rect, i, item.Status));                     
1902                         }                               
1903                 }               
1904                 
1905                 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
1906                 {
1907                         StringFormat string_format;
1908                         Rectangle rect_text = e.Bounds;
1909
1910                         if (item.Visible == false)
1911                                 return;
1912
1913                         if (item.MenuBar)
1914                                 string_format = string_format_menu_menubar_text;
1915                         else
1916                                 string_format = string_format_menu_text;
1917
1918                         if (item.Separator == true) {
1919                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
1920                                         e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
1921
1922                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
1923                                         e.Bounds.X, e.Bounds.Y + 1, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + 1);
1924
1925                                 return;
1926                         }
1927
1928                         if (!item.MenuBar)
1929                                 rect_text.X += ThemeEngine.Current.MenuCheckSize.Width;
1930
1931                         if (item.BarBreak) { /* Draw vertical break bar*/
1932                                 Rectangle rect = e.Bounds;
1933                                 rect.Y++;
1934                                 rect.Width = 3;
1935                                 rect.Height = item.MenuHeight - 6;
1936
1937                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
1938                                         rect.X, rect.Y , rect.X, rect.Y + rect.Height);
1939
1940                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlLight),
1941                                         rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
1942                         }                       
1943                         
1944                         Color color_text;
1945                         Color color_back;
1946                         
1947                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1948                                 color_text = ThemeEngine.Current.ColorHighlightText;
1949                                 color_back = ThemeEngine.Current.ColorHighlight;
1950                         } else {
1951                                 color_text = ThemeEngine.Current.ColorMenuText;
1952                                 color_back = ThemeEngine.Current.ColorMenu;
1953                         }
1954
1955                         /* Draw background */
1956                         Rectangle rect_back = e.Bounds;
1957                         rect_back.X++;
1958                         rect_back.Width -=2;
1959                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color_back), rect_back);
1960                         
1961                         if (item.Enabled) {
1962                                 e.Graphics.DrawString (item.Text, e.Font,
1963                                         ThemeEngine.Current.ResPool.GetSolidBrush (color_text),
1964                                         rect_text, string_format);
1965
1966                                 if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
1967                                         string str = item.GetShortCutText ();
1968                                         Rectangle rect = rect_text;
1969                                         rect.X = item.XTab;
1970                                         rect.Width -= item.XTab;
1971
1972                                         e.Graphics.DrawString (str, e.Font, ThemeEngine.Current.ResPool.GetSolidBrush (color_text),
1973                                                 rect, string_format_menu_shortcut);
1974                                 }
1975                         } else {
1976                                 ControlPaint.DrawStringDisabled (e.Graphics, item.Text, e.Font, 
1977                                         Color.Black, rect_text, string_format);
1978                         }
1979
1980                         /* Draw arrow */
1981                         if (item.MenuBar == false && item.IsPopup || item.MdiList) {
1982
1983                                 int cx = ThemeEngine.Current.MenuCheckSize.Width;
1984                                 int cy = ThemeEngine.Current.MenuCheckSize.Height;
1985                                 Bitmap  bmp = new Bitmap (cx, cy);
1986                                 Graphics gr = Graphics.FromImage (bmp);
1987                                 Rectangle rect_arrow = new Rectangle (0, 0, cx, cy);
1988                                 ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Arrow);
1989                                 bmp.MakeTransparent ();
1990                                 
1991                                 if (item.Enabled) {
1992                                         e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
1993                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
1994                                 } else {
1995                                         ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
1996                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
1997                                 }
1998  
1999                                 gr.Dispose ();
2000                                 bmp.Dispose ();
2001                         }
2002
2003                         /* Draw checked or radio */
2004                         if (item.MenuBar == false && item.Checked) {
2005
2006                                 Rectangle area = e.Bounds;
2007                                 int cx = ThemeEngine.Current.MenuCheckSize.Width;
2008                                 int cy = ThemeEngine.Current.MenuCheckSize.Height;
2009                                 Bitmap  bmp = new Bitmap (cx, cy);
2010                                 Graphics gr = Graphics.FromImage (bmp);
2011                                 Rectangle rect_arrow = new Rectangle (0, 0, cx, cy);
2012
2013                                 if (item.RadioCheck)
2014                                         ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Bullet);
2015                                 else
2016                                         ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Checkmark);
2017
2018                                 bmp.MakeTransparent ();
2019                                 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
2020
2021                                 gr.Dispose ();
2022                                 bmp.Dispose ();
2023                         }                       
2024                 }               
2025                         
2026                 public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
2027                 {
2028
2029                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
2030                                 (ThemeEngine.Current.ColorMenu), cliparea);
2031
2032                         /* Draw menu borders */
2033                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorHighlightText),
2034                                 rect.X, rect.Y, rect.X + rect.Width, rect.Y);
2035
2036                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorHighlightText),
2037                                 rect.X, rect.Y, rect.X, rect.Y + rect.Height);
2038
2039                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
2040                                 rect.X + rect.Width - 1 , rect.Y , rect.X + rect.Width - 1, rect.Y + rect.Height);
2041
2042                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDarkDark),
2043                                 rect.X + rect.Width, rect.Y , rect.X + rect.Width, rect.Y + rect.Height);
2044
2045                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDark),
2046                                 rect.X , rect.Y + rect.Height - 1 , rect.X + rect.Width - 1, rect.Y + rect.Height -1);
2047
2048                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorControlDarkDark),
2049                                 rect.X , rect.Y + rect.Height, rect.X + rect.Width - 1, rect.Y + rect.Height);
2050
2051                         for (int i = 0; i < menu.MenuItems.Count; i++)
2052                                 if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
2053                                         MenuItem item = menu.MenuItems [i];
2054                                         item.MenuHeight = menu.Height;
2055                                         item.PerformDrawItem (new DrawItemEventArgs (dc, ThemeEngine.Current.MenuFont,
2056                                                 item.bounds, i, item.Status));
2057                         }
2058                 }
2059                 
2060                 #endregion // Menus
2061
2062                 #region MonthCalendar
2063
2064                 // draw the month calendar
2065                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) 
2066                 {
2067                         Rectangle client_rectangle = mc.ClientRectangle;
2068                         Size month_size = mc.SingleMonthSize;
2069                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
2070                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
2071                         Size date_cell_size = (Size)((object)mc.date_cell_size);
2072                         
2073                         // draw the singlecalendars
2074                         int x_offset = 1;
2075                         int y_offset = 1;
2076                         // adjust for the position of the specific month
2077                         for (int i=0; i < mc.CalendarDimensions.Height; i++) 
2078                         {
2079                                 if (i > 0) 
2080                                 {
2081                                         y_offset += month_size.Height + calendar_spacing.Height;
2082                                 }
2083                                 // now adjust for x position    
2084                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) 
2085                                 {
2086                                         if (j > 0) 
2087                                         {
2088                                                 x_offset += month_size.Width + calendar_spacing.Width;
2089                                         } 
2090                                         else 
2091                                         {
2092                                                 x_offset = 1;
2093                                         }
2094
2095                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
2096                                         if (month_rect.IntersectsWith (clip_rectangle)) {
2097                                                 DrawSingleMonth (
2098                                                         dc,
2099                                                         clip_rectangle,
2100                                                         month_rect,
2101                                                         mc,
2102                                                         i,
2103                                                         j);
2104                                         }
2105                                 }
2106                         }
2107                         
2108                         Rectangle bottom_rect = new Rectangle (
2109                                                 client_rectangle.X,
2110                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
2111                                                 client_rectangle.Width,
2112                                                 date_cell_size.Height + 2);
2113                         // draw the today date if it's set
2114                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) 
2115                         {
2116                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), bottom_rect);
2117                                 if (mc.ShowToday) {
2118                                         int today_offset = 5;
2119                                         if (mc.ShowTodayCircle) 
2120                                         {
2121                                                 Rectangle today_circle_rect = new Rectangle (
2122                                                         client_rectangle.X + 5,
2123                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
2124                                                         date_cell_size.Width,
2125                                                         date_cell_size.Height);
2126                                                         DrawTodayCircle (dc, today_circle_rect);
2127                                                 today_offset += date_cell_size.Width + 5;
2128                                         }
2129                                         // draw today's date
2130                                         StringFormat text_format = new StringFormat();
2131                                         text_format.LineAlignment = StringAlignment.Center;
2132                                         text_format.Alignment = StringAlignment.Near;
2133                                         Font bold_font = new Font (mc.Font.FontFamily, mc.Font.Size, mc.Font.Style | FontStyle.Bold);
2134                                         Rectangle today_rect = new Rectangle (
2135                                                         today_offset + client_rectangle.X,
2136                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
2137                                                         Math.Max(client_rectangle.Width - today_offset, 0),
2138                                                         date_cell_size.Height);
2139                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), bold_font, ResPool.GetSolidBrush (mc.ForeColor), today_rect, text_format);
2140                                         text_format.Dispose ();
2141                                         bold_font.Dispose ();
2142                                 }                               
2143                         }
2144                         
2145                         // finally paint the borders of the calendars as required
2146                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
2147                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
2148                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height));
2149                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
2150                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.Right-1, client_rectangle.Y, 1, client_rectangle.Height));
2151                                 } else { 
2152                                         Rectangle rect = new Rectangle (
2153                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
2154                                                 client_rectangle.Y,
2155                                                 calendar_spacing.Width,
2156                                                 client_rectangle.Height);
2157                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
2158                                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), rect);
2159                                         }
2160                                 }
2161                         }
2162                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
2163                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
2164                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1));
2165                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
2166                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Bottom-1, client_rectangle.Width, 1));
2167                                 } else { 
2168                                         Rectangle rect = new Rectangle (
2169                                                 client_rectangle.X,
2170                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
2171                                                 client_rectangle.Width,
2172                                                 calendar_spacing.Height);
2173                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
2174                                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), rect);
2175                                         }
2176                                 }
2177                         }
2178                         
2179                         // draw the drop down border if need
2180                         if (mc.owner != null) {
2181                                 Rectangle bounds = mc.ClientRectangle;
2182                                 if (clip_rectangle.Contains (mc.Location)) {
2183                                         // find out if top or left line to draw
2184                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
2185                                         
2186                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
2187                                         }
2188                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
2189                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
2190                                         }
2191                                 }
2192                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
2193                                         // find out if bottom or right line to draw
2194                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
2195                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
2196                                         }
2197                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
2198                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
2199                                         }
2200                                 }
2201                         }
2202                 }
2203
2204                 // darws a single part of the month calendar (with one month)
2205                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) 
2206                 {
2207                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
2208                         Size title_size = (Size)((object)mc.title_size);
2209                         Size date_cell_size = (Size)((object)mc.date_cell_size);
2210                         DateTime current_month = (DateTime)((object)mc.current_month);
2211                         
2212                         // set up some standard string formating variables
2213                         StringFormat text_format = new StringFormat();
2214                         text_format.LineAlignment = StringAlignment.Center;
2215                         text_format.Alignment = StringAlignment.Center;
2216                         
2217
2218                         // draw the title back ground
2219                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
2220                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
2221                         if (title_rect.IntersectsWith (clip_rectangle)) {
2222                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
2223                                 // draw the title                               
2224                                 string title_text = this_month.ToString ("MMMM yyyy");
2225                                 dc.DrawString (title_text, mc.Font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, text_format);
2226
2227                                 // draw previous and next buttons if it's time
2228                                 if (row == 0 && col == 0) 
2229                                 {
2230                                         // draw previous button
2231                                         DrawMonthCalendarButton (
2232                                                 dc,
2233                                                 rectangle,
2234                                                 mc,
2235                                                 title_size,
2236                                                 mc.button_x_offset,
2237                                                 (System.Drawing.Size)((object)mc.button_size),
2238                                                 true);
2239                                 }
2240                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) 
2241                                 {
2242                                         // draw next button
2243                                         DrawMonthCalendarButton (
2244                                                 dc,
2245                                                 rectangle,
2246                                                 mc,
2247                                                 title_size,
2248                                                 mc.button_x_offset,
2249                                                 (System.Drawing.Size)((object)mc.button_size),
2250                                                 false);
2251                                 }
2252                         }
2253                         
2254                         // set the week offset and draw week nums if needed
2255                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
2256                         Rectangle day_name_rect = new Rectangle(
2257                                 rectangle.X,
2258                                 rectangle.Y + title_size.Height,
2259                                 (7 + col_offset) * date_cell_size.Width,
2260                                 date_cell_size.Height);
2261                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
2262                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), day_name_rect);
2263                                 // draw the day names 
2264                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
2265                                 for (int i=0; i < 7; i++) 
2266                                 {
2267                                         int position = i - (int) first_day_of_week;
2268                                         if (position < 0) 
2269                                         {
2270                                                 position = 7 + position;
2271                                         }
2272                                         // draw it
2273                                         Rectangle day_rect = new Rectangle(
2274                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
2275                                                 day_name_rect.Y,
2276                                                 date_cell_size.Width,
2277                                                 date_cell_size.Height);
2278                                         dc.DrawString (((DayOfWeek)i).ToString().Substring(0, 3), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, text_format);
2279                                 }
2280                                 
2281                                 // draw the vertical divider
2282                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
2283                                 dc.DrawLine (
2284                                         ResPool.GetPen (mc.ForeColor),
2285                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
2286                                         rectangle.Y + vert_divider_y,
2287                                         rectangle.Right - mc.divider_line_offset,
2288                                         rectangle.Y + vert_divider_y);
2289                         }
2290
2291
2292                         // draw the actual date items in the grid (including the week numbers)
2293                         Rectangle date_rect = new Rectangle (
2294                                 rectangle.X,
2295                                 rectangle.Y + title_size.Height + date_cell_size.Height,
2296                                 date_cell_size.Width,
2297                                 date_cell_size.Height);
2298                         int month_row_count = 0;
2299                         bool draw_week_num_divider = false;
2300                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
2301                         for (int i=0; i < 6; i++) 
2302                         {
2303                                 // establish if this row is in our clip_area
2304                                 Rectangle row_rect = new Rectangle (
2305                                         rectangle.X,
2306                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
2307                                         date_cell_size.Width * 7,
2308                                         date_cell_size.Height);
2309                                 if (mc.ShowWeekNumbers) {
2310                                         row_rect.Width += date_cell_size.Width;
2311                                 }
2312                 
2313                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
2314                                 if (draw_row) {
2315                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), row_rect);
2316                                 }
2317                                 // establish if this is a valid week to draw
2318                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
2319                                         month_row_count = i;
2320                                 }
2321                                 
2322                                 // draw the week number if required
2323                                 if (mc.ShowWeekNumbers && month_row_count == i) {
2324                                         if (!draw_week_num_divider) {
2325                                                 draw_week_num_divider = draw_row;
2326                                         }
2327                                         // get the week for this row
2328                                         int week = mc.GetWeekOfYear (current_date);     
2329
2330                                         if (draw_row) {
2331                                                 dc.DrawString (
2332                                                         week.ToString(),
2333                                                         mc.Font,
2334                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
2335                                                         date_rect,
2336                                                         text_format);
2337                                         }
2338                                         date_rect.Offset(date_cell_size.Width, 0);
2339                                 }
2340                                                                 
2341                                 // only draw the days if we have to
2342                                 if(month_row_count == i) {
2343                                         for (int j=0; j < 7; j++) 
2344                                         {
2345                                                 if (draw_row) {
2346                                                         DrawMonthCalendarDate (
2347                                                                 dc,
2348                                                                 date_rect,
2349                                                                 mc,
2350                                                                 current_date,
2351                                                                 this_month,
2352                                                                 row,
2353                                                                 col);
2354                                                 }
2355
2356                                                 // move the day on
2357                                                 current_date = current_date.AddDays(1);
2358                                                 date_rect.Offset(date_cell_size.Width, 0);
2359                                         }
2360
2361                                         // shift the rectangle down one row
2362                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
2363                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
2364                                 }
2365                         }
2366
2367                         // month_row_count is zero based, so add one
2368                         month_row_count++;
2369
2370                         // draw week numbers if required
2371                         if (draw_week_num_divider) {
2372                                 col_offset = 1;
2373                                 dc.DrawLine (
2374                                         ResPool.GetPen (mc.ForeColor),
2375                                         rectangle.X + date_cell_size.Width - 1,
2376                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
2377                                         rectangle.X + date_cell_size.Width - 1,
2378                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
2379                         }
2380                         text_format.Dispose ();
2381                 }
2382
2383                 // draws the pervious or next button
2384                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) 
2385                 {
2386                         bool is_clicked = false;
2387                         Rectangle button_rect;
2388                         Rectangle arrow_rect = new Rectangle (rectangle.X, rectangle.Y, 4, 7);
2389                         Point[] arrow_path = new Point[3];
2390                         // prepare the button
2391                         if (is_previous) 
2392                         {
2393                                 is_clicked = mc.is_previous_clicked;
2394                                 button_rect = new Rectangle (
2395                                         rectangle.X + 1 + x_offset,
2396                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
2397                                         Math.Max(button_size.Width - 1, 0),
2398                                         Math.Max(button_size.Height - 1, 0));
2399                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
2400                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
2401                                 if (is_clicked) {
2402                                         arrow_rect.Offset(1,1);
2403                                 }
2404                                 arrow_path[0] = new Point (arrow_rect.Right, arrow_rect.Y);
2405                                 arrow_path[1] = new Point (arrow_rect.X, arrow_rect.Y + arrow_rect.Height/2);
2406                                 arrow_path[2] = new Point (arrow_rect.Right, arrow_rect.Bottom);
2407                         }
2408                         else
2409                         {
2410                                 is_clicked = mc.is_next_clicked;
2411                                 button_rect = new Rectangle (
2412                                         rectangle.Right - 1 - x_offset - button_size.Width,
2413                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
2414                                         Math.Max(button_size.Width - 1, 0),
2415                                         Math.Max(button_size.Height - 1, 0));
2416                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
2417                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
2418                                 if (is_clicked) {
2419                                         arrow_rect.Offset(1,1);
2420                                 }
2421                                 arrow_path[0] = new Point (arrow_rect.X, arrow_rect.Y);
2422                                 arrow_path[1] = new Point (arrow_rect.Right, arrow_rect.Y + arrow_rect.Height/2);
2423                                 arrow_path[2] = new Point (arrow_rect.X, arrow_rect.Bottom);                            
2424                         }
2425
2426                         // fill the background
2427                         dc.FillRectangle (SystemBrushes.Control, button_rect);
2428                         // draw the border
2429                         if (is_clicked) {
2430                                 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
2431                         }
2432                         else {
2433                                 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.All);
2434                         }
2435                         // draw the arrow
2436                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);                 
2437                 }
2438                 
2439
2440                 // draws one day in the calendar grid
2441                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
2442                         Color date_color = mc.ForeColor;
2443                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
2444
2445                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
2446                         if (date.Year != month.Year || date.Month != month.Month) {
2447                                 DateTime check_date = month.AddMonths (-1);
2448                                 // check if it's the month before 
2449                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
2450                                         date_color = mc.TrailingForeColor;
2451                                 } else {
2452                                         // check if it's the month after
2453                                         check_date = month.AddMonths (1);
2454                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
2455                                                 date_color = mc.TrailingForeColor;
2456                                         } else {
2457                                                 return;
2458                                         }
2459                                 }
2460                         } else {
2461                                 date_color = mc.ForeColor;
2462                         }
2463
2464
2465                         if (date == mc.SelectionStart && date == mc.SelectionEnd) {
2466                                 // see if the date is in the start of selection
2467                                 date_color = mc.BackColor;
2468                                 // draw the left hand of the back ground
2469                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);                                
2470                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 359);
2471                         } else if (date == mc.SelectionStart) {
2472                                 // see if the date is in the start of selection
2473                                 date_color = mc.BackColor;
2474                                 // draw the left hand of the back ground
2475                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);                                
2476                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
2477                                 // fill the other side as a straight rect
2478                                 if (date < mc.SelectionEnd) 
2479                                 {
2480                                         // use rectangle instead of rectangle to go all the way to edge of rect
2481                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
2482                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
2483                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2484                                 }
2485                         } else if (date == mc.SelectionEnd) {
2486                                 // see if it is the end of selection
2487                                 date_color = mc.BackColor;
2488                                 // draw the left hand of the back ground
2489                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);
2490                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
2491                                 // fill the other side as a straight rect
2492                                 if (date > mc.SelectionStart) {
2493                                         selection_rect.X = rectangle.X;
2494                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
2495                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2496                                 }
2497                         } else if (date > mc.SelectionStart && date < mc.SelectionEnd) {
2498                                 // now see if it's in the middle
2499                                 date_color = mc.BackColor;
2500                                 // draw the left hand of the back ground
2501                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, 0, -3);
2502                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2503                         }
2504
2505                         // set up some standard string formating variables
2506                         StringFormat text_format = new StringFormat();
2507                         text_format.LineAlignment = StringAlignment.Center;
2508                         text_format.Alignment = StringAlignment.Center;
2509                         
2510
2511                         // establish if it's a bolded font
2512                         Font font;
2513                         if (mc.IsBoldedDate (date)) {
2514                                 font = new Font (mc.Font.FontFamily, mc.Font.Size, mc.Font.Style | FontStyle.Bold);
2515                         } else {
2516                                 font = mc.Font;
2517                         }
2518
2519                         // just draw the date now
2520                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, text_format);
2521
2522                         // today circle if needed
2523                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
2524                                 DrawTodayCircle (dc, interior);
2525                         }
2526
2527                         // draw the selection grid
2528                         if (mc.is_date_clicked && mc.clicked_date == date) {                            
2529                                 using (Pen pen = new Pen (Color.Black, 1) ) {
2530                                         pen.DashStyle = DashStyle.Dot;
2531                                         dc.DrawRectangle (pen, interior);
2532                                 }
2533                         }
2534                         text_format.Dispose ();
2535                 }
2536
2537                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
2538                         Color circle_color = Color.FromArgb (248, 0, 0);
2539                         // draw the left hand of the circle 
2540                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
2541                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
2542                         Point [] curve_points = new Point [3];
2543                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
2544                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
2545                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
2546
2547                         using (Pen pen = new Pen (circle_color, 2)) {
2548                                 dc.DrawArc (pen, lhs_circle_rect, 90, 180);
2549                                 dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
2550                                 dc.DrawCurve (pen, curve_points);
2551                                 dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
2552                         }
2553                 }
2554
2555                 #endregion      // MonthCalendar
2556
2557                 #region Panel
2558                 public override Size PanelDefaultSize {
2559                         get {
2560                                 return new Size (200, 100);
2561                         }
2562                 }
2563                 #endregion      // Panel
2564
2565                 #region PictureBox
2566                 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
2567                         Rectangle client = pb.ClientRectangle;
2568
2569                         // FIXME - instead of drawing the whole picturebox every time
2570                         // intersect the clip rectangle with the drawn picture and only draw what's needed,
2571                         // Also, we only need a background fill where no image goes
2572                         if (pb.Image != null) {
2573                                 switch (pb.SizeMode) {
2574                                 case PictureBoxSizeMode.StretchImage:
2575                                         dc.DrawImage (pb.Image, 0, 0, client.Width, client.Height);
2576                                         break;
2577
2578                                 case PictureBoxSizeMode.CenterImage:
2579                                         dc.FillRectangle(ResPool.GetSolidBrush(pb.BackColor), clip);
2580                                         dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
2581                                         break;
2582                                 default:
2583                                         dc.FillRectangle(ResPool.GetSolidBrush(pb.BackColor), clip);
2584                                         // Normal, AutoSize
2585                                         dc.DrawImage(pb.Image, 0, 0, pb.Image.Width, pb.Image.Height);
2586                                         break;
2587                                 }
2588
2589                                 return;
2590                         }
2591
2592                         // We only get here if no image is set. At least paint the background
2593                         dc.FillRectangle(ResPool.GetSolidBrush(pb.BackColor), clip);
2594                 }
2595
2596                 public override Size PictureBoxDefaultSize {
2597                         get {
2598                                 return new Size (100, 50);
2599                         }
2600                 }
2601                 #endregion      // PictureBox
2602
2603                 #region ProgressBar
2604                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) 
2605                 {
2606                         Rectangle       block_rect;
2607                         Rectangle       client_area = ctrl.client_area;
2608                         int             space_betweenblocks     = 2;                    
2609                         int             block_width;
2610                         int             increment;
2611                         int             barpos_pixels;
2612                         
2613                         block_width = ((client_area.Height) * 2 ) / 3;
2614                         barpos_pixels = ((ctrl.Value - ctrl.Minimum) * client_area.Width) / (ctrl.Maximum - ctrl.Minimum);
2615                         increment = block_width + space_betweenblocks;
2616
2617                         /* Draw border */
2618                         CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenInner, Border3DSide.All & ~Border3DSide.Middle, ColorControl);
2619                         
2620                         /* Draw Blocks */
2621                         block_rect = new Rectangle (client_area.X, client_area.Y, block_width, client_area.Height);
2622                         while ((block_rect.X - client_area.X) < barpos_pixels) {
2623                                 
2624                                 if (clip_rect.IntersectsWith (block_rect) == true) {                            
2625                                         dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), block_rect);
2626                                 }                               
2627                                 
2628                                 block_rect.X  += increment;
2629                         }
2630                 }
2631                 
2632                 public override Size ProgressBarDefaultSize {
2633                         get {
2634                                 return new Size (100, 23);
2635                         }
2636                 }
2637
2638                 #endregion      // ProgressBar
2639
2640                 #region RadioButton
2641                 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
2642                         StringFormat    text_format;
2643                         Rectangle       client_rectangle;
2644                         Rectangle       text_rectangle;
2645                         Rectangle       radiobutton_rectangle;
2646                         int             radiobutton_size = 12;
2647                         int     radiobutton_space = 4;
2648
2649                         client_rectangle = radio_button.ClientRectangle;
2650                         text_rectangle = client_rectangle;
2651                         radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
2652
2653                         text_format = new StringFormat();
2654                         text_format.Alignment = StringAlignment.Near;
2655                         text_format.LineAlignment = StringAlignment.Center;
2656                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
2657
2658                         /* Calculate the position of text and checkbox rectangle */
2659                         if (radio_button.appearance!=Appearance.Button) {
2660                                 switch(radio_button.radiobutton_alignment) {
2661                                 case ContentAlignment.BottomCenter: {
2662                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
2663                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
2664                                         text_rectangle.X=client_rectangle.X;
2665                                         text_rectangle.Width=client_rectangle.Width;
2666                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
2667                                         break;
2668                                 }
2669
2670                                 case ContentAlignment.BottomLeft: {
2671                                         radiobutton_rectangle.X=client_rectangle.Left;
2672                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
2673                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
2674                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;                                 
2675                                         break;
2676                                 }
2677
2678                                 case ContentAlignment.BottomRight: {
2679                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
2680                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
2681                                         text_rectangle.X=client_rectangle.X;
2682                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2683                                         break;
2684                                 }
2685
2686                                 case ContentAlignment.MiddleCenter: {
2687                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
2688                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
2689                                         text_rectangle.X=client_rectangle.X;
2690                                         text_rectangle.Width=client_rectangle.Width;
2691                                         break;
2692                                 }
2693
2694                                 default:
2695                                 case ContentAlignment.MiddleLeft: {
2696                                         radiobutton_rectangle.X=client_rectangle.Left;
2697                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
2698                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
2699                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2700                                         break;
2701                                 }
2702
2703                                 case ContentAlignment.MiddleRight: {
2704                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
2705                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
2706                                         text_rectangle.X=client_rectangle.X;
2707                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2708                                         break;
2709                                 }
2710
2711                                 case ContentAlignment.TopCenter: {
2712                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
2713                                         radiobutton_rectangle.Y=client_rectangle.Top;
2714                                         text_rectangle.X=client_rectangle.X;
2715                                         text_rectangle.Y=radiobutton_size+radiobutton_space;
2716                                         text_rectangle.Width=client_rectangle.Width;
2717                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
2718                                         break;
2719                                 }
2720
2721                                 case ContentAlignment.TopLeft: {
2722                                         radiobutton_rectangle.X=client_rectangle.Left;
2723                                         radiobutton_rectangle.Y=client_rectangle.Top;
2724                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
2725                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2726                                         break;
2727                                 }
2728
2729                                 case ContentAlignment.TopRight: {
2730                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
2731                                         radiobutton_rectangle.Y=client_rectangle.Top;
2732                                         text_rectangle.X=client_rectangle.X;
2733                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2734                                         break;
2735                                 }
2736                                 }
2737                         } else {
2738                                 text_rectangle.X=client_rectangle.X;
2739                                 text_rectangle.Width=client_rectangle.Width;
2740                         }
2741                         
2742                         /* Set the horizontal alignment of our text */
2743                         switch(radio_button.text_alignment) {
2744                                 case ContentAlignment.BottomLeft:
2745                                 case ContentAlignment.MiddleLeft:
2746                                 case ContentAlignment.TopLeft: {
2747                                         text_format.Alignment=StringAlignment.Near;
2748                                         break;
2749                                 }
2750
2751                                 case ContentAlignment.BottomCenter:
2752                                 case ContentAlignment.MiddleCenter:
2753                                 case ContentAlignment.TopCenter: {
2754                                         text_format.Alignment=StringAlignment.Center;
2755                                         break;
2756                                 }
2757
2758                                 case ContentAlignment.BottomRight:
2759                                 case ContentAlignment.MiddleRight:
2760                                 case ContentAlignment.TopRight: {
2761                                         text_format.Alignment=StringAlignment.Far;
2762                                         break;
2763                                 }
2764                         }
2765
2766                         /* Set the vertical alignment of our text */
2767                         switch(radio_button.text_alignment) {
2768                                 case ContentAlignment.TopLeft: 
2769                                 case ContentAlignment.TopCenter: 
2770                                 case ContentAlignment.TopRight: {
2771                                         text_format.LineAlignment=StringAlignment.Near;
2772                                         break;
2773                                 }
2774
2775                                 case ContentAlignment.BottomLeft:
2776                                 case ContentAlignment.BottomCenter:
2777                                 case ContentAlignment.BottomRight: {
2778                                         text_format.LineAlignment=StringAlignment.Far;
2779                                         break;
2780                                 }
2781
2782                                 case ContentAlignment.MiddleLeft:
2783                                 case ContentAlignment.MiddleCenter:
2784                                 case ContentAlignment.MiddleRight: {
2785                                         text_format.LineAlignment=StringAlignment.Center;
2786                                         break;
2787                                 }
2788                         }
2789
2790                         ButtonState state = ButtonState.Normal;
2791                         if (radio_button.FlatStyle == FlatStyle.Flat) {
2792                                 state |= ButtonState.Flat;
2793                         }
2794                         
2795                         if (radio_button.Checked) {
2796                                 state |= ButtonState.Checked;
2797                         }
2798
2799                         // Start drawing
2800                         RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
2801                         
2802                         RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
2803
2804                         RadioButton_DrawFocus(radio_button, dc, text_rectangle);                        
2805                         text_format.Dispose ();
2806                 }
2807
2808                 protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
2809                 {
2810                         SolidBrush sb = new SolidBrush(radio_button.BackColor);
2811                         dc.FillRectangle(sb, radio_button.ClientRectangle);
2812                         sb.Dispose();
2813                         
2814                         if (radio_button.appearance==Appearance.Button) {
2815                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
2816                                         DrawFlatStyleButton(dc, radio_button.ClientRectangle, radio_button);
2817                                 } else {                                
2818                                         CPDrawButton(dc, radio_button.ClientRectangle, state);
2819                                 }               
2820                         } else {
2821                                 // establish if we are rendering a flat style of some sort
2822                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
2823                                         DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
2824                                 } else {
2825                                         ControlPaint.DrawRadioButton (dc, radiobutton_rectangle, state);
2826                                 }
2827                         }
2828                 }
2829                 
2830                 protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
2831                 {
2832                         SolidBrush sb;
2833                         
2834                         // offset the text if it's pressed and a button
2835                         if (radio_button.Appearance == Appearance.Button) {
2836                                 if (radio_button.Checked || (radio_button.Capture && radio_button.FlatStyle != FlatStyle.Flat)) {
2837                                         text_rectangle.X ++;
2838                                         text_rectangle.Y ++;
2839                                 }
2840                                 
2841                                 text_rectangle.Inflate(-4,-4);
2842                         } 
2843                         
2844                         /* Place the text; to be compatible with Windows place it after the radiobutton has been drawn */                       
2845                         dc.DrawString (radio_button.Text, radio_button.Font, ThemeEngine.Current.ResPool.GetSolidBrush (radio_button.ForeColor), text_rectangle, text_format);
2846                         
2847                         if (radio_button.Enabled) {
2848                                 sb = ResPool.GetSolidBrush(radio_button.ForeColor);
2849                                 dc.DrawString(radio_button.Text, radio_button.Font, sb, text_rectangle, text_format);
2850                         } else if (radio_button.FlatStyle == FlatStyle.Flat) {
2851                                 dc.DrawString(radio_button.Text, radio_button.Font, ResPool.GetSolidBrush (ControlPaint.DarkDark (this.ColorControl)), text_rectangle, text_format);
2852                         } else {
2853                                 CPDrawStringDisabled(dc, radio_button.Text, radio_button.Font, this.ColorControlText, text_rectangle, text_format);
2854                         }
2855                 }
2856                 
2857                 protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
2858                 {
2859                         if (radio_button.Focused) {
2860                                 if (radio_button.FlatStyle != FlatStyle.Flat) {
2861                                         DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
2862                                 } else {
2863                                         dc.DrawRectangle (ResPool.GetPen (radio_button.ForeColor), text_rectangle);
2864                                 }
2865                         }
2866                 }
2867
2868                 // renders a radio button with the Flat and Popup FlatStyle
2869                 protected void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
2870                 {
2871                         int     lineWidth;
2872                         
2873                         if (radio_button.Enabled) {
2874                                 // draw the outer flatstyle arcs
2875                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
2876                                         graphics.DrawArc (ResPool.GetPen (radio_button.ForeColor), rectangle, 0, 359);
2877                                         
2878                                         // fill in the area depending on whether or not the mouse is hovering
2879                                         if (radio_button.is_entered && radio_button.Capture) {
2880                                                 graphics.FillPie (ResPool.GetSolidBrush (ControlPaint.Light (radio_button.BackColor)), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
2881                                         } else {
2882                                                 graphics.FillPie (ResPool.GetSolidBrush (ControlPaint.LightLight (radio_button.BackColor)), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
2883                                         }
2884                                 } else {
2885                                         // must be a popup radio button
2886                                         // fill the control
2887                                         graphics.FillPie (ResPool.GetSolidBrush (ControlPaint.LightLight (radio_button.BackColor)), rectangle, 0, 359);
2888
2889                                         if (radio_button.is_entered || radio_button.Capture) {
2890                                                 // draw the popup 3d button knob
2891                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Light (radio_button.BackColor)), rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
2892
2893                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Dark (radio_button.BackColor)), rectangle, 135, 180);
2894                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.LightLight (radio_button.BackColor)), rectangle, 315, 180);
2895                                                 
2896                                         } else {
2897                                                 // just draw lighter flatstyle outer circle
2898                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Dark (this.ColorControl)), rectangle, 0, 359);                                           
2899                                         }                                                                               
2900                                 }
2901                         } else {
2902                                 // disabled
2903                                 // fill control background color regardless of actual backcolor
2904                                 graphics.FillPie (ResPool.GetSolidBrush (this.ColorControl), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
2905                                 // draw the ark as control dark
2906                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Dark(this.ColorControl)), rectangle, 0, 359);
2907                         }
2908
2909                         // draw the check
2910                         lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
2911                         if (radio_button.Checked) {
2912                                 SolidBrush buttonBrush;
2913
2914                                 if (!radio_button.Enabled) {
2915                                         buttonBrush = ResPool.GetSolidBrush (ControlPaint.Dark (this.ColorControl));
2916                                 } else if (radio_button.FlatStyle == FlatStyle.Popup && radio_button.is_entered && radio_button.Capture) {
2917                                         buttonBrush = ResPool.GetSolidBrush (this.ColorControlText);
2918                                 } else {
2919                                         buttonBrush = ResPool.GetSolidBrush (radio_button.ForeColor);
2920                                 }
2921                                 graphics.FillPie (buttonBrush, rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2, 0, 359);
2922                         }       
2923                 }
2924
2925                 public override Size RadioButtonDefaultSize {
2926                         get {
2927                                 return new Size (104,24);
2928                         }
2929                 }
2930                 #endregion      // RadioButton
2931
2932                 #region ScrollBar
2933                 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
2934                 {
2935                         int             scrollbutton_width = bar.scrollbutton_width;
2936                         int             scrollbutton_height = bar.scrollbutton_height;
2937                         Rectangle       first_arrow_area;
2938                         Rectangle       second_arrow_area;                      
2939                         Rectangle       thumb_pos;
2940                         
2941                         thumb_pos = bar.ThumbPos;
2942
2943                         if (bar.vert) {
2944                                 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
2945                                 bar.FirstArrowArea = first_arrow_area;
2946
2947                                 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
2948                                 bar.SecondArrowArea = second_arrow_area;
2949
2950                                 thumb_pos.Width = bar.Width;
2951                                 bar.ThumbPos = thumb_pos;
2952
2953                                 /* Buttons */
2954                                 if (clip.IntersectsWith (first_arrow_area))
2955                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
2956                                 if (clip.IntersectsWith (second_arrow_area))
2957                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
2958
2959                                 /* Background */
2960                                 switch (bar.thumb_moving) {
2961                                 case ScrollBar.ThumbMoving.None: {
2962                                         ScrollBar_Vertical_Draw_ThumbMoving_None(scrollbutton_height, bar, clip, dc);
2963                                         break;
2964                                 }
2965                                 case ScrollBar.ThumbMoving.Forward: {
2966                                         ScrollBar_Vertical_Draw_ThumbMoving_Forward(scrollbutton_height, bar, thumb_pos, clip, dc);
2967                                         break;
2968                                 }
2969                                 
2970                                 case ScrollBar.ThumbMoving.Backwards: {
2971                                         ScrollBar_Vertical_Draw_ThumbMoving_Backwards(scrollbutton_height, bar, thumb_pos, clip, dc);
2972                                         break;
2973                                 }
2974                                 
2975                                 default:
2976                                         break;
2977                                 }
2978                         } else {
2979                                 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
2980                                 bar.FirstArrowArea = first_arrow_area;
2981
2982                                 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
2983                                 bar.SecondArrowArea = second_arrow_area;
2984
2985                                 thumb_pos.Height = bar.Height;
2986                                 bar.ThumbPos = thumb_pos;
2987
2988                                 /* Buttons */
2989                                 if (clip.IntersectsWith (first_arrow_area))
2990                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
2991                                 if (clip.IntersectsWith (second_arrow_area))
2992                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
2993
2994                                 /* Background */                                        
2995                                 switch (bar.thumb_moving) {
2996                                 case ScrollBar.ThumbMoving.None: {
2997                                         ScrollBar_Horizontal_Draw_ThumbMoving_None(scrollbutton_width, bar, clip, dc);
2998                                         break;
2999                                 }
3000                                 
3001                                 case ScrollBar.ThumbMoving.Forward: {
3002                                         ScrollBar_Horizontal_Draw_ThumbMoving_Forward(scrollbutton_width, thumb_pos, bar, clip, dc);
3003                                         break;
3004                                 }
3005                                 
3006                                 case ScrollBar.ThumbMoving.Backwards: {
3007                                         ScrollBar_Horizontal_Draw_ThumbMoving_Backwards(scrollbutton_width, thumb_pos, bar, clip, dc);
3008                                         break;
3009                                 }
3010                                 }
3011                         }
3012
3013                         /* Thumb */
3014                         ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);                          
3015                 }
3016
3017                 protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
3018                 {
3019                         if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
3020                                 DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
3021                 }
3022
3023                 protected virtual void ScrollBar_Vertical_Draw_ThumbMoving_None( int scrollbutton_height, ScrollBar bar, Rectangle clip, Graphics dc )
3024                 {
3025                         Rectangle r = new Rectangle( 0,  
3026                                                     scrollbutton_height, bar.ClientRectangle.Width, bar.ClientRectangle.Height - ( scrollbutton_height * 2 ) );
3027                         Rectangle intersect = Rectangle.Intersect( clip, r );
3028                         
3029                         if ( intersect != Rectangle.Empty )
3030                         {
3031                                 Brush h = ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White);
3032                                 dc.FillRectangle( h, intersect );
3033                         }
3034                 }
3035                 
3036                 protected virtual void ScrollBar_Vertical_Draw_ThumbMoving_Forward( int scrollbutton_height, ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc )
3037                 {
3038                         Rectangle r = new Rectangle( 0,  scrollbutton_height,
3039                                                     bar.ClientRectangle.Width, thumb_pos.Y - scrollbutton_height );
3040                         Rectangle intersect = Rectangle.Intersect( clip, r );
3041                         
3042                         if ( intersect != Rectangle.Empty )
3043                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White ), intersect );
3044                         
3045                         r.X = 0;
3046                         r.Y = thumb_pos.Y + thumb_pos.Height;
3047                         r.Width = bar.ClientRectangle.Width;
3048                         r.Height = bar.ClientRectangle.Height -  ( thumb_pos.Y + thumb_pos.Height ) - scrollbutton_height;
3049                         
3050                         intersect = Rectangle.Intersect( clip, r );
3051                         if ( intersect != Rectangle.Empty )
3052                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
3053                 }
3054                 
3055                 protected virtual void ScrollBar_Vertical_Draw_ThumbMoving_Backwards( int scrollbutton_height, ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc )
3056                 {
3057                         Rectangle r = new Rectangle( 0,  scrollbutton_height,
3058                                                     bar.ClientRectangle.Width, thumb_pos.Y - scrollbutton_height );
3059                         Rectangle intersect = Rectangle.Intersect( clip, r );
3060                         
3061                         if ( intersect != Rectangle.Empty )
3062                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
3063                         
3064                         r.X = 0;
3065                         r.Y = thumb_pos.Y + thumb_pos.Height;
3066                         r.Width = bar.ClientRectangle.Width; 
3067                         r.Height = bar.ClientRectangle.Height -  ( thumb_pos.Y + thumb_pos.Height ) - scrollbutton_height;
3068                         
3069                         intersect = Rectangle.Intersect( clip, r );
3070                         if ( intersect != Rectangle.Empty )
3071                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
3072                 }
3073                 
3074                 protected virtual void ScrollBar_Horizontal_Draw_ThumbMoving_None( int scrollbutton_width, ScrollBar bar, Rectangle clip, Graphics dc )
3075                 {
3076                         Rectangle r = new Rectangle( scrollbutton_width,
3077                                                     0, bar.ClientRectangle.Width - ( scrollbutton_width * 2 ), bar.ClientRectangle.Height );
3078                         Rectangle intersect = Rectangle.Intersect( clip, r );
3079                         
3080                         if ( intersect != Rectangle.Empty )
3081                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
3082                 }
3083                 
3084                 protected virtual void ScrollBar_Horizontal_Draw_ThumbMoving_Forward( int scrollbutton_width, Rectangle thumb_pos, ScrollBar bar, Rectangle clip, Graphics dc )
3085                 {
3086                         Rectangle r = new Rectangle( scrollbutton_width,  0,
3087                                                     thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height );
3088                         Rectangle intersect = Rectangle.Intersect( clip, r );
3089                         
3090                         if ( intersect != Rectangle.Empty )
3091                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
3092                         
3093                         r.X = thumb_pos.X + thumb_pos.Width;
3094                         r.Y = 0;
3095                         r.Width = bar.ClientRectangle.Width -  ( thumb_pos.X + thumb_pos.Width ) - scrollbutton_width;
3096                         r.Height = bar.ClientRectangle.Height;
3097                         
3098                         intersect = Rectangle.Intersect( clip, r );
3099                         if ( intersect != Rectangle.Empty )
3100                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
3101                 }
3102                 
3103                 protected virtual void ScrollBar_Horizontal_Draw_ThumbMoving_Backwards( int scrollbutton_width, Rectangle thumb_pos, ScrollBar bar, Rectangle clip, Graphics dc )
3104                 {
3105                         Rectangle r = new Rectangle( scrollbutton_width,  0,
3106                                                     thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height );
3107                         Rectangle intersect = Rectangle.Intersect( clip, r );
3108                         
3109                         if ( intersect != Rectangle.Empty )
3110                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
3111                         
3112                         r.X = thumb_pos.X + thumb_pos.Width;
3113                         r.Y = 0;
3114                         r.Width = bar.ClientRectangle.Width -  ( thumb_pos.X + thumb_pos.Width ) - scrollbutton_width;
3115                         r.Height = bar.ClientRectangle.Height;
3116                         
3117                         intersect = Rectangle.Intersect( clip, r );
3118                         if ( intersect != Rectangle.Empty )
3119                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
3120                 }
3121
3122                 public override int ScrollBarButtonSize {
3123                         get { return 16; }
3124                 }
3125                 #endregion      // ScrollBar
3126
3127                 #region StatusBar
3128                 public  override void DrawStatusBar (Graphics dc, Rectangle clip, StatusBar sb) {
3129                         Rectangle area = sb.ClientRectangle;
3130                         int horz_border = 2;
3131                         int vert_border = 2;
3132
3133                         dc.FillRectangle (GetControlBackBrush (sb.BackColor), clip);
3134                         
3135                         if (sb.Panels.Count == 0 && sb.Text != String.Empty) {
3136                                 string text = sb.Text;
3137                                 StringFormat string_format = new StringFormat ();
3138                                 string_format.Trimming = StringTrimming.Character;
3139                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
3140
3141                                 if (text [0] == '\t') {
3142                                         string_format.Alignment = StringAlignment.Center;
3143                                         text = text.Substring (1);
3144                                         if (text [0] == '\t') {
3145                                                 string_format.Alignment = StringAlignment.Far;
3146                                                 text = text.Substring (1);
3147                                         }
3148                                 }
3149                 
3150                                 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
3151                                                 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
3152                                 string_format.Dispose ();
3153                         } else if (sb.ShowPanels) {
3154                                 SolidBrush br_forecolor = GetControlForeBrush (sb.ForeColor);
3155                                 int prev_x = area.X + horz_border;
3156                                 int y = area.Y + vert_border;
3157                                 for (int i = 0; i < sb.Panels.Count; i++) {
3158                                         Rectangle pr = new Rectangle (prev_x, y,
3159                                                 sb.Panels [i].Width, area.Height);
3160                                         prev_x += pr.Width + StatusBarHorzGapWidth;
3161                                         if (pr.IntersectsWith (clip))
3162                                                 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
3163                                 }
3164                         }
3165
3166                         if (sb.SizingGrip)
3167                                 CPDrawSizeGrip (dc, ColorControl, area);
3168
3169                 }
3170
3171
3172                 protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
3173                         SolidBrush br_forecolor, StatusBarPanel panel) {
3174                         int border_size = 3; // this is actually const, even if the border style is none
3175
3176                         area.Height -= border_size;
3177                         if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
3178                                 Border3DStyle border_style = Border3DStyle.SunkenInner;
3179                                 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
3180                                         border_style = Border3DStyle.RaisedOuter;
3181                                 CPDrawBorder3D(dc, area, border_style, Border3DSide.All, panel.Parent.BackColor);
3182                         }
3183
3184                         if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
3185                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
3186                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
3187                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor);
3188                                 panel.Parent.OnDrawItemInternal (e);
3189                                 return;
3190                         }
3191
3192                         int left = area.Left;
3193                         if (panel.Icon != null) {
3194                                 left += 2;
3195                                 dc.DrawIcon (panel.Icon, left, area.Top);
3196                                 left += panel.Icon.Width;
3197                         }
3198
3199                         if (panel.Text == String.Empty)
3200                                 return;
3201
3202                         string text = panel.Text;
3203                         StringFormat string_format = new StringFormat ();
3204                         string_format.Trimming = StringTrimming.Character;
3205                         string_format.FormatFlags = StringFormatFlags.NoWrap;
3206
3207                         if (text [0] == '\t') {
3208                                 string_format.Alignment = StringAlignment.Center;
3209                                 text = text.Substring (1);
3210                                 if (text [0] == '\t') {
3211                                         string_format.Alignment = StringAlignment.Far;
3212                                         text = text.Substring (1);
3213                                 }
3214                         }
3215
3216                         int x = left + border_size;
3217                         int y = border_size + 2;
3218                         Rectangle r = new Rectangle (x, y, 
3219                                 area.Right - x - border_size,
3220                                 area.Bottom - y - border_size);
3221                         
3222                         dc.DrawString (text, panel.Parent.Font, br_forecolor, r, string_format);
3223                         string_format.Dispose ();
3224                 }
3225
3226                 public override int StatusBarSizeGripWidth {
3227                         get { return 15; }
3228                 }
3229
3230                 public override int StatusBarHorzGapWidth {
3231                         get { return 3; }
3232                 }
3233
3234                 public override Size StatusBarDefaultSize {
3235                         get {
3236                                 return new Size (100, 22);
3237                         }
3238                 }
3239                 #endregion      // StatusBar
3240
3241                 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
3242                 {
3243                         // Do we need to fill the back color? It can't be changed...
3244                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), area);
3245                         Rectangle panel_rect = GetTabPanelRectExt (tab);
3246
3247                         if (tab.Appearance == TabAppearance.Normal) {
3248                                 CPDrawBorder3D (dc, panel_rect, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top, ColorControl);
3249                                 CPDrawBorder3D (dc, panel_rect, Border3DStyle.Raised, Border3DSide.Right | Border3DSide.Bottom, ColorControl);
3250                         }
3251
3252                         if (tab.Alignment == TabAlignment.Top) {
3253                                 for (int r = tab.TabPages.Count; r > 0; r--) {
3254                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
3255                                                 if (i == tab.SelectedIndex)
3256                                                         continue;
3257                                                 if (r != tab.TabPages [i].Row)
3258                                                         continue;
3259                                                 Rectangle rect = tab.GetTabRect (i);
3260                                                 if (!rect.IntersectsWith (area))
3261                                                         continue;
3262                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
3263                                         }
3264                                 }
3265                         } else {
3266                                 for (int r = 0; r < tab.TabPages.Count; r++) {
3267                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
3268                                                 if (i == tab.SelectedIndex)
3269                                                         continue;
3270                                                 if (r != tab.TabPages [i].Row)
3271                                                         continue;
3272                                                 Rectangle rect = tab.GetTabRect (i);
3273                                                 if (!rect.IntersectsWith (area))
3274                                                         continue;
3275                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
3276                                         }
3277                                 }
3278                         }
3279
3280                         if (tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos) {
3281                                 Rectangle rect = tab.GetTabRect (tab.SelectedIndex);
3282                                 if (rect.IntersectsWith (area))
3283                                         DrawTab (dc, tab.TabPages [tab.SelectedIndex], tab, rect, true);
3284                         }
3285
3286                         if (tab.ShowSlider) {
3287                                 Rectangle right = GetTabControlRightScrollRect (tab);
3288                                 Rectangle left = GetTabControlLeftScrollRect (tab);
3289                                 CPDrawScrollButton (dc, right, ScrollButton.Right, tab.RightSliderState);
3290                                 CPDrawScrollButton (dc, left, ScrollButton.Left, tab.LeftSliderState);
3291                         }
3292                 }
3293
3294                 public override Rectangle GetTabControlLeftScrollRect (TabControl tab)
3295                 {
3296                         switch (tab.Alignment) {
3297                         case TabAlignment.Top:
3298                                 return new Rectangle (tab.ClientRectangle.Right - 34, tab.ClientRectangle.Top + 1, 17, 17);
3299                         default:
3300                                 Rectangle panel_rect = GetTabPanelRectExt (tab);
3301                                 return new Rectangle (tab.ClientRectangle.Right - 34, panel_rect.Bottom + 2, 17, 17);
3302                         }
3303                 }
3304
3305                 public override Rectangle GetTabControlRightScrollRect (TabControl tab)
3306                 {
3307                         switch (tab.Alignment) {
3308                         case TabAlignment.Top:
3309                                 return new Rectangle (tab.ClientRectangle.Right - 17, tab.ClientRectangle.Top + 1, 17, 17);
3310                         default:
3311                                 Rectangle panel_rect = GetTabPanelRectExt (tab);
3312                                 return new Rectangle (tab.ClientRectangle.Right - 17, panel_rect.Bottom + 2, 17, 17);
3313                         }
3314                 }
3315
3316                 public override Size TabControlDefaultItemSize {
3317                         get { return new Size (42, 21); }
3318                 }
3319
3320                 public override Point TabControlDefaultPadding {
3321                         get { return new Point (6, 3); }
3322                 }
3323
3324                 public override int TabControlMinimumTabWidth {
3325                         get { return 42; }
3326                 }
3327
3328                 public override Rectangle GetTabControlDisplayRectangle (TabControl tab)
3329                 {
3330                         Rectangle ext = GetTabPanelRectExt (tab);
3331                         // Account for border size
3332                         return new Rectangle (ext.Left + 2, ext.Top + 1, ext.Width - 6, ext.Height - 4);
3333                 }
3334
3335                 public override Size TabControlGetSpacing (TabControl tab) {
3336                         switch (tab.Appearance) {
3337                                 case TabAppearance.Normal:
3338                                         return new Size (1, -2);
3339                                 case TabAppearance.Buttons:
3340                                         return new Size (3, 3);
3341                                 case TabAppearance.FlatButtons:
3342                                         return new Size (9, 3);
3343                                 default:
3344                                         throw new Exception ("Invalid Appearance value: " + tab.Appearance);
3345                                 }
3346                 }
3347
3348                 protected virtual Rectangle GetTabPanelRectExt (TabControl tab)
3349                 {
3350                         // Offset the tab from the top corner
3351                         Rectangle res = new Rectangle (tab.ClientRectangle.X + 2,
3352                                         tab.ClientRectangle.Y,
3353                                         tab.ClientRectangle.Width - 2,
3354                                         tab.ClientRectangle.Height - 1);
3355
3356                         if (tab.TabCount == 0)
3357                                 return res;
3358
3359                         int spacing = TabControlGetSpacing (tab).Height;
3360                         int offset = (tab.ItemSize.Height + spacing) * tab.RowCount + 3;
3361
3362                         switch (tab.Alignment) {
3363                         case TabAlignment.Left:
3364                                 res.X += offset;
3365                                 res.Width -= offset;
3366                                 break;
3367                         case TabAlignment.Right:
3368                                 res.Width -= offset;
3369                                 break;
3370                         case TabAlignment.Top:
3371                                 res.Y += offset;
3372                                 res.Height -= offset;
3373                                 break;
3374                         case TabAlignment.Bottom:
3375                                 res.Height -= offset;
3376                                 break;
3377                         }
3378
3379                         return res;
3380                 }
3381
3382                 protected virtual int DrawTab (Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected)
3383                 {
3384                         int FlatButtonSpacing = 8;
3385                         Rectangle interior;
3386                         int res = bounds.Width;
3387
3388                         
3389                         
3390                         // we can't fill the background right away because the bounds might be adjusted if the tab is selected
3391
3392                         StringFormat string_format = new StringFormat ();
3393                         if (tab.Appearance == TabAppearance.Buttons || tab.Appearance == TabAppearance.FlatButtons) {
3394                                 dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3395
3396                                 // Separators
3397                                 if (tab.Appearance == TabAppearance.FlatButtons) {
3398                                         int width = bounds.Width;
3399                                         bounds.Width += (FlatButtonSpacing - 2);
3400                                         res = bounds.Width;
3401                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Etched, Border3DSide.Right);
3402                                         bounds.Width = width;
3403                                 }
3404
3405                                 if (is_selected) {
3406                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Sunken, Border3DSide.All);
3407                                 } else if (tab.Appearance != TabAppearance.FlatButtons) {
3408                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Raised, Border3DSide.All);
3409                                 }
3410
3411                                 interior = new Rectangle (bounds.Left + 2, bounds.Top + 2, bounds.Width - 4, bounds.Height - 4);
3412
3413                                 
3414                                 string_format.Alignment = StringAlignment.Center;
3415                                 string_format.LineAlignment = StringAlignment.Center;
3416                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
3417                         } else {
3418                                 Pen light = ResPool.GetPen (ControlPaint.LightLight (tab.BackColor));
3419
3420                                 switch (tab.Alignment) {
3421                                         
3422                                 case TabAlignment.Top:
3423
3424
3425                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3426
3427                                         dc.DrawLine (light, bounds.Left, bounds.Bottom, bounds.Left, bounds.Top + 3);
3428                                         dc.DrawLine (light, bounds.Left, bounds.Top + 3, bounds.Left + 3, bounds.Top);
3429                                         dc.DrawLine (light, bounds.Left + 3, bounds.Top, bounds.Right - 3, bounds.Top);
3430
3431                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom);
3432                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 1, bounds.Top + 2, bounds.Right, bounds.Top + 3);
3433                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Top + 3, bounds.Right, bounds.Bottom);
3434
3435                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3436
3437                                         string_format.Alignment = StringAlignment.Center;
3438                                         string_format.LineAlignment = StringAlignment.Center;
3439                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
3440
3441                                         break;
3442
3443                                 case TabAlignment.Bottom:
3444
3445                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3446
3447                                         dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 3);
3448                                         dc.DrawLine (light, bounds.Left, bounds.Bottom - 3, bounds.Left + 2, bounds.Bottom - 1);
3449
3450                                         dc.DrawLine (SystemPens.ControlDark, bounds.Left + 3, bounds.Bottom - 1, bounds.Right - 3, bounds.Bottom - 1);
3451                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Bottom - 3, bounds.Right - 1, bounds.Top);
3452
3453                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 3, bounds.Bottom, bounds.Right - 3, bounds.Bottom);
3454                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 3, bounds.Bottom, bounds.Right, bounds.Bottom - 3);
3455                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Bottom - 3, bounds.Right, bounds.Top);
3456
3457                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3458
3459                                         string_format.Alignment = StringAlignment.Center;
3460                                         string_format.LineAlignment = StringAlignment.Center;
3461                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
3462
3463                                         break;
3464
3465                                 case TabAlignment.Left:
3466
3467                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3468
3469                                         dc.DrawLine (light, bounds.Left, bounds.Bottom - 3, bounds.Left, bounds.Top + 3);
3470                                         dc.DrawLine (light, bounds.Left, bounds.Top + 3, bounds.Left + 3, bounds.Top);
3471                                         dc.DrawLine (light, bounds.Left + 3, bounds.Top, bounds.Right, bounds.Top);
3472
3473                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right, bounds.Bottom - 1, bounds.Left + 2, bounds.Bottom - 1);
3474
3475                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Bottom, bounds.Left + 2, bounds.Bottom);
3476                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 2, bounds.Bottom, bounds.Left, bounds.Bottom - 3);
3477
3478                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3479
3480                                         string_format.Alignment = StringAlignment.Center;
3481                                         string_format.LineAlignment = StringAlignment.Center;
3482                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
3483                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
3484
3485                                         break;
3486
3487                                 default:
3488                                         // TabAlignment.Right
3489
3490                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3491
3492                                         dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Right - 3, bounds.Top);
3493                                         dc.DrawLine (light, bounds.Right - 3, bounds.Top, bounds.Right, bounds.Top + 3);
3494
3495                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom - 1);
3496                                         dc.DrawLine (SystemPens.ControlDark, bounds.Left, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom - 1);
3497
3498                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Top + 3, bounds.Right, bounds.Bottom - 3);
3499                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left, bounds.Bottom, bounds.Right - 3, bounds.Bottom);
3500
3501                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3502
3503                                         string_format.Alignment = StringAlignment.Center;
3504                                         string_format.LineAlignment = StringAlignment.Center;
3505                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
3506                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
3507
3508                                         break;
3509                                 }
3510
3511                                 if (tab.DrawMode == TabDrawMode.Normal && page.Text != null) {
3512                                         if (tab.Alignment == TabAlignment.Left) {
3513                                                 int wo = interior.Width / 2;
3514                                                 int ho = interior.Height / 2;
3515                                                 dc.TranslateTransform (interior.X + wo, interior.Y + ho);
3516                                                 dc.RotateTransform (180);
3517                                                 dc.DrawString (page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush (SystemColors.ControlText), 0, 0, string_format);
3518                                                 dc.ResetTransform ();
3519                                         } else {
3520                                                 dc.DrawString (page.Text, page.Font,
3521                                                                 ThemeEngine.Current.ResPool.GetSolidBrush (SystemColors.ControlText),
3522                                                                 interior, string_format);
3523                                         }
3524                                 } else if (page.Text != null) {
3525                                         DrawItemState state = DrawItemState.None;
3526                                         if (page == tab.SelectedTab)
3527                                                 state |= DrawItemState.Selected;
3528                                         DrawItemEventArgs e = new DrawItemEventArgs (dc,
3529                                                         tab.Font, bounds, tab.IndexForTabPage (page),
3530                                                         state, page.ForeColor, page.BackColor);
3531                                         tab.OnDrawItemInternal (e);
3532                                         return res;
3533                                 }
3534                         }
3535
3536                         if (page.Focused) {
3537                                 CPDrawFocusRectangle (dc, interior, tab.ForeColor, tab.BackColor);
3538                         }
3539
3540                         return res;
3541                 }
3542
3543                 #region ToolBar
3544                 public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) {
3545                         StringFormat    format = new StringFormat ();
3546                         format.Trimming = StringTrimming.EllipsisWord;
3547                         if (control.textAlignment == ToolBarTextAlign.Underneath) {
3548                                 format.LineAlignment = StringAlignment.Center;
3549                                 format.Alignment = StringAlignment.Center;
3550                         } else {
3551                                 format.LineAlignment = StringAlignment.Center;
3552                                 format.Alignment = StringAlignment.Near;
3553                         }
3554                         
3555                         // Exclude the area for divider
3556                         Rectangle paint_area = new Rectangle (0, ToolBarGripWidth / 2, 
3557                                 control.Width, control.Height - ToolBarGripWidth / 2);
3558                         bool flat = (control.Appearance == ToolBarAppearance.Flat);
3559                         dc.FillRectangle (ResPool.GetSolidBrush( DefaultControlBackColor ), paint_area);
3560                         if (control.Divider)
3561                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), 0, 0, paint_area.Width, 0);
3562
3563                         foreach (ToolBarButton button in control.Buttons) {
3564
3565                                 Image image = null;
3566                                 Rectangle buttonArea = button.Rectangle;
3567                                 Rectangle imgRect = Rectangle.Empty;  // rect to draw the image
3568                                 Rectangle txtRect = buttonArea;       // rect to draw the text
3569                                 Rectangle ddRect = Rectangle.Empty;   // rect for the drop down arrow
3570
3571                                 // calculate different rects and draw the frame if its not separator button
3572                                 if (button.Style != ToolBarButtonStyle.Separator) {
3573                                         /* Adjustment for drop down arrow */
3574                                         if (button.Style == ToolBarButtonStyle.DropDownButton && control.DropDownArrows) {
3575                                                 ddRect.X = buttonArea.X + buttonArea.Width - this.ToolBarDropDownWidth;
3576                                                 ddRect.Y = buttonArea.Y;
3577                                                 ddRect.Width = this.ToolBarDropDownWidth;
3578                                                 ddRect.Height = buttonArea.Height;
3579                                         }
3580
3581                                         // calculate txtRect and imgRect, if imageIndex and imageList are present
3582                                         if (button.ImageIndex > -1 && control.ImageList != null) {
3583                                                 if (button.ImageIndex < control.ImageList.Images.Count)
3584                                                         image = control.ImageList.Images [button.ImageIndex];
3585                                                 // draw the image at the centre if textalignment is underneath
3586                                                 if (control.TextAlign == ToolBarTextAlign.Underneath) {
3587                                                         imgRect.X = buttonArea.X + ((buttonArea.Width - ddRect.Width 
3588                                                                 - control.ImageSize.Width) / 2) 
3589                                                                 + this.ToolBarImageGripWidth;
3590                                                         imgRect.Y = buttonArea.Y + this.ToolBarImageGripWidth;
3591                                                         imgRect.Width = control.ImageSize.Width;
3592                                                         imgRect.Height = control.ImageSize.Height;
3593
3594                                                         txtRect.X = buttonArea.X;
3595                                                         txtRect.Y = buttonArea.Y + imgRect.Height + 2 * this.ToolBarImageGripWidth;
3596                                                         txtRect.Width = buttonArea.Width - ddRect.Width;
3597                                                         txtRect.Height = buttonArea.Height - imgRect.Height 
3598                                                                 - 2 * this.ToolBarImageGripWidth;
3599                                                 }
3600                                                 else {
3601                                                         imgRect.X = buttonArea.X + this.ToolBarImageGripWidth;
3602                                                         imgRect.Y = buttonArea.Y + this.ToolBarImageGripWidth;
3603                                                         imgRect.Width = control.ImageSize.Width;
3604                                                         imgRect.Height = control.ImageSize.Height;
3605
3606                                                         txtRect.X = buttonArea.X + imgRect.Width + 2 * this.ToolBarImageGripWidth;
3607                                                         txtRect.Y = buttonArea.Y;
3608                                                         txtRect.Width = buttonArea.Width - imgRect.Width 
3609                                                                 - 2 * this.ToolBarImageGripWidth - ddRect.Width;
3610                                                         txtRect.Height = buttonArea.Height;
3611                                                 }
3612                                         }
3613                                         /* Draw the button frame, only if it is not a separator */
3614                                         if (flat) { 
3615                                                 if (button.Pushed || button.Pressed) {
3616                                                         CPDrawBorder3D (dc, buttonArea, Border3DStyle.SunkenOuter, Border3DSide.All, ColorControl);
3617                                                 } else if (button.Hilight) {
3618                                                         dc.DrawRectangle (ResPool.GetPen (ColorControlText), buttonArea);
3619                                                         if (! ddRect.IsEmpty) {
3620                                                                 dc.DrawLine (ResPool.GetPen (ColorControlText), ddRect.X, ddRect.Y, ddRect.X, 
3621                                                                         ddRect.Y + ddRect.Height);
3622                                                                 buttonArea.Width -= this.ToolBarDropDownWidth;
3623                                                         }
3624                                                 }
3625                                         }
3626                                         else { // normal toolbar
3627                                                 if (button.Pushed || button.Pressed) {
3628                                                         CPDrawBorder3D (dc, buttonArea, Border3DStyle.SunkenInner,
3629                                                                 Border3DSide.All, ColorControl);
3630                                                         if (! ddRect.IsEmpty) {
3631                                                                 CPDrawBorder3D (dc, ddRect, Border3DStyle.SunkenInner,
3632                                                                         Border3DSide.Left, ColorControl);
3633                                                                 buttonArea.Width -= this.ToolBarDropDownWidth;
3634                                                         }
3635                                                 }
3636                                                 else {
3637                                                         CPDrawBorder3D (dc, buttonArea, Border3DStyle.RaisedInner,
3638                                                                 Border3DSide.All, ColorControl);
3639                                                         if (! ddRect.IsEmpty) {
3640                                                                 CPDrawBorder3D (dc, ddRect, Border3DStyle.RaisedInner,
3641                                                                         Border3DSide.Left, ColorControl);
3642                                                                 buttonArea.Width -= this.ToolBarDropDownWidth;
3643                                                         }
3644                                                 }
3645                                         }
3646                                 }
3647                                 DrawToolBarButton (dc, button, control.Font, format, paint_area, buttonArea,
3648                                         imgRect, image, txtRect, ddRect, flat);
3649                         }
3650                         format.Dispose ();
3651                 }
3652
3653                 private void DrawToolBarButton (Graphics dc, ToolBarButton button, Font font, StringFormat format,
3654                         Rectangle controlArea, Rectangle buttonArea, Rectangle imgRect, 
3655                         Image image, Rectangle txtRect, Rectangle ddRect, bool flat) {
3656                         if (! button.Visible)
3657                                 return;
3658
3659                         switch (button.Style) {
3660
3661                         case ToolBarButtonStyle.Separator:
3662                                 // separator is drawn only in the case of flat appearance
3663                                 if (flat) {
3664                                         dc.DrawLine (ResPool.GetPen (ColorControlDark), buttonArea.X + 1, buttonArea.Y, 
3665                                                 buttonArea.X + 1, buttonArea.Height);
3666                                         dc.DrawLine (ResPool.GetPen (ColorControlLight), buttonArea.X + 1 + (int) ResPool.GetPen (ColorControl).Width,
3667                                                 buttonArea.Y, buttonArea.X + 1 + (int) ResPool.GetPen (ColorControl).Width, buttonArea.Height);
3668                                         /* draw a horizontal separator */
3669                                         if (button.Wrapper) {
3670                                                 int y = buttonArea.Height + this.ToolBarSeparatorWidth / 2;
3671                                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), 0, y, controlArea.Width, y);
3672                                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), 0, y + 1 + (int) ResPool.GetPen (ColorControl).Width, controlArea.Width,
3673                                                         y + 1 + (int) ResPool.GetPen (ColorControl).Width);
3674                                         }
3675                                 }
3676                                 break;
3677
3678                         case ToolBarButtonStyle.ToggleButton:
3679                                 Rectangle toggleArea = Rectangle.Empty;
3680                                 toggleArea.X = buttonArea.X + this.ToolBarImageGripWidth;
3681                                 toggleArea.Y = buttonArea.Y + this.ToolBarImageGripWidth;
3682                                 toggleArea.Width = buttonArea.Width - 2 * this.ToolBarImageGripWidth;
3683                                 toggleArea.Height = buttonArea.Height - 2 * this.ToolBarImageGripWidth;
3684                                 if (button.PartialPush && button.Pushed) {
3685                                         dc.FillRectangle (SystemBrushes.ControlLightLight, toggleArea);
3686                                         if (! imgRect.IsEmpty) {
3687                                                 if (button.Enabled && image != null)
3688                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width, 
3689                                                                 imgRect.Height, button.ImageIndex);
3690                                                 else {
3691                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3692                                                         ControlPaint.DrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3693                                                                 Border3DSide.Right | Border3DSide.Bottom);
3694                                                 }
3695                                         }
3696                                         if (button.Enabled)
3697                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3698                                         else
3699                                                 CPDrawStringDisabled (dc, button.Text, font, ColorControlLight, txtRect, format);
3700                                 }
3701
3702                                 else if (button.PartialPush) {
3703                                         dc.FillRectangle (SystemBrushes.ControlLight, toggleArea);
3704                                         if (! imgRect.IsEmpty) {
3705                                                 if (button.Enabled && image != null)
3706                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width,
3707                                                                 imgRect.Height, button.ImageIndex);
3708                                                 else {
3709                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3710                                                         ControlPaint.DrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3711                                                                 Border3DSide.Right | Border3DSide.Bottom);
3712                                                 }
3713                                         }
3714                                         if (button.Enabled)
3715                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3716                                         else
3717                                                 CPDrawStringDisabled (dc, button.Text, font, ColorControlLight,
3718                                                         txtRect, format);
3719                                 }
3720
3721                                 else if (button.Pushed) {
3722                                         dc.FillRectangle (SystemBrushes.ControlLightLight, toggleArea);
3723                                         if (! imgRect.IsEmpty) {
3724                                                 if (button.Enabled && image != null)
3725                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width,
3726                                                                 imgRect.Height, button.ImageIndex);
3727                                                 else {
3728                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3729                                                         CPDrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3730                                                                 Border3DSide.Right | Border3DSide.Bottom, ColorControl);
3731                                                 }
3732                                         }
3733                                         if (button.Enabled)
3734                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3735                                         else
3736                                                 CPDrawStringDisabled (dc, button.Text, font, ColorControlLight,
3737                                                         txtRect, format);
3738                                 }
3739
3740                                 else {
3741                                         dc.FillRectangle (SystemBrushes.Control, toggleArea);
3742                                         if (! imgRect.IsEmpty) {
3743                                                 if (button.Enabled && image != null)
3744                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width,
3745                                                                 imgRect.Height, button.ImageIndex);
3746                                                 else {
3747                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3748                                                         CPDrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3749                                                                 Border3DSide.Right | Border3DSide.Bottom, ColorControl);
3750                                                 }
3751                                         }
3752                                         if (button.Enabled)
3753                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3754                                         else
3755                                                 CPDrawStringDisabled (dc, button.Text, font, ColorControlLight,
3756                                                         txtRect, format);
3757                                 }
3758                                 break;
3759
3760                         case ToolBarButtonStyle.DropDownButton:
3761                                 // draw the dropdown arrow
3762                                 if (! ddRect.IsEmpty) {
3763                                         PointF [] vertices = new PointF [3];
3764                                         PointF ddCenter = new PointF (ddRect.X + (ddRect.Width/2.0f), ddRect.Y + (ddRect.Height/2.0f));
3765                                         vertices [0].X = ddCenter.X - this.ToolBarDropDownArrowWidth / 2.0f + 0.5f;
3766                                         vertices [0].Y = ddCenter.Y;
3767                                         vertices [1].X = ddCenter.X + this.ToolBarDropDownArrowWidth / 2.0f + 0.5f;
3768                                         vertices [1].Y = ddCenter.Y;
3769                                         vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
3770                                         vertices [2].Y = ddCenter.Y + this.ToolBarDropDownArrowHeight;
3771                                         dc.FillPolygon (SystemBrushes.ControlText, vertices);
3772                                 }
3773                                 goto case ToolBarButtonStyle.PushButton;
3774
3775                         case ToolBarButtonStyle.PushButton:
3776                                 if (! imgRect.IsEmpty){
3777                                         if (button.Enabled && image != null)
3778                                                 button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width, imgRect.Height,
3779                                                         button.ImageIndex);
3780                                         else {
3781                                                 dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3782                                                 CPDrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3783                                                         Border3DSide.Right | Border3DSide.Bottom, ColorControl);
3784                                         }
3785                                 }
3786                                 if (button.Enabled)
3787                                         dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3788                                 else
3789                                         CPDrawStringDisabled (dc, button.Text, font, ColorControlLight,
3790                                                 txtRect, format);
3791                                 break;
3792                         }
3793                 }
3794
3795                 // Grip width for the ToolBar
3796                 public override int ToolBarGripWidth {
3797                         get { return 2;}
3798                 }
3799
3800                 // Grip width for the Image on the ToolBarButton
3801                 public override int ToolBarImageGripWidth {
3802                         get { return 2;}
3803                 }
3804
3805                 // width of the separator
3806                 public override int ToolBarSeparatorWidth {
3807                         get { return 4; }
3808                 }
3809
3810                 // width of the dropdown arrow rect
3811                 public override int ToolBarDropDownWidth {
3812                         get { return 13; }
3813                 }
3814
3815                 // width for the dropdown arrow on the ToolBarButton
3816                 public override int ToolBarDropDownArrowWidth {
3817                         get { return 5;}
3818                 }
3819
3820                 // height for the dropdown arrow on the ToolBarButton
3821                 public override int ToolBarDropDownArrowHeight {
3822                         get { return 3;}
3823                 }
3824
3825                 public override Size ToolBarDefaultSize {
3826                         get {
3827                                 return new Size (100, 42);
3828                         }
3829                 }
3830                 #endregion      // ToolBar
3831
3832                 #region ToolTip
3833                 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) {
3834                         dc.FillRectangle(ResPool.GetSolidBrush(this.ColorInfo), control.client_rect);
3835                         dc.DrawRectangle(ResPool.GetPen(this.ColorWindowFrame), 0, 0, control.Width-1, control.Height-1);
3836                         dc.DrawString(control.text, control.Font, ResPool.GetSolidBrush(this.ColorInfoText), control.client_rect, control.string_format);
3837                 }
3838
3839                 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text) {
3840                         SizeF   sizef;
3841
3842                         sizef = tt.DeviceContext.MeasureString(text, tt.Font);
3843                         return new Size((int)sizef.Width+2, (int)sizef.Height+3);               // Need space for the border
3844                 }
3845                 #endregion      // ToolTip
3846
3847                 #region TrackBar
3848                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
3849                         ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
3850                         float ticks, int value_pos, bool mouse_value) {                 
3851
3852                         Point toptick_startpoint = new Point ();
3853                         Point bottomtick_startpoint = new Point ();
3854                         Point channel_startpoint = new Point ();
3855                         float pixel_len;
3856                         float pixels_betweenticks;
3857                         const int space_from_right = 8;
3858                         const int space_from_left = 8;
3859                         Rectangle area = tb.ClientRectangle;
3860                         
3861                         switch (tb.TickStyle)   {
3862                         case TickStyle.BottomRight:
3863                         case TickStyle.None:
3864                                 channel_startpoint.Y = 8;
3865                                 channel_startpoint.X = 9;
3866                                 bottomtick_startpoint.Y = 13;
3867                                 bottomtick_startpoint.X = 24;                           
3868                                 break;
3869                         case TickStyle.TopLeft:
3870                                 channel_startpoint.Y = 8;
3871                                 channel_startpoint.X = 19;
3872                                 toptick_startpoint.Y = 13;
3873                                 toptick_startpoint.X = 8;
3874                                 break;
3875                         case TickStyle.Both:
3876                                 channel_startpoint.Y = 8;
3877                                 channel_startpoint.X = 18;      
3878                                 bottomtick_startpoint.Y = 13;
3879                                 bottomtick_startpoint.X = 32;                           
3880                                 toptick_startpoint.Y = 13;
3881                                 toptick_startpoint.X = 8;                               
3882                                 break;
3883                         default:
3884                                 break;
3885                         }
3886                         
3887                         thumb_area.X = area.X + channel_startpoint.X;
3888                         thumb_area.Y = area.Y + channel_startpoint.Y;
3889                         thumb_area.Height = area.Height - space_from_right - space_from_left;
3890                         thumb_area.Width = 4;
3891
3892                         /* Draw channel */
3893                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDark), channel_startpoint.X, channel_startpoint.Y,
3894                                 1, thumb_area.Height);
3895                         
3896                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDarkDark), channel_startpoint.X + 1, channel_startpoint.Y,
3897                                 1, thumb_area.Height);
3898
3899                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlLight), channel_startpoint.X + 3, channel_startpoint.Y,
3900                                 1, thumb_area.Height);
3901
3902                         pixel_len = thumb_area.Height - 11;
3903                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
3904                         
3905                         /* Convert thumb position from mouse position to value*/
3906                         if (mouse_value) {
3907                                 
3908                                 if (value_pos >= channel_startpoint.Y)
3909                                         value_pos = (int)(((float) (value_pos - channel_startpoint.Y)) / pixels_betweenticks);
3910                                 else
3911                                         value_pos = 0;                  
3912
3913                                 if (value_pos + tb.Minimum > tb.Maximum)
3914                                         value_pos = tb.Maximum - tb.Minimum;
3915                                 
3916                                 tb.Value = value_pos + tb.Minimum;
3917                         }                       
3918                         
3919                         thumb_pos.Y = channel_startpoint.Y + (int) (pixels_betweenticks * (float) value_pos);
3920                         
3921                         /* Draw thumb fixed 10x22 size */
3922                         thumb_pos.Width = 10;
3923                         thumb_pos.Height = 22;
3924
3925                         switch (tb.TickStyle)   {
3926                         case TickStyle.BottomRight:
3927                         case TickStyle.None: {
3928                                 thumb_pos.X = channel_startpoint.X - 8;
3929
3930                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X , thumb_pos.Y + 10);
3931                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
3932                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
3933                                 
3934                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X +1, thumb_pos.Y + 9, thumb_pos.X +15, thumb_pos.Y  +9);
3935                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X +16 + 4, thumb_pos.Y  +9 - 4);
3936
3937                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X, thumb_pos.Y  + 10, thumb_pos.X +16, thumb_pos.Y +10);
3938                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X + 16, thumb_pos.Y  + 10, thumb_pos.X  +16 + 5, thumb_pos.Y +10 - 5);
3939
3940                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
3941                                 dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
3942                                 dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
3943                                 dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
3944
3945                                 break;
3946                         }
3947                         case TickStyle.TopLeft: {
3948                                 thumb_pos.X = channel_startpoint.X - 10;
3949
3950                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
3951                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
3952
3953                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X  + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16 , thumb_pos.Y+ 9);
3954                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 4, thumb_pos.Y  + 9, thumb_pos.X, thumb_pos.Y + 5);
3955                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X  + 19, thumb_pos.Y + 9, thumb_pos.X  +19 , thumb_pos.Y+ 1);
3956
3957                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X  + 4, thumb_pos.Y+ 10, thumb_pos.X  + 4 + 16, thumb_pos.Y+ 10);
3958                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X  + 4, thumb_pos.Y + 10, thumb_pos.X  -1, thumb_pos.Y+ 5);
3959                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X+ 20, thumb_pos.Y + 10);
3960
3961                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
3962                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
3963                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
3964                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
3965
3966                                 break;
3967                         }
3968
3969                         case TickStyle.Both: {
3970                                 thumb_pos.X = area.X + 10;
3971                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
3972                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
3973
3974                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X+ 19, thumb_pos.Y  + 9);
3975                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X  + 10, thumb_pos.Y+ 1, thumb_pos.X + 19, thumb_pos.Y  + 8);
3976
3977                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X+ 20, thumb_pos.Y  +10);
3978                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X  + 20, thumb_pos.Y, thumb_pos.X  + 20, thumb_pos.Y+ 9);
3979
3980                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
3981
3982                                 break;
3983                         }
3984
3985                         default:
3986                                 break;
3987                         }
3988
3989                         pixel_len = thumb_area.Height - 11;
3990                         pixels_betweenticks = pixel_len / ticks;
3991                         
3992                         thumb_area.X = thumb_pos.X;
3993                         thumb_area.Y = channel_startpoint.Y;
3994                         thumb_area.Width = thumb_pos.Height;
3995                         
3996                         /* Draw ticks*/
3997                         Region outside = new Region (area);
3998                         outside.Exclude (thumb_area);                   
3999                         
4000                         if (outside.IsVisible (clip_rectangle)) {                               
4001                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
4002                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) { 
4003                                         
4004                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks)  {                                       
4005                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
4006                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X , area.Y + bottomtick_startpoint.Y  + inc, 
4007                                                                 area.X + bottomtick_startpoint.X  + 3, area.Y + bottomtick_startpoint.Y + inc);
4008                                                 else
4009                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X, area.Y + bottomtick_startpoint.Y  + inc, 
4010                                                                 area.X + bottomtick_startpoint.X  + 2, area.Y + bottomtick_startpoint.Y + inc);
4011                                         }
4012                                 }
4013         
4014                                 if (pixels_betweenticks > 0 &&  ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
4015                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
4016         
4017                                         pixel_len = thumb_area.Height - 11;
4018                                         pixels_betweenticks = pixel_len / ticks;
4019                                         
4020                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
4021                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
4022                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 3 , area.Y + toptick_startpoint.Y + inc, 
4023                                                                 area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc);
4024                                                 else
4025                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 2, area.Y + toptick_startpoint.Y + inc, 
4026                                                                 area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y  + inc);
4027                                         }                       
4028                                 }
4029                         }
4030                         
4031                         outside.Dispose ();
4032                         
4033                 }
4034
4035                 /* 
4036                         Horizontal trackbar 
4037                   
4038                         Does not matter the size of the control, Win32 always draws:
4039                                 - Ticks starting from pixel 13, 8
4040                                 - Channel starting at pos 8, 19 and ends at Width - 8
4041                                 - Autosize makes always the control 40 pixels height
4042                                 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
4043                                 
4044                 */
4045                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
4046                         ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
4047                         float ticks, int value_pos, bool mouse_value) {                 
4048                         Point toptick_startpoint = new Point ();
4049                         Point bottomtick_startpoint = new Point ();
4050                         Point channel_startpoint = new Point ();
4051                         float pixel_len;
4052                         float pixels_betweenticks;
4053                         const int space_from_right = 8;
4054                         const int space_from_left = 8;
4055                         Rectangle area = tb.ClientRectangle;
4056                                                 
4057                         switch (tb.TickStyle) {
4058                         case TickStyle.BottomRight:
4059                         case TickStyle.None:
4060                                 channel_startpoint.X = 8;
4061                                 channel_startpoint.Y = 9;
4062                                 bottomtick_startpoint.X = 13;
4063                                 bottomtick_startpoint.Y = 24;                           
4064                                 break;
4065                         case TickStyle.TopLeft:
4066                                 channel_startpoint.X = 8;
4067                                 channel_startpoint.Y = 19;
4068                                 toptick_startpoint.X = 13;
4069                                 toptick_startpoint.Y = 8;
4070                                 break;
4071                         case TickStyle.Both:
4072                                 channel_startpoint.X = 8;
4073                                 channel_startpoint.Y = 18;      
4074                                 bottomtick_startpoint.X = 13;
4075                                 bottomtick_startpoint.Y = 32;                           
4076                                 toptick_startpoint.X = 13;
4077                                 toptick_startpoint.Y = 8;                               
4078                                 break;
4079                         default:
4080                                 break;
4081                         }
4082                                                 
4083                         thumb_area.X = area.X + channel_startpoint.X;
4084                         thumb_area.Y = area.Y + channel_startpoint.Y;
4085                         thumb_area.Width = area.Width - space_from_right - space_from_left;
4086                         thumb_area.Height = 4;
4087                         
4088                         /* Draw channel */
4089                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDark), channel_startpoint.X, channel_startpoint.Y,
4090                                 thumb_area.Width, 1);
4091                         
4092                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDarkDark), channel_startpoint.X, channel_startpoint.Y + 1,
4093                                 thumb_area.Width, 1);
4094
4095                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlLight), channel_startpoint.X, channel_startpoint.Y +3,
4096                                 thumb_area.Width, 1);
4097
4098                         pixel_len = thumb_area.Width - 11;
4099                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
4100
4101                         /* Convert thumb position from mouse position to value*/
4102                         if (mouse_value) {                      
4103                                 if (value_pos >= channel_startpoint.X)
4104                                         value_pos = (int)(((float) (value_pos - channel_startpoint.X)) / pixels_betweenticks);
4105                                 else
4106                                         value_pos = 0;                          
4107
4108                                 if (value_pos + tb.Minimum > tb.Maximum)
4109                                         value_pos = tb.Maximum - tb.Minimum;
4110                                 
4111                                 tb.Value = value_pos + tb.Minimum;
4112                         }                       
4113                         
4114                         thumb_pos.X = channel_startpoint.X + (int) (pixels_betweenticks * (float) value_pos);
4115                         
4116                         /* Draw thumb fixed 10x22 size */
4117                         thumb_pos.Width = 10;
4118                         thumb_pos.Height = 22;
4119
4120                         switch (tb.TickStyle) {
4121                         case TickStyle.BottomRight:
4122                         case TickStyle.None: {
4123                                 thumb_pos.Y = channel_startpoint.Y - 8;
4124
4125                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
4126                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
4127                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
4128
4129                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X +9, thumb_pos.Y +15);
4130                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X +9 - 4, thumb_pos.Y +16 + 4);
4131
4132                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X +10, thumb_pos.Y +16);
4133                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X +10 - 5, thumb_pos.Y +16 + 5);
4134
4135                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
4136                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
4137                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
4138                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
4139                                 break;
4140                         }
4141                         case TickStyle.TopLeft: {
4142                                 thumb_pos.Y = channel_startpoint.Y - 10;
4143
4144                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
4145                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
4146
4147                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
4148                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
4149                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1 , thumb_pos.Y +19);
4150
4151                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
4152                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y -1);
4153                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
4154
4155                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
4156                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
4157                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
4158                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
4159                                 break;
4160                         }
4161
4162                         case TickStyle.Both: {
4163                                 thumb_pos.Y = area.Y + 10;
4164                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
4165                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
4166
4167                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
4168                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
4169
4170                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X +10, thumb_pos.Y + 20);
4171                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
4172
4173                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
4174
4175                                 break;
4176                         }
4177
4178                         default:
4179                                 break;
4180                         }
4181
4182                         pixel_len = thumb_area.Width - 11;
4183                         pixels_betweenticks = pixel_len / ticks;
4184
4185                         /* Draw ticks*/
4186                         thumb_area.Y = thumb_pos.Y;
4187                         thumb_area.X = channel_startpoint.X;
4188                         thumb_area.Height = thumb_pos.Height;
4189                         Region outside = new Region (area);
4190                         outside.Exclude (thumb_area);                   
4191                         
4192                         if (outside.IsVisible (clip_rectangle)) {                               
4193                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
4194                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {                         
4195                                         
4196                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
4197                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
4198                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y, 
4199                                                                 area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y + 3);
4200                                                 else
4201                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y, 
4202                                                                 area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y + 2);
4203                                         }
4204                                 }
4205         
4206                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
4207                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
4208                                         
4209                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
4210                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
4211                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y - 3, 
4212                                                                 area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y);
4213                                                 else
4214                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y - 2, 
4215                                                                 area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y );
4216                                         }                       
4217                                 }
4218                         }
4219                         
4220                         outside.Dispose ();                     
4221                 }
4222
4223                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) 
4224                 {
4225                         Brush           br_thumb;
4226                         int             value_pos;
4227                         bool            mouse_value;
4228                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
4229                         Rectangle       area;
4230                         Rectangle       thumb_pos = tb.ThumbPos;
4231                         Rectangle       thumb_area = tb.ThumbArea;
4232                         
4233                         if (tb.thumb_pressed) {
4234                                 value_pos = tb.thumb_mouseclick;
4235                                 mouse_value = true;
4236                         } else {
4237                                 value_pos = tb.Value - tb.Minimum;
4238                                 mouse_value = false;
4239                         }
4240
4241                         area = tb.ClientRectangle;
4242
4243                         if (tb.thumb_pressed == true) {
4244                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
4245                         } else {
4246                                 br_thumb = ResPool.GetSolidBrush (ColorControl);
4247                         }
4248
4249                         
4250                         /* Control Background */
4251                         if (tb.BackColor == DefaultControlBackColor) {
4252                                 dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), clip_rectangle);
4253                         } else {
4254                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
4255                         }
4256                         
4257
4258                         if (tb.Focused) {
4259                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControl, Color.Black), area.X, area.Y, area.Width - 1, 1);
4260                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControl, Color.Black), area.X, area.Y + area.Height - 1, area.Width - 1, 1);
4261                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControl, Color.Black), area.X, area.Y, 1, area.Height - 1);
4262                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControl, Color.Black), area.X + area.Width - 1, area.Y, 1, area.Height - 1);
4263                         }
4264
4265                         if (tb.Orientation == Orientation.Vertical) {
4266                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
4267                                         br_thumb, ticks, value_pos, mouse_value);
4268                         
4269                         } else {
4270                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
4271                                         br_thumb, ticks, value_pos, mouse_value);
4272                         }
4273
4274                         tb.ThumbPos = thumb_pos;
4275                         tb.ThumbArea = thumb_area;
4276                 }
4277
4278                 public override Size TrackBarDefaultSize {
4279                         get {
4280                                 return new Size (104, 42);
4281                         }
4282                 }
4283
4284                 #endregion      // TrackBar
4285
4286                 #region VScrollBar
4287                 public override Size VScrollBarDefaultSize {
4288                         get {
4289                                 return new Size (this.ScrollBarButtonSize, 80);
4290                         }
4291                 }
4292                 #endregion      // VScrollBar
4293
4294                 #region TreeView
4295                 public override Size TreeViewDefaultSize {
4296                         get {
4297                                 return new Size (121, 97);
4298                         }
4299                 }
4300
4301                 #endregion
4302
4303                 #region ControlPaint
4304                 private enum DrawFrameControlStates {
4305                         ButtonCheck             = 0x0000,
4306                         ButtonRadioImage        = 0x0001,
4307                         ButtonRadioMask         = 0x0002,
4308                         ButtonRadio             = 0x0004,
4309                         Button3State            = 0x0008,
4310                         ButtonPush              = 0x0010,
4311
4312                         CaptionClose            = 0x0000,
4313                         CaptionMin              = 0x0001,
4314                         CaptionMax              = 0x0002,
4315                         CaptionRestore          = 0x0004,
4316                         CaptionHelp             = 0x0008,
4317
4318                         MenuArrow               = 0x0000,
4319                         MenuCheck               = 0x0001,
4320                         MenuBullet              = 0x0002,
4321                         MenuArrowRight          = 0x0004,
4322
4323                         ScrollUp                = 0x0000,
4324                         ScrollDown              = 0x0001,
4325                         ScrollLeft              = 0x0002,
4326                         ScrollRight             = 0x0003,
4327                         ScrollComboBox          = 0x0005,
4328                         ScrollSizeGrip          = 0x0008,
4329                         ScrollSizeGripRight     = 0x0010,
4330
4331                         Inactive                = 0x0100,
4332                         Pushed                  = 0x0200,
4333                         Checked                 = 0x0400,
4334                         Transparent             = 0x0800,
4335                         Hot                     = 0x1000,
4336                         AdjustRect              = 0x2000,
4337                         Flat                    = 0x4000,
4338                         Mono                    = 0x8000
4339
4340                 }
4341
4342                 private enum DrawFrameControlTypes {
4343                         Caption = 1,
4344                         Menu    = 2,
4345                         Scroll  = 3,
4346                         Button  = 4
4347                 }
4348
4349                 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
4350                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
4351                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
4352                         int bottomWidth, ButtonBorderStyle bottomStyle) {
4353                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
4354                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
4355                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
4356                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
4357                 }
4358
4359                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
4360                         CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
4361                 }
4362
4363                 private void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color) {
4364                         Pen             penTopLeft;
4365                         Pen             penTopLeftInner;
4366                         Pen             penBottomRight;
4367                         Pen             penBottomRightInner;
4368                         Rectangle       rect= new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
4369                         bool            doInner = false;
4370
4371                         if ((style & Border3DStyle.Adjust)!=0) {
4372                                 rect.Y-=2;
4373                                 rect.X-=2;
4374                                 rect.Width+=4;
4375                                 rect.Height+=4;
4376                         }
4377
4378                         /* default to flat */
4379                         penTopLeft=ResPool.GetPen(ControlPaint.Dark(control_color));
4380                         penTopLeftInner=ResPool.GetPen(ControlPaint.Dark(control_color));
4381                         penBottomRight=ResPool.GetPen(ControlPaint.Dark(control_color));
4382                         penBottomRightInner=ResPool.GetPen(ControlPaint.Dark(control_color));
4383
4384                         if ((style & Border3DStyle.RaisedOuter)!=0) {
4385                                 penTopLeft=ResPool.GetPen(ControlPaint.LightLight(control_color));
4386                                 penBottomRight=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4387                                 if ((style & (Border3DStyle.RaisedInner | Border3DStyle.SunkenInner))!=0) {
4388                                         doInner=true;
4389                                 }
4390                         } else if ((style & Border3DStyle.SunkenOuter)!=0) {
4391                                 penTopLeft=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4392                                 penBottomRight=ResPool.GetPen(ControlPaint.LightLight(control_color));
4393                                 if ((style & (Border3DStyle.RaisedInner | Border3DStyle.SunkenInner))!=0) {
4394                                         doInner=true;
4395                                 }
4396                         }
4397
4398                         if ((style & Border3DStyle.RaisedInner)!=0) {
4399                                 if (doInner) {
4400                                         penTopLeftInner=ResPool.GetPen(control_color);
4401                                         penBottomRightInner=ResPool.GetPen(ControlPaint.Dark(control_color));
4402                                 } else {
4403                                         penTopLeft=ResPool.GetPen(ControlPaint.LightLight(control_color));
4404                                         penBottomRight=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4405                                 }
4406                         } else if ((style & Border3DStyle.SunkenInner)!=0) {
4407                                 if (doInner) {
4408                                         penTopLeftInner=ResPool.GetPen(ControlPaint.Dark(control_color));
4409                                         penBottomRightInner=ResPool.GetPen(control_color);
4410                                 } else {
4411                                         penTopLeft=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4412                                         penBottomRight=ResPool.GetPen(ControlPaint.LightLight(control_color));
4413                                 }
4414                         }
4415
4416                         if ((sides & Border3DSide.Middle)!=0) {
4417                                 graphics.FillRectangle(ResPool.GetSolidBrush(control_color), rect);
4418                         }
4419
4420                         if ((sides & Border3DSide.Left)!=0) {
4421                                 graphics.DrawLine(penTopLeft, rect.Left, rect.Bottom-2, rect.Left, rect.Top);
4422                                 if (doInner) {
4423                                         graphics.DrawLine(penTopLeftInner, rect.Left+1, rect.Bottom-2, rect.Left+1, rect.Top);
4424                                 }
4425                         }
4426
4427                         if ((sides & Border3DSide.Top)!=0) {
4428                                 graphics.DrawLine(penTopLeft, rect.Left, rect.Top, rect.Right-2, rect.Top);
4429
4430                                 if (doInner) {
4431                                         if ((sides & Border3DSide.Left)!=0) {
4432                                                 graphics.DrawLine(penTopLeftInner, rect.Left+1, rect.Top+1, rect.Right-3, rect.Top+1);
4433                                         } else {
4434                                                 graphics.DrawLine(penTopLeftInner, rect.Left, rect.Top+1, rect.Right-3, rect.Top+1);
4435                                         }
4436                                 }
4437                         }
4438
4439                         if ((sides & Border3DSide.Right)!=0) {
4440                                 graphics.DrawLine(penBottomRight, rect.Right-1, rect.Top, rect.Right-1, rect.Bottom-1);
4441
4442                                 if (doInner) {
4443                                         if ((sides & Border3DSide.Top)!=0) {
4444                                                 graphics.DrawLine(penBottomRightInner, rect.Right-2, rect.Top+1, rect.Right-2, rect.Bottom-2);
4445                                         } else {
4446                                                 graphics.DrawLine(penBottomRightInner, rect.Right-2, rect.Top, rect.Right-2, rect.Bottom-2);
4447                                         }
4448                                 }
4449                         }
4450
4451                         if ((sides & Border3DSide.Bottom)!=0) {
4452                                 int     left=rect.Left;
4453
4454                                 if ((sides & Border3DSide.Left)!=0) {
4455                                         left+=1;
4456                                 }
4457
4458                                 graphics.DrawLine(penBottomRight, rect.Left, rect.Bottom-1, rect.Right-1, rect.Bottom-1);
4459
4460                                 if (doInner) {
4461                                         if ((sides & Border3DSide.Right)!=0) {
4462                                                 graphics.DrawLine(penBottomRightInner, left, rect.Bottom-2, rect.Right-2, rect.Bottom-2);
4463                                         } else {
4464                                                 graphics.DrawLine(penBottomRightInner, left, rect.Bottom-2, rect.Right-2, rect.Bottom-2);
4465                                         }
4466                                 }
4467                         }
4468
4469                 }
4470
4471
4472                 public override void CPDrawButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
4473                         DrawFrameControlStates  dfcs=DrawFrameControlStates.ButtonPush;
4474
4475                         if ((state & ButtonState.Pushed)!=0) {
4476                                 dfcs |= DrawFrameControlStates.Pushed;
4477                         }
4478
4479                         if ((state & ButtonState.Checked)!=0) {
4480                                 dfcs |= DrawFrameControlStates.Checked;
4481                         }
4482
4483                         if ((state & ButtonState.Flat)!=0) {
4484                                 dfcs |= DrawFrameControlStates.Flat;
4485                         }
4486
4487                         if ((state & ButtonState.Inactive)!=0) {
4488                                 dfcs |= DrawFrameControlStates.Inactive;
4489                         }
4490                         DrawFrameControl(graphics, rectangle, DrawFrameControlTypes.Button, dfcs);
4491                 }
4492
4493
4494                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
4495                         Rectangle       captionRect;
4496                         int                     lineWidth;
4497
4498                         CPDrawButton(graphics, rectangle, state);
4499
4500                         if (rectangle.Width<rectangle.Height) {
4501                                 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
4502                         } else {
4503                                 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
4504                         }
4505
4506                         if ((state & ButtonState.Pushed)!=0) {
4507                                 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
4508                         }
4509
4510                         /* Make sure we've got at least a line width of 1 */
4511                         lineWidth=Math.Max(1, captionRect.Width/7);
4512
4513                         switch(button) {
4514                         case CaptionButton.Close: {
4515                                 Pen     pen;
4516
4517                                 if ((state & ButtonState.Inactive)!=0) {
4518                                         pen=new Pen(ColorControlLight, lineWidth);
4519                                         DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
4520                                         pen.Dispose();
4521
4522                                         pen=new Pen(ColorControlDark, lineWidth);
4523                                         DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
4524                                         pen.Dispose();
4525                                         return;
4526                                 } else {
4527                                         pen=new Pen(ColorControlText, lineWidth);
4528                                         DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
4529                                         pen.Dispose();
4530                                         return;
4531                                 }
4532                         }
4533
4534                         case CaptionButton.Help:
4535                         case CaptionButton.Maximize:
4536                         case CaptionButton.Minimize:
4537                         case CaptionButton.Restore: {
4538                                 if ((state & ButtonState.Inactive)!=0) {
4539                                         DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
4540
4541                                         DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
4542                                         return;
4543                                 } else {
4544                                         DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
4545                                         return;
4546                                 }
4547                         }
4548                         }
4549                 }
4550
4551
4552                 public override void CPDrawCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state) {
4553                         DrawFrameControlStates  dfcs=DrawFrameControlStates.ButtonCheck;
4554
4555                         if ((state & ButtonState.Pushed)!=0) {
4556                                 dfcs |= DrawFrameControlStates.Pushed;
4557                         }
4558
4559                         if ((state & ButtonState.Checked)!=0) {
4560                                 dfcs |= DrawFrameControlStates.Checked;
4561                         }
4562
4563                         if ((state & ButtonState.Flat)!=0) {
4564                                 dfcs |= DrawFrameControlStates.Flat;
4565                         }
4566
4567                         if ((state & ButtonState.Inactive)!=0) {
4568                                 dfcs |= DrawFrameControlStates.Inactive;
4569                         }
4570
4571                         DrawFrameControl(graphics, rectangle, DrawFrameControlTypes.Button, dfcs);
4572
4573                 }
4574
4575                 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
4576                         Point[]                 arrow = new Point[3];
4577                         Point                           P1;
4578                         Point                           P2;
4579                         Point                           P3;
4580                         int                             centerX;
4581                         int                             centerY;
4582                         int                             shiftX;
4583                         int                             shiftY;
4584                         Rectangle               rect;
4585
4586                         if ((state & ButtonState.Checked)!=0) {
4587                                 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);                              
4588                         }
4589
4590                         if ((state & ButtonState.Flat)!=0) {
4591                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
4592                         } else {
4593                                 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
4594                                         // this needs to render like a pushed button - jba
4595                                         // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
4596                                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
4597                                         graphics.DrawRectangle (ResPool.GetPen (ControlPaint.Dark (ColorControl)), trace_rectangle);
4598                                 } else {
4599                                         CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
4600                                 }
4601                         }
4602
4603                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
4604                         centerX=rect.Left+rect.Width/2;
4605                         centerY=rect.Top+rect.Height/2;
4606                         shiftX=Math.Max(1, rect.Width/8);
4607                         shiftY=Math.Max(1, rect.Height/8);
4608
4609                         if ((state & ButtonState.Pushed)!=0) {
4610                                 shiftX++;
4611                                 shiftY++;
4612                         }
4613
4614                         rect.Y-=shiftY;
4615                         centerY-=shiftY;
4616                         P1=new Point(rect.Left, centerY);
4617                         P2=new Point(rect.Right, centerY);
4618                         P3=new Point(centerX, rect.Bottom);
4619
4620                         arrow[0]=P1;
4621                         arrow[1]=P2;
4622                         arrow[2]=P3;
4623
4624                         /* Draw the arrow */
4625                         if ((state & ButtonState.Inactive)!=0) {
4626                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
4627
4628                                 /* Move away from the shadow */
4629                                 P1.X-=1;                P1.Y-=1;
4630                                 P2.X-=1;                P2.Y-=1;
4631                                 P3.X-=1;                P3.Y-=1;
4632
4633                                 arrow[0]=P1;
4634                                 arrow[1]=P2;
4635                                 arrow[2]=P3;
4636
4637
4638                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
4639                         } else {
4640                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
4641                         }
4642                 }
4643
4644
4645                 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds) {
4646                         
4647                         Pen                     pen     = new Pen(Color.Black, 1);
4648                         Rectangle       rect    = new Rectangle(bounds.X, bounds.Y, bounds.Width-1, bounds.Height-1);   // Dunno why, but MS does it that way, too
4649                         int                     X;
4650                         int                     Y;
4651
4652                         graphics.FillRectangle(ResPool.GetSolidBrush (ColorControlText), rect);
4653                         graphics.DrawRectangle(pen, rect);
4654
4655                         X=rect.X+rect.Width/2;
4656                         Y=rect.Y+rect.Height/2;
4657
4658                         /* Draw the cross */
4659                         graphics.DrawLine(pen, X, rect.Y+2, X, rect.Bottom-2);
4660                         graphics.DrawLine(pen, rect.X+2, Y, rect.Right-2, Y);
4661
4662                         /* Draw 'arrows' for vertical lines */
4663                         graphics.DrawLine(pen, X-1, rect.Y+3, X+1, rect.Y+3);
4664                         graphics.DrawLine(pen, X-1, rect.Bottom-3, X+1, rect.Bottom-3);
4665
4666                         /* Draw 'arrows' for horizontal lines */
4667                         graphics.DrawLine(pen, rect.X+3, Y-1, rect.X+3, Y+1);
4668                         graphics.DrawLine(pen, rect.Right-3, Y-1, rect.Right-3, Y+1);
4669                         pen.Dispose ();
4670
4671                 }
4672
4673                 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
4674                         // make a rectange to trace around border of the button
4675                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
4676                         
4677                         Color outerColor = foreColor;
4678                         // adjust focus color according to the flatstyle
4679                         if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
4680                                 outerColor = (backColor == ColorControl) ? ControlPaint.Dark(ColorControl) : ColorControlText;                          
4681                         }
4682                         
4683                         // draw the outer rectangle
4684                         graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);                  
4685                         
4686                         // draw the inner rectangle                                             
4687                         if (button.FlatStyle == FlatStyle.Popup) {
4688                                 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
4689                         } else {
4690                                 // draw a flat inner rectangle
4691                                 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
4692                                 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));                               
4693                         }
4694                 }
4695                 
4696                 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
4697                 {       
4698                         // make a rectange to trace around border of the button
4699                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
4700                         
4701 #if NotUntilCairoIsFixed
4702                         Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
4703                         DashStyle oldStyle; // used for caching old penstyle
4704                         Pen pen = ResPool.GetPen (colorBackInverted);
4705
4706                         oldStyle = pen.DashStyle; 
4707                         pen.DashStyle = DashStyle.Dot;
4708
4709                         graphics.DrawRectangle (pen, trace_rectangle);
4710                         pen.DashStyle = oldStyle;
4711 #else
4712                         CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
4713 #endif
4714                 }
4715                                 
4716
4717                 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) 
4718                 {                       
4719                         Rectangle rect = rectangle;
4720                         Pen pen;
4721                         HatchBrush brush;
4722                                 
4723                         if (backColor.GetBrightness () >= 0.5) {
4724                                 foreColor = Color.Transparent;
4725                                 backColor = Color.Black;
4726                                 
4727                         } else {
4728                                 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
4729                                 foreColor = Color.Black;
4730                         }
4731                                                 
4732                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
4733                         pen = new Pen (brush, 1);
4734                                                 
4735                         rect.Width--;
4736                         rect.Height--;                  
4737                         
4738                         graphics.DrawRectangle (pen, rect);
4739                         pen.Dispose ();
4740                 }
4741                 
4742                 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled) {
4743                         SolidBrush      sb;
4744                         Pen                     pen;
4745
4746                         if (primary==true) {
4747                                 pen=new Pen(Color.Black, 1);
4748                                 if (enabled==true) {
4749                                         sb=ResPool.GetSolidBrush (ColorControlText);
4750                                 } else {
4751                                         sb=ResPool.GetSolidBrush (ColorControl);
4752                                 }
4753                         } else {
4754                                 pen=new Pen(Color.White, 1);
4755                                 if (enabled==true) {
4756                                         sb=ThemeEngine.Current.ResPool.GetSolidBrush (Color.Black);
4757                                 } else {
4758                                         sb=ResPool.GetSolidBrush (ColorControl);
4759                                 }
4760                         }
4761                         graphics.FillRectangle(sb, rectangle);
4762                         graphics.DrawRectangle(pen, rectangle);                 
4763                         pen.Dispose();
4764                 }
4765
4766
4767                 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
4768                         Color   foreColor;
4769                         int     h;
4770                         int     b;
4771                         int     s;
4772
4773                         ControlPaint.Color2HBS(backColor, out h, out b, out s);
4774
4775                         if (b>127) {
4776                                 foreColor=Color.Black;
4777                         } else {
4778                                 foreColor=Color.White;
4779                         }
4780
4781 #if false
4782                         /* Commented out until I take the time and figure out
4783                                 which HatchStyle will match requirements. The code below
4784                                 is only correct for Percent50.
4785                         */
4786                         if (pixelsBetweenDots.Width==pixelsBetweenDots.Height) {
4787                                 HatchBrush      brush=null;
4788
4789                                 switch(pixelsBetweenDots.Width) {
4790                                         case 2: brush=new HatchBrush(HatchStyle.Percent50, foreColor, backColor); break;
4791                                         case 4: brush=new HatchBrush(HatchStyle.Percent25, foreColor, backColor); break;
4792                                         case 5: brush=new HatchBrush(HatchStyle.Percent20, foreColor, backColor); break;
4793                                         default: {
4794                                                 /* Have to do it the slow way */
4795                                                 break;
4796                                         }
4797                                 }
4798                                 if (brush!=null) {
4799                                         graphics.FillRectangle(brush, area);
4800                                         pen.Dispose();
4801                                         brush.Dispose();
4802                                         return;
4803                                 }
4804                         }
4805 #endif
4806                         /* Slow method */
4807
4808                         Bitmap bitmap = new Bitmap(area.Width, area.Height, graphics);
4809
4810                         for (int x=0; x<area.Width; x+=pixelsBetweenDots.Width) {
4811                                 for (int y=0; y<area.Height; y+=pixelsBetweenDots.Height) {
4812                                         bitmap.SetPixel(x, y, foreColor);
4813                                 }
4814                         }
4815                         graphics.DrawImage(bitmap, area.X, area.Y, area.Width, area.Height);
4816                         bitmap.Dispose();
4817                 }
4818
4819                 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
4820                         /*
4821                                 Microsoft seems to ignore the background and simply make
4822                                 the image grayscale. At least when having > 256 colors on
4823                                 the display.
4824                         */
4825                         
4826                         if (imagedisabled_attributes == null) {                         
4827                                 imagedisabled_attributes = new ImageAttributes ();
4828                                 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
4829                                           // This table would create a perfect grayscale image, based on luminance
4830                                           //                            new float[]{0.3f,0.3f,0.3f,0,0},
4831                                           //                            new float[]{0.59f,0.59f,0.59f,0,0},
4832                                           //                            new float[]{0.11f,0.11f,0.11f,0,0},
4833                                           //                            new float[]{0,0,0,1,0,0},
4834                                           //                            new float[]{0,0,0,0,1,0},
4835                                           //                            new float[]{0,0,0,0,0,1}
4836                 
4837                                           // This table generates a image that is grayscaled and then
4838                                           // brightened up. Seems to match MS close enough.
4839                                           new float[]{0.2f,0.2f,0.2f,0,0},
4840                                           new float[]{0.41f,0.41f,0.41f,0,0},
4841                                           new float[]{0.11f,0.11f,0.11f,0,0},
4842                                           new float[]{0.15f,0.15f,0.15f,1,0,0},
4843                                           new float[]{0.15f,0.15f,0.15f,0,1,0},
4844                                           new float[]{0.15f,0.15f,0.15f,0,0,1}
4845                                   });
4846                                   
4847                                  imagedisabled_attributes.SetColorMatrix (colorMatrix);
4848                         }
4849                         
4850                         graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
4851                         
4852                 }
4853
4854
4855                 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
4856                         Pen     penBorder;
4857                         Pen     penInside;
4858
4859                         if (primary) {
4860                                 penBorder=new Pen(Color.White, 2);
4861                                 penInside=new Pen(Color.Black, 1);
4862                         } else {
4863                                 penBorder=new Pen(Color.Black, 2);
4864                                 penInside=new Pen(Color.White, 1);
4865                         }
4866                         penBorder.Alignment=PenAlignment.Inset;
4867                         penInside.Alignment=PenAlignment.Inset;
4868
4869                         graphics.DrawRectangle(penBorder, rectangle);
4870                         graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
4871                         penBorder.Dispose();
4872                         penInside.Dispose();
4873                 }
4874
4875
4876                 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph) {
4877                         Rectangle       rect;
4878                         int                     lineWidth;
4879
4880                         // MS draws always the background white
4881                         graphics.FillRectangle(ResPool.GetSolidBrush (Color.White), rectangle);
4882
4883                         switch(glyph) {
4884                         case MenuGlyph.Arrow: {
4885                                 Point[]                 arrow = new Point[3];
4886                                 Point                           P1;
4887                                 Point                           P2;
4888                                 Point                           P3;
4889                                 int                             centerX;
4890                                 int                             centerY;
4891                                 int                             shiftX;
4892
4893                                 rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
4894                                 centerX=rect.Left+rect.Width/2;
4895                                 centerY=rect.Top+rect.Height/2;
4896                                 shiftX=Math.Max(1, rect.Width/8);
4897
4898                                 rect.X-=shiftX;
4899                                 centerX-=shiftX;
4900
4901                                 P1=new Point(centerX, rect.Top-1);
4902                                 P2=new Point(centerX, rect.Bottom);
4903                                 P3=new Point(rect.Right, centerY);
4904
4905                                 arrow[0]=P1;
4906                                 arrow[1]=P2;
4907                                 arrow[2]=P3;
4908
4909                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
4910
4911                                 return;
4912                         }
4913
4914                         case MenuGlyph.Bullet: {
4915                                 
4916                                 lineWidth=Math.Max(2, rectangle.Width/3);
4917                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
4918                                 
4919                                 graphics.FillEllipse(ResPool.GetSolidBrush (ColorControlText), rect);
4920                                 
4921                                 return;
4922                         }
4923
4924                         case MenuGlyph.Checkmark: {
4925                                 int                     Scale;
4926
4927                                 lineWidth=Math.Max(2, rectangle.Width/6);
4928                                 Scale=Math.Max(1, rectangle.Width/12);
4929
4930                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
4931
4932                                 for (int i=0; i<lineWidth; i++) {
4933                                         graphics.DrawLine(SystemPens.MenuText, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
4934                                         graphics.DrawLine(SystemPens.MenuText, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i, rect.Left+lineWidth/2+6*Scale, rect.Top+lineWidth-2*Scale+i);
4935                                 }
4936                                 return;
4937                         }
4938                         }
4939
4940                 }
4941
4942                 public override void CPDrawRadioButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
4943                         DrawFrameControlStates  dfcs=DrawFrameControlStates.ButtonRadio;
4944
4945                         if ((state & ButtonState.Pushed)!=0) {
4946                                 dfcs |= DrawFrameControlStates.Pushed;
4947                         }
4948
4949                         if ((state & ButtonState.Checked)!=0) {
4950                                 dfcs |= DrawFrameControlStates.Checked;
4951                         }
4952
4953                         if ((state & ButtonState.Flat)!=0) {
4954                                 dfcs |= DrawFrameControlStates.Flat;
4955                         }
4956
4957                         if ((state & ButtonState.Inactive)!=0) {
4958                                 dfcs |= DrawFrameControlStates.Inactive;
4959                         }
4960                         DrawFrameControl(graphics, rectangle, DrawFrameControlTypes.Button, dfcs);
4961
4962                 }
4963
4964
4965                 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
4966
4967                 }
4968
4969
4970                 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
4971
4972                 }
4973
4974
4975                 /* Scroll button: regular button + direction arrow */
4976                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state) {
4977                         bool enabled = (state == ButtonState.Inactive) ? false: true;                   
4978                                         
4979                         DrawScrollButtonPrimitive (dc, area, state);
4980
4981                         // A lot of the following is adapted from the rewind project
4982                         Rectangle rect = new Rectangle (area.X - 3, area.Y - 3,
4983                                         area.Width + 6, area.Height + 6);
4984                         int small_diam = rect.Width > rect.Height ? rect.Height : rect.Width;
4985                         if (rect.Width < rect.Height) {
4986                                 rect.Y += (rect.Height - rect.Width) / 2;
4987                                 rect.Height = small_diam;
4988                         } else if (rect.Width > rect.Height) {
4989                                 rect.X += (rect.Width - rect.Height) / 2;
4990                                 rect.Width = small_diam;
4991                         }
4992
4993                         small_diam -= 2;
4994
4995                         int tri = 290 * small_diam / 1000 - 1;
4996                         if (tri == 0)
4997                                 tri = 1;
4998
4999                         Point [] arrow = new Point [3];
5000                         for (int i = 0; i < 3; i++)
5001                                 arrow [i] = new Point ();
5002
5003                         switch(type) {
5004                         default:
5005                         case ScrollButton.Down:
5006                                 arrow [2].X = rect.Left + 470 * small_diam / 1000 + 2;
5007                                 arrow [2].Y = rect.Top + 687 * small_diam / 1000 + 1;
5008                                 arrow [0].X = arrow [2].X - tri;
5009                                 arrow [1].X = arrow [2].X + tri;
5010                                 arrow [0].Y = arrow [1].Y = arrow [2].Y - tri;
5011                                 break;
5012
5013                         case ScrollButton.Up:
5014                                 arrow [2].X = rect.Left + 470 * small_diam / 1000 + 2;
5015                                 arrow [2].Y = rect.Bottom - (687 * small_diam / 1000 + 1);
5016                                 arrow [0].X = arrow [2].X - tri;
5017                                 arrow [1].X = arrow [2].X + tri;
5018                                 arrow [0].Y = arrow [1].Y = arrow [2].Y + tri;
5019                                 break;
5020
5021                         case ScrollButton.Left:
5022                                 arrow [2].X = rect.Right - (687 * small_diam / 1000 + 1);
5023                                 arrow [2].Y = rect.Top + 470 * small_diam / 1000 + 2;
5024                                 arrow [0].Y = arrow [2].Y - tri;
5025                                 arrow [1].Y = arrow [2].Y + tri;
5026                                 arrow [0].X = arrow [1].X = arrow [2].X + tri;
5027                                 break;
5028                         case ScrollButton.Right:
5029                                 arrow [2].X = rect.Left + 687 * small_diam / 1000 + 1;
5030                                 arrow [2].Y = rect.Top + 470 * small_diam / 1000 + 2;
5031                                 arrow [0].Y = arrow [2].Y - tri;
5032                                 arrow [1].Y = arrow [2].Y + tri;
5033                                 arrow [0].X = arrow [1].X = arrow [2].X - tri;
5034                                 break;
5035                         }
5036
5037                         /* Draw the arrow */
5038                         if ((state & ButtonState.Inactive)!=0) {
5039                                 dc.FillPolygon (SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
5040
5041                                 for (int i = 0; i < 3; i++) {
5042                                         arrow [i].X--;
5043                                         arrow [i].Y--;
5044                                 }
5045                                 
5046                                 dc.FillPolygon (SystemBrushes.ControlDark, arrow, FillMode.Winding);
5047                         } else {
5048                                 dc.FillPolygon (SystemBrushes.ControlText, arrow, FillMode.Winding);
5049                         }
5050                 }
5051
5052                 public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
5053                         Color backColor) {
5054
5055                 }
5056
5057
5058                 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds) {
5059                         Point pt = new Point (bounds.Right - 2, bounds.Bottom - 1);
5060
5061                         dc.DrawLine (ResPool.GetPen (ColorControl), pt.X - 12, pt.Y, pt.X, pt.Y);
5062                         dc.DrawLine (ResPool.GetPen (ColorControl), pt.X, pt.Y, pt.X, pt.Y - 13);
5063
5064                         // diagonals
5065                         for (int i = 0; i < 11; i += 4) {
5066                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), pt.X - i, pt.Y, pt.X + 1, pt.Y - i - 2);
5067                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), pt.X - i - 1, pt.Y, pt.X + 1, pt.Y - i - 2);
5068                         }
5069
5070                         for (int i = 3; i < 13; i += 4)
5071                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), pt.X - i, pt.Y, pt.X + 1, pt.Y - i - 1);
5072                 }
5073
5074
5075                 public  override void CPDrawStringDisabled (Graphics graphics, string s, Font font, Color color, RectangleF layoutRectangle,
5076                         StringFormat format) {                  
5077
5078                         layoutRectangle.Offset(1.0f, 1.0f);
5079                         graphics.DrawString(s, font, ResPool.GetSolidBrush (ControlPaint.Light(color, 95)), layoutRectangle, format);                   
5080                         layoutRectangle.Offset(-1.0f, -1.0f);
5081                         graphics.DrawString(s, font, ResPool.GetSolidBrush (ControlPaint.Light(color, 50)), layoutRectangle, format);
5082                         
5083                 }
5084
5085                 private static void DrawBorderInternal(Graphics graphics, int startX, int startY, int endX, int endY,
5086                         int width, Color color, ButtonBorderStyle style, Border3DSide side) {
5087
5088                         Pen     pen=new Pen(color, 1);
5089
5090                         switch(style) {
5091                         case ButtonBorderStyle.Solid: {
5092                                 pen.DashStyle=DashStyle.Solid;
5093                                 break;
5094                         }
5095
5096                         case ButtonBorderStyle.Dashed: {
5097                                 pen.DashStyle=DashStyle.Dash;
5098                                 break;
5099                         }
5100
5101                         case ButtonBorderStyle.Dotted: {
5102                                 pen.DashStyle=DashStyle.Dot;
5103                                 break;
5104                         }
5105
5106                         case ButtonBorderStyle.Inset: {
5107                                 pen.DashStyle=DashStyle.Solid;
5108                                 break;
5109                         }
5110
5111                         case ButtonBorderStyle.Outset: {
5112                                 pen.DashStyle=DashStyle.Solid;
5113                                 break;
5114                         }
5115
5116                         default:
5117                         case ButtonBorderStyle.None: {
5118                                 pen.Dispose();
5119                                 return;
5120                         }
5121                         }
5122
5123
5124                         switch(style) {
5125                         case ButtonBorderStyle.Outset: {
5126                                 Color           colorGrade;
5127                                 int             hue, brightness, saturation;
5128                                 int             brightnessSteps;
5129                                 int             brightnessDownSteps;
5130
5131                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
5132
5133                                 brightnessDownSteps=brightness/width;
5134                                 if (brightness>127) {
5135                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
5136                                 } else {
5137                                         brightnessSteps=(127-brightness)/width;
5138                                 }
5139
5140                                 for (int i=0; i<width; i++) {
5141                                         switch(side) {
5142                                         case Border3DSide.Left: {
5143                                                 pen.Dispose();
5144                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
5145                                                 pen=new Pen(colorGrade, 1);
5146                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
5147                                                 break;
5148                                         }
5149
5150                                         case Border3DSide.Right: {
5151                                                 pen.Dispose();
5152                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
5153                                                 pen=new Pen(colorGrade, 1);
5154                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
5155                                                 break;
5156                                         }
5157
5158                                         case Border3DSide.Top: {
5159                                                 pen.Dispose();
5160                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
5161                                                 pen=new Pen(colorGrade, 1);
5162                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
5163                                                 break;
5164                                         }
5165
5166                                         case Border3DSide.Bottom: {
5167                                                 pen.Dispose();
5168                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
5169                                                 pen=new Pen(colorGrade, 1);
5170                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
5171                                                 break;
5172                                         }
5173                                         }
5174                                 }
5175                                 break;
5176                         }
5177
5178                         case ButtonBorderStyle.Inset: {
5179                                 Color           colorGrade;
5180                                 int             hue, brightness, saturation;
5181                                 int             brightnessSteps;
5182                                 int             brightnessDownSteps;
5183
5184                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
5185
5186                                 brightnessDownSteps=brightness/width;
5187                                 if (brightness>127) {
5188                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
5189                                 } else {
5190                                         brightnessSteps=(127-brightness)/width;
5191                                 }
5192
5193                                 for (int i=0; i<width; i++) {
5194                                         switch(side) {
5195                                         case Border3DSide.Left: {
5196                                                 pen.Dispose();
5197                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
5198                                                 pen=new Pen(colorGrade, 1);
5199                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
5200                                                 break;
5201                                         }
5202
5203                                         case Border3DSide.Right: {
5204                                                 pen.Dispose();
5205                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
5206                                                 pen=new Pen(colorGrade, 1);
5207                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
5208                                                 break;
5209                                         }
5210
5211                                         case Border3DSide.Top: {
5212                                                 pen.Dispose();
5213                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
5214                                                 pen=new Pen(colorGrade, 1);
5215                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
5216                                                 break;
5217                                         }
5218
5219                                         case Border3DSide.Bottom: {
5220                                                 pen.Dispose();
5221                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
5222                                                 pen=new Pen(colorGrade, 1);
5223                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
5224                                                 break;
5225                                         }
5226                                         }
5227                                 }
5228                                 break;
5229                         }
5230
5231                                 /*
5232                                         I decided to have the for-loop duplicated for speed reasons;
5233                                         that way we only have to switch once (as opposed to have the
5234                                         for-loop around the switch)
5235                                 */
5236                         default: {
5237                                 switch(side) {
5238                                 case Border3DSide.Left: {
5239                                         for (int i=0; i<width; i++) {
5240                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
5241                                         }
5242                                         break;
5243                                 }
5244
5245                                 case Border3DSide.Right: {
5246                                         for (int i=0; i<width; i++) {
5247                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
5248                                         }
5249                                         break;
5250                                 }
5251
5252                                 case Border3DSide.Top: {
5253                                         for (int i=0; i<width; i++) {
5254                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
5255                                         }
5256                                         break;
5257                                 }
5258
5259                                 case Border3DSide.Bottom: {
5260                                         for (int i=0; i<width; i++) {
5261                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
5262                                         }
5263                                         break;
5264                                 }
5265                                 }
5266                                 break;
5267                         }
5268                         }
5269                         pen.Dispose();
5270                 }
5271
5272                 /*
5273                         This function actually draws the various caption elements.
5274                         This way we can scale them nicely, no matter what size, and they
5275                         still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
5276                 */
5277
5278                 private static void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
5279                         switch(button) {
5280                         case CaptionButton.Close: {
5281                                 pen.StartCap=LineCap.Triangle;
5282                                 pen.EndCap=LineCap.Triangle;
5283                                 if (lineWidth<2) {
5284                                         graphics.DrawLine(pen, captionRect.Left+2*lineWidth+1+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+1+shift, captionRect.Bottom-2*lineWidth+shift);
5285                                         graphics.DrawLine(pen, captionRect.Right-2*lineWidth+1+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+1+shift, captionRect.Bottom-2*lineWidth+shift);
5286                                 }
5287
5288                                 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
5289                                 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
5290                                 return;
5291                         }
5292
5293                         case CaptionButton.Help: {
5294                                 StringFormat    sf = new StringFormat();                                
5295                                 Font                            font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
5296
5297                                 sf.Alignment=StringAlignment.Center;
5298                                 sf.LineAlignment=StringAlignment.Center;
5299
5300
5301                                 graphics.DrawString("?", font, ThemeEngine.Current.ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
5302
5303                                 sf.Dispose();                           
5304                                 font.Dispose();
5305
5306                                 return;
5307                         }
5308
5309                         case CaptionButton.Maximize: {
5310                                 /* Top 'caption bar' line */
5311                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
5312                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Top+2*lineWidth+shift+i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Top+2*lineWidth+shift+i);
5313                                 }
5314
5315                                 /* Left side line */
5316                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5317                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
5318                                 }
5319
5320                                 /* Right side line */
5321                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5322                                         graphics.DrawLine(pen, captionRect.Right-lineWidth-lineWidth/2+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Right-lineWidth-lineWidth/2+shift+i, captionRect.Bottom-lineWidth+shift);
5323                                 }
5324
5325                                 /* Bottom line */
5326                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5327                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
5328                                 }
5329                                 return;
5330                         }
5331
5332                         case CaptionButton.Minimize: {
5333                                 /* Bottom line */
5334                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
5335                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
5336                                 }
5337                                 return;
5338                         }
5339
5340                         case CaptionButton.Restore: {
5341                                 /** First 'window' **/
5342                                 /* Top 'caption bar' line */
5343                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
5344                                         graphics.DrawLine(pen, captionRect.Left+3*lineWidth+shift, captionRect.Top+2*lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Top+2*lineWidth+shift-i);
5345                                 }
5346
5347                                 /* Left side line */
5348                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5349                                         graphics.DrawLine(pen, captionRect.Left+3*lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+3*lineWidth+shift+i, captionRect.Top+4*lineWidth+shift);
5350                                 }
5351
5352                                 /* Right side line */
5353                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5354                                         graphics.DrawLine(pen, captionRect.Right-lineWidth-lineWidth/2+shift-i, captionRect.Top+2*lineWidth+shift, captionRect.Right-lineWidth-lineWidth/2+shift-i, captionRect.Top+5*lineWidth-lineWidth/2+shift);
5355                                 }
5356
5357                                 /* Bottom line */
5358                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5359                                         graphics.DrawLine(pen, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Top+5*lineWidth-lineWidth/2+shift+1+i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Top+5*lineWidth-lineWidth/2+shift+1+i);
5360                                 }
5361
5362                                 /** Second 'window' **/
5363                                 /* Top 'caption bar' line */
5364                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
5365                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Top+4*lineWidth+shift+1-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Top+4*lineWidth+shift+1-i);
5366                                 }
5367
5368                                 /* Left side line */
5369                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5370                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
5371                                 }
5372
5373                                 /* Right side line */
5374                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5375                                         graphics.DrawLine(pen, captionRect.Right-3*lineWidth-lineWidth/2+shift-i, captionRect.Top+4*lineWidth+shift+1, captionRect.Right-3*lineWidth-lineWidth/2+shift-i, captionRect.Bottom-lineWidth+shift);
5376                                 }
5377
5378                                 /* Bottom line */
5379                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
5380                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
5381                                 }
5382
5383                                 return;
5384                         }
5385
5386                         }
5387                 }
5388
5389                 [MonoTODO("Finish drawing code for Caption, Menu and Scroll")]
5390                 private void DrawFrameControl(Graphics graphics, Rectangle rectangle, DrawFrameControlTypes Type, DrawFrameControlStates State) {
5391                         // make a rectange to trace around border of the button
5392                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
5393                         switch(Type) {
5394                         case DrawFrameControlTypes.Button: {
5395
5396                                 if ((State & DrawFrameControlStates.ButtonPush)!=0) {
5397 // JBA 31 oct 2004 - I don't think that button style should be rendered like this
5398 //                                      /* Goes first, affects the background */
5399 //                                      if ((State & DrawFrameControlStates.Checked)!=0) {
5400 //                                              HatchBrush      hatchBrush=new HatchBrush(HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
5401 //                                              graphics.FillRectangle(hatchBrush,rectangle);
5402 //                                              hatchBrush.Dispose();
5403 //                                      }
5404
5405                                         if ((State & DrawFrameControlStates.Pushed)!=0 || (State & DrawFrameControlStates.Checked)!=0) {
5406                                                 graphics.DrawRectangle (ResPool.GetPen (ControlPaint.Dark (ColorControl)), trace_rectangle);
5407                                         } else if ((State & DrawFrameControlStates.Flat)!=0) {
5408                                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
5409                                         } else if ((State & DrawFrameControlStates.Inactive)!=0) {
5410                                                 /* Same as normal, it would seem */
5411                                                 CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
5412                                         } else {
5413                                                 CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
5414                                         }
5415                                 } else if ((State & DrawFrameControlStates.ButtonRadio)!=0) {
5416                                         Pen                     penFatDark      = new Pen(ColorControlDark, 1);
5417                                         Pen                     penFatLight     = new Pen(ColorControlLightLight, 1);
5418                                         int                     lineWidth;
5419
5420                                         graphics.FillPie (ResPool.GetSolidBrush (this.ColorWindow), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
5421
5422                                         graphics.DrawArc(penFatDark, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 135, 180);
5423                                         graphics.DrawArc(penFatLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 315, 180);
5424
5425                                         graphics.DrawArc(SystemPens.ControlDark, rectangle, 135, 180);
5426                                         graphics.DrawArc(SystemPens.ControlLightLight, rectangle, 315, 180);
5427
5428                                         lineWidth=Math.Max(1, Math.Min(rectangle.Width, rectangle.Height)/3);
5429
5430                                         if ((State & DrawFrameControlStates.Checked)!=0) {
5431                                                 SolidBrush      buttonBrush;
5432
5433                                                 if ((State & DrawFrameControlStates.Inactive)!=0) {
5434                                                         buttonBrush=(SolidBrush)SystemBrushes.ControlDark;
5435                                                 } else {
5436                                                         buttonBrush=(SolidBrush)SystemBrushes.ControlText;
5437                                                 }
5438                                                 graphics.FillPie(buttonBrush, rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2, 0, 359);
5439                                         }
5440                                         penFatDark.Dispose();
5441                                         penFatLight.Dispose();
5442                                 } else if ((State & DrawFrameControlStates.ButtonRadioImage)!=0) {
5443                                         throw new NotImplementedException () ;
5444                                 } else if ((State & DrawFrameControlStates.ButtonRadioMask)!=0) {
5445                                         throw new NotImplementedException ();
5446                                 } else {        /* Must be Checkbox */
5447                                         Pen                     pen;
5448                                         int                     lineWidth;
5449                                         Rectangle       rect;
5450                                         int                     Scale;
5451
5452                                         /* Goes first, affects the background */
5453                                         if ((State & DrawFrameControlStates.Pushed)!=0 ||
5454                                                 (State & DrawFrameControlStates.Inactive)!=0) {
5455                                                 graphics.FillRectangle(SystemBrushes.Control, rectangle);
5456                                         } else {
5457                                                 graphics.FillRectangle(SystemBrushes.Window, rectangle);
5458                                         }
5459
5460                                         /* Draw the sunken frame */
5461                                         if ((State & DrawFrameControlStates.Flat)!=0) {
5462                                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
5463                                         } else {
5464                                                 CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
5465                                         }
5466
5467                                         /* Make sure we've got at least a line width of 1 */
5468                                         lineWidth=Math.Max(3, rectangle.Width/6);
5469                                         Scale=Math.Max(1, rectangle.Width/12);
5470
5471                                         // define a rectangle inside the border area
5472                                         rect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-4, rectangle.Height-4);
5473                                         if ((State & DrawFrameControlStates.Inactive)!=0) {
5474                                                 pen=SystemPens.ControlDark;
5475                                         } else {
5476                                                 pen=SystemPens.ControlText;
5477                                         }
5478
5479                                         if ((State & DrawFrameControlStates.Checked)!=0) {
5480                                                 /* Need to draw a check-mark */
5481                                                 for (int i=0; i<lineWidth; i++) {
5482                                                         graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
5483                                                         graphics.DrawLine(pen, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i, rect.Left+lineWidth/2+6*Scale, rect.Top+lineWidth-2*Scale+i);
5484                                                 }
5485
5486                                         }
5487                                 }
5488                                 return;
5489                         }
5490
5491                         case DrawFrameControlTypes.Caption: {
5492                                 // FIXME:
5493                                 break;
5494                         }
5495
5496                         case DrawFrameControlTypes.Menu: {
5497                                 // FIXME:
5498                                 break;
5499                         }
5500
5501                         case DrawFrameControlTypes.Scroll: {
5502                                 // FIXME:
5503                                 break;
5504                         }
5505                         }
5506                 }
5507
5508                 /* Generic scroll button */
5509                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
5510                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
5511                                 dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), area.X + 1,
5512                                         area.Y + 1, area.Width - 2 , area.Height - 2);
5513
5514                                 dc.DrawRectangle (ResPool.GetPen (ColorControlDark), area.X,
5515                                         area.Y, area.Width, area.Height);
5516
5517                                 return;
5518                         }                       
5519         
5520                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), area.X, area.Y, area.Width, 1);
5521                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), area.X, area.Y, 1, area.Height);
5522
5523                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlLight), area.X + 1, area.Y + 1, area.Width - 1, 1);
5524                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlLight), area.X + 1, area.Y + 2, 1,
5525                                 area.Height - 4);
5526
5527                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDark), area.X + 1, area.Y + area.Height - 2,
5528                                 area.Width - 2, 1);
5529
5530                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDarkDark), area.X, area.Y + area.Height -1,
5531                                 area.Width , 1);
5532
5533                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDark), area.X + area.Width - 2,
5534                                 area.Y + 1, 1, area.Height -3);
5535
5536                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControlDarkDark), area.X + area.Width -1,
5537                                 area.Y, 1, area.Height - 1);
5538
5539                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), area.X + 2,
5540                                 area.Y + 2, area.Width - 4, area.Height - 4);
5541                         
5542                 }
5543                 
5544                 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
5545                         switch (border_style){
5546                         case BorderStyle.Fixed3D:
5547                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
5548                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
5549                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width , 
5550                                         area.Y + area.Height - 1);
5551                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, 
5552                                         area.Y + area.Height);
5553
5554                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
5555                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
5556                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
5557                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
5558                                 break;
5559                         case BorderStyle.FixedSingle:
5560                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
5561                                 break;
5562                         case BorderStyle.None:
5563                         default:
5564                                 break;
5565                         }
5566                         
5567                 }
5568                 #endregion      // ControlPaint
5569
5570
5571         } //class
5572 }