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