2008-07-29 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[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-2006 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 //      Alexander Olk, alex.olk@googlemail.com
28 //
29
30 using System.ComponentModel;
31 using System.Data;
32 using System.Drawing;
33 using System.Drawing.Drawing2D;
34 using System.Drawing.Imaging;
35 using System.Drawing.Printing;
36 using System.Drawing.Text;
37 using System.Text;
38 using System.Windows.Forms.Theming;
39
40 namespace System.Windows.Forms
41 {
42
43         internal class ThemeWin32Classic : Theme
44         {               
45                 public override Version Version {
46                         get {
47                                 return new Version(0, 1, 0, 0);
48                         }
49                 }
50
51                 /* Hardcoded colour values not exposed in the API constants in all configurations */
52                 protected static readonly Color arrow_color = Color.Black;
53                 protected static readonly Color pen_ticks_color = Color.Black;
54                 protected static readonly Color progressbarblock_color = Color.FromArgb (255, 0, 0, 128);
55                 protected static StringFormat string_format_menu_text;
56                 protected static StringFormat string_format_menu_shortcut;
57                 protected static StringFormat string_format_menu_menubar_text;
58                 static ImageAttributes imagedisabled_attributes = null;
59                 const int SEPARATOR_HEIGHT = 6;
60                 const int SEPARATOR_MIN_WIDTH = 20;
61                 const int SM_CXBORDER = 1;
62                 const int SM_CYBORDER = 1;              
63                 const int MENU_TAB_SPACE = 8;           // Pixels added to the width of an item because of a tabd
64                 const int MENU_BAR_ITEMS_SPACE = 8;     // Space between menu bar items
65
66                 #region Principal Theme Methods
67                 public ThemeWin32Classic ()
68                 {                       
69                         defaultWindowBackColor = this.ColorWindow;
70                         defaultWindowForeColor = this.ColorControlText;
71             window_border_font = new Font(FontFamily.GenericSansSerif, 8.25f, FontStyle.Bold);
72                         
73                         /* Menu string formats */
74                         string_format_menu_text = new StringFormat ();
75                         string_format_menu_text.LineAlignment = StringAlignment.Center;
76                         string_format_menu_text.Alignment = StringAlignment.Near;
77                         string_format_menu_text.HotkeyPrefix = HotkeyPrefix.Show;
78                         string_format_menu_text.SetTabStops (0f, new float [] { 50f });
79                         string_format_menu_text.FormatFlags |= StringFormatFlags.NoWrap;
80
81                         string_format_menu_shortcut = new StringFormat ();      
82                         string_format_menu_shortcut.LineAlignment = StringAlignment.Center;
83                         string_format_menu_shortcut.Alignment = StringAlignment.Far;
84
85                         string_format_menu_menubar_text = new StringFormat ();
86                         string_format_menu_menubar_text.LineAlignment = StringAlignment.Center;
87                         string_format_menu_menubar_text.Alignment = StringAlignment.Center;
88                         string_format_menu_menubar_text.HotkeyPrefix = HotkeyPrefix.Show;
89                 }
90
91                 public override void ResetDefaults() {
92                         Console.WriteLine("NOT IMPLEMENTED: ResetDefault()");
93                         //throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
94                 }
95
96                 public override bool DoubleBufferingSupported {
97                         get {return true; }
98                 }
99
100                 public override int HorizontalScrollBarHeight {
101                         get {
102                                 return XplatUI.HorizontalScrollBarHeight;
103                         }
104                 }
105
106                 public override int VerticalScrollBarWidth {
107                         get {
108                                 return XplatUI.VerticalScrollBarWidth;
109                         }
110                 }
111
112                 #endregion      // Principal Theme Methods
113
114                 #region Internal Methods
115                 protected Brush GetControlBackBrush (Color c) {
116                         if (c.ToArgb () == DefaultControlBackColor.ToArgb ())
117                                 return SystemBrushes.Control;
118                         return ResPool.GetSolidBrush (c);
119                 }
120
121                 protected Brush GetControlForeBrush (Color c) {
122                         if (c.ToArgb () == DefaultControlForeColor.ToArgb ())
123                                 return SystemBrushes.ControlText;
124                         return ResPool.GetSolidBrush (c);
125                 }
126                 #endregion      // Internal Methods
127
128                 #region Control
129                 public override Font GetLinkFont (Control control) 
130                 {
131                         return new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Underline, control.Font.Unit); 
132                 }
133                 #endregion      // Control
134
135                 #region OwnerDraw Support
136                 public  override void DrawOwnerDrawBackground (DrawItemEventArgs e)
137                 {
138                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
139                                 e.Graphics.FillRectangle (SystemBrushes.Highlight, e.Bounds);
140                                 return;
141                         }
142
143                         e.Graphics.FillRectangle (ResPool.GetSolidBrush(e.BackColor), e.Bounds);
144                 }
145
146                 public  override void DrawOwnerDrawFocusRectangle (DrawItemEventArgs e)
147                 {
148                         if (e.State == DrawItemState.Focus)
149                                 CPDrawFocusRectangle (e.Graphics, e.Bounds, e.ForeColor, e.BackColor);
150                 }
151                 #endregion      // OwnerDraw Support
152
153                 #region Button
154                 #region Standard Button Style
155                 public override void DrawButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
156                 {
157                         // Draw Button Background
158                         DrawButtonBackground (g, b, clipRectangle);
159
160                         // If we have an image, draw it
161                         if (imageBounds.Size != Size.Empty)
162                                 DrawButtonImage (g, b, imageBounds);
163
164                         // If we're focused, draw a focus rectangle
165                         if (b.Focused && b.Enabled && b.ShowFocusCues)
166                                 DrawButtonFocus (g, b);
167
168                         // If we have text, draw it
169                         if (textBounds != Rectangle.Empty)
170                                 DrawButtonText (g, b, textBounds);
171                 }
172
173                 public virtual void DrawButtonBackground (Graphics g, Button button, Rectangle clipArea) 
174                 {
175                         if (button.Pressed)
176                                 ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor);
177                         else if (button.InternalSelected)
178                                 ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor);
179                         else if (button.Entered)
180                                 ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor);
181                         else if (!button.Enabled)
182                                 ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor);
183                         else
184                                 ThemeElements.DrawButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor);
185                 }
186
187                 public virtual void DrawButtonFocus (Graphics g, Button button)
188                 {
189                         ControlPaint.DrawFocusRectangle (g, Rectangle.Inflate (button.ClientRectangle, -4, -4));
190                 }
191
192                 public virtual void DrawButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds)
193                 {
194                         if (button.Enabled)
195                                 g.DrawImage (button.Image, imageBounds);
196                         else
197                                 CPDrawImageDisabled (g, button.Image, imageBounds.Left, imageBounds.Top, ColorControl);
198                 }
199
200                 public virtual void DrawButtonText (Graphics g, ButtonBase button, Rectangle textBounds)
201                 {
202                         // Ensure that at least one line is going to get displayed.
203                         // Line limit does not ensure that despite its description.
204                         textBounds.Height = Math.Max (textBounds.Height, button.Font.Height);
205                         
206                         if (button.Enabled)
207                                 TextRenderer.DrawTextInternal (g, button.Text, button.Font, textBounds, button.ForeColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
208                         else
209                                 DrawStringDisabled20 (g, button.Text, button.Font, textBounds, button.BackColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
210                 }
211                 #endregion
212
213                 #region FlatStyle Button Style
214                 public override void DrawFlatButton (Graphics g, ButtonBase b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
215                 {
216                         // Draw Button Background
217                         if (b.BackgroundImage == null)
218                                 DrawFlatButtonBackground (g, b, clipRectangle);
219
220                         // If we have an image, draw it
221                         if (imageBounds.Size != Size.Empty)
222                                 DrawFlatButtonImage (g, b, imageBounds);
223
224                         // If we're focused, draw a focus rectangle
225                         if (b.Focused && b.Enabled && b.ShowFocusCues)
226                                 DrawFlatButtonFocus (g, b);
227
228                         // If we have text, draw it
229                         if (textBounds != Rectangle.Empty)
230                                 DrawFlatButtonText (g, b, textBounds);
231                 }
232
233                 public virtual void DrawFlatButtonBackground (Graphics g, ButtonBase button, Rectangle clipArea)
234                 {
235                         if (button.Pressed)
236                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor, button.FlatAppearance);
237                         else if (button.InternalSelected) {
238                                 if (button.Entered) 
239                                         ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default | ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
240                                 else
241                                         ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance);
242                         }
243                         else if (button.Entered)
244                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
245                         else if (!button.Enabled)
246                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor, button.FlatAppearance);
247                         else
248                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor, button.FlatAppearance);
249                 }
250
251                 public virtual void DrawFlatButtonFocus (Graphics g, ButtonBase button)
252                 {
253                         if (!button.Pressed) {
254                                 Color focus_color = ControlPaint.Dark (button.BackColor);
255                                 g.DrawRectangle (ResPool.GetPen (focus_color), new Rectangle (button.ClientRectangle.Left + 4, button.ClientRectangle.Top + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9));
256                         }
257                 }
258
259                 public virtual void DrawFlatButtonImage (Graphics g, ButtonBase button, Rectangle imageBounds)
260                 {
261                         // No changes from Standard for image for this theme
262                         DrawButtonImage (g, button, imageBounds);
263                 }
264
265                 public virtual void DrawFlatButtonText (Graphics g, ButtonBase button, Rectangle textBounds)
266                 {
267                         // No changes from Standard for text for this theme
268                         DrawButtonText (g, button, textBounds);
269                 }
270                 #endregion
271
272                 #region Popup Button Style
273                 public override void DrawPopupButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
274                 {
275                         // Draw Button Background
276                         DrawPopupButtonBackground (g, b, clipRectangle);
277
278                         // If we have an image, draw it
279                         if (imageBounds.Size != Size.Empty)
280                                 DrawPopupButtonImage (g, b, imageBounds);
281
282                         // If we're focused, draw a focus rectangle
283                         if (b.Focused && b.Enabled && b.ShowFocusCues)
284                                 DrawPopupButtonFocus (g, b);
285
286                         // If we have text, draw it
287                         if (textBounds != Rectangle.Empty)
288                                 DrawPopupButtonText (g, b, textBounds);
289                 }
290
291                 public virtual void DrawPopupButtonBackground (Graphics g, Button button, Rectangle clipArea)
292                 {
293                         if (button.Pressed)
294                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor);
295                         else if (button.Entered)
296                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor);
297                         else if (button.InternalSelected)
298                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor);
299                         else if (!button.Enabled)
300                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor);
301                         else
302                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor);
303                 }
304
305                 public virtual void DrawPopupButtonFocus (Graphics g, Button button)
306                 {
307                         // No changes from Standard for image for this theme
308                         DrawButtonFocus (g, button);
309                 }
310
311                 public virtual void DrawPopupButtonImage (Graphics g, Button button, Rectangle imageBounds)
312                 {
313                         // No changes from Standard for image for this theme
314                         DrawButtonImage (g, button, imageBounds);
315                 }
316
317                 public virtual void DrawPopupButtonText (Graphics g, Button button, Rectangle textBounds)
318                 {
319                         // No changes from Standard for image for this theme
320                         DrawButtonText (g, button, textBounds);
321                 }
322                 #endregion
323
324                 #region Button Layout Calculations
325 #if NET_2_0
326                 public override Size CalculateButtonAutoSize (Button button)
327                 {
328                         Size ret_size = Size.Empty;
329                         Size text_size = TextRenderer.MeasureTextInternal (button.Text, button.Font, button.UseCompatibleTextRendering);
330                         Size image_size = button.Image == null ? Size.Empty : button.Image.Size;
331                         
332                         // Pad the text size
333                         if (button.Text.Length != 0) {
334                                 text_size.Height += 4;
335                                 text_size.Width += 4;
336                         }
337                         
338                         switch (button.TextImageRelation) {
339                                 case TextImageRelation.Overlay:
340                                         ret_size.Height = Math.Max (button.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
341                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
342                                         break;
343                                 case TextImageRelation.ImageAboveText:
344                                 case TextImageRelation.TextAboveImage:
345                                         ret_size.Height = text_size.Height + image_size.Height;
346                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
347                                         break;
348                                 case TextImageRelation.ImageBeforeText:
349                                 case TextImageRelation.TextBeforeImage:
350                                         ret_size.Height = Math.Max (text_size.Height, image_size.Height);
351                                         ret_size.Width = text_size.Width + image_size.Width;
352                                         break;
353                         }
354
355                         // Pad the result
356                         ret_size.Height += (button.Padding.Vertical + 6);
357                         ret_size.Width += (button.Padding.Horizontal + 6);
358                         
359                         return ret_size;
360                 }
361 #endif
362
363                 public override void CalculateButtonTextAndImageLayout (ButtonBase button, out Rectangle textRectangle, out Rectangle imageRectangle)
364                 {
365                         Image image = button.Image;
366                         string text = button.Text;
367                         Rectangle content_rect = button.ClientRectangle;
368                         Size text_size = TextRenderer.MeasureTextInternal (text, button.Font, content_rect.Size, button.TextFormatFlags, button.UseCompatibleTextRendering);
369                         Size image_size = image == null ? Size.Empty : image.Size;
370
371                         textRectangle = Rectangle.Empty;
372                         imageRectangle = Rectangle.Empty;
373                         
374                         switch (button.TextImageRelation) {
375                                 case TextImageRelation.Overlay:
376                                         // Overlay is easy, text always goes here
377                                         textRectangle = Rectangle.Inflate (content_rect, -4, -4);
378
379                                         if (button.Pressed)
380                                                 textRectangle.Offset (1, 1);
381                                                 
382                                         // Image is dependent on ImageAlign
383                                         if (image == null)
384                                                 return;
385                                                 
386                                         int image_x = 0;
387                                         int image_y = 0;
388                                         int image_height = image.Height;
389                                         int image_width = image.Width;
390                                         
391                                         switch (button.ImageAlign) {
392                                                 case System.Drawing.ContentAlignment.TopLeft:
393                                                         image_x = 5;
394                                                         image_y = 5;
395                                                         break;
396                                                 case System.Drawing.ContentAlignment.TopCenter:
397                                                         image_x = (content_rect.Width - image_width) / 2;
398                                                         image_y = 5;
399                                                         break;
400                                                 case System.Drawing.ContentAlignment.TopRight:
401                                                         image_x = content_rect.Width - image_width - 5;
402                                                         image_y = 5;
403                                                         break;
404                                                 case System.Drawing.ContentAlignment.MiddleLeft:
405                                                         image_x = 5;
406                                                         image_y = (content_rect.Height - image_height) / 2;
407                                                         break;
408                                                 case System.Drawing.ContentAlignment.MiddleCenter:
409                                                         image_x = (content_rect.Width - image_width) / 2;
410                                                         image_y = (content_rect.Height - image_height) / 2;
411                                                         break;
412                                                 case System.Drawing.ContentAlignment.MiddleRight:
413                                                         image_x = content_rect.Width - image_width - 4;
414                                                         image_y = (content_rect.Height - image_height) / 2;
415                                                         break;
416                                                 case System.Drawing.ContentAlignment.BottomLeft:
417                                                         image_x = 5;
418                                                         image_y = content_rect.Height - image_height - 4;
419                                                         break;
420                                                 case System.Drawing.ContentAlignment.BottomCenter:
421                                                         image_x = (content_rect.Width - image_width) / 2;
422                                                         image_y = content_rect.Height - image_height - 4;
423                                                         break;
424                                                 case System.Drawing.ContentAlignment.BottomRight:
425                                                         image_x = content_rect.Width - image_width - 4;
426                                                         image_y = content_rect.Height - image_height - 4;
427                                                         break;
428                                                 default:
429                                                         image_x = 5;
430                                                         image_y = 5;
431                                                         break;
432                                         }
433                                         
434                                         imageRectangle = new Rectangle (image_x, image_y, image_width, image_height);
435                                         break;
436                                 case TextImageRelation.ImageAboveText:
437                                         content_rect.Inflate (-4, -4);
438                                         LayoutTextAboveOrBelowImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
439                                         break;
440                                 case TextImageRelation.TextAboveImage:
441                                         content_rect.Inflate (-4, -4);
442                                         LayoutTextAboveOrBelowImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
443                                         break;
444                                 case TextImageRelation.ImageBeforeText:
445                                         content_rect.Inflate (-4, -4);
446                                         LayoutTextBeforeOrAfterImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
447                                         break;
448                                 case TextImageRelation.TextBeforeImage:
449                                         content_rect.Inflate (-4, -4);
450                                         LayoutTextBeforeOrAfterImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
451                                         break;
452                         }
453                 }
454
455                 private void LayoutTextBeforeOrAfterImage (Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, System.Drawing.ContentAlignment textAlign, System.Drawing.ContentAlignment imageAlign, out Rectangle textRect, out Rectangle imageRect)
456                 {
457                         int element_spacing = 0;        // Spacing between the Text and the Image
458                         int total_width = textSize.Width + element_spacing + imageSize.Width;
459                         
460                         if (!textFirst)
461                                 element_spacing += 2;
462                                 
463                         // If the text is too big, chop it down to the size we have available to it
464                         if (total_width > totalArea.Width) {
465                                 textSize.Width = totalArea.Width - element_spacing - imageSize.Width;
466                                 total_width = totalArea.Width;
467                         }
468                         
469                         int excess_width = totalArea.Width - total_width;
470                         int offset = 0;
471
472                         Rectangle final_text_rect;
473                         Rectangle final_image_rect;
474
475                         HorizontalAlignment h_text = GetHorizontalAlignment (textAlign);
476                         HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign);
477
478                         if (h_image == HorizontalAlignment.Left)
479                                 offset = 0;
480                         else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right)
481                                 offset = excess_width;
482                         else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center))
483                                 offset += (int)(excess_width / 3);
484                         else
485                                 offset += (int)(2 * (excess_width / 3));
486
487                         if (textFirst) {
488                                 final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
489                                 final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
490                         }
491                         else {
492                                 final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
493                                 final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
494                         }
495
496                         textRect = final_text_rect;
497                         imageRect = final_image_rect;
498                 }
499
500                 private void LayoutTextAboveOrBelowImage (Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, System.Drawing.ContentAlignment textAlign, System.Drawing.ContentAlignment imageAlign, out Rectangle textRect, out Rectangle imageRect)
501                 {
502                         int element_spacing = 0;        // Spacing between the Text and the Image
503                         int total_height = textSize.Height + element_spacing + imageSize.Height;
504
505                         if (textFirst)
506                                 element_spacing += 2;
507
508                         if (textSize.Width > totalArea.Width)
509                                 textSize.Width = totalArea.Width;
510                                 
511                         // If the there isn't enough room and we're text first, cut out the image
512                         if (total_height > totalArea.Height && textFirst) {
513                                 imageSize = Size.Empty;
514                                 total_height = totalArea.Height;
515                         }
516
517                         int excess_height = totalArea.Height - total_height;
518                         int offset = 0;
519
520                         Rectangle final_text_rect;
521                         Rectangle final_image_rect;
522
523                         VerticalAlignment v_text = GetVerticalAlignment (textAlign);
524                         VerticalAlignment v_image = GetVerticalAlignment (imageAlign);
525
526                         if (v_image == VerticalAlignment.Top)
527                                 offset = 0;
528                         else if (v_image == VerticalAlignment.Bottom && v_text == VerticalAlignment.Bottom)
529                                 offset = excess_height;
530                         else if (v_image == VerticalAlignment.Center && (v_text == VerticalAlignment.Top || v_text == VerticalAlignment.Center))
531                                 offset += (int)(excess_height / 3);
532                         else
533                                 offset += (int)(2 * (excess_height / 3));
534
535                         if (textFirst) {
536                                 final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, totalArea.Top + offset, textSize.Width, textSize.Height);
537                                 final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, final_text_rect.Bottom + element_spacing, imageSize.Width, imageSize.Height);
538                         }
539                         else {
540                                 final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, totalArea.Top + offset, imageSize.Width, imageSize.Height);
541                                 final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, final_image_rect.Bottom + element_spacing, textSize.Width, textSize.Height);
542                                 
543                                 if (final_text_rect.Bottom > totalArea.Bottom)
544                                         final_text_rect.Y = totalArea.Top;
545                         }
546
547                         textRect = final_text_rect;
548                         imageRect = final_image_rect;
549                 }
550                 
551                 private HorizontalAlignment GetHorizontalAlignment (System.Drawing.ContentAlignment align)
552                 {
553                         switch (align) {
554                                 case System.Drawing.ContentAlignment.BottomLeft:
555                                 case System.Drawing.ContentAlignment.MiddleLeft:
556                                 case System.Drawing.ContentAlignment.TopLeft:
557                                         return HorizontalAlignment.Left;
558                                 case System.Drawing.ContentAlignment.BottomCenter:
559                                 case System.Drawing.ContentAlignment.MiddleCenter:
560                                 case System.Drawing.ContentAlignment.TopCenter:
561                                         return HorizontalAlignment.Center;
562                                 case System.Drawing.ContentAlignment.BottomRight:
563                                 case System.Drawing.ContentAlignment.MiddleRight:
564                                 case System.Drawing.ContentAlignment.TopRight:
565                                         return HorizontalAlignment.Right;
566                         }
567
568                         return HorizontalAlignment.Left;
569                 }
570
571                 private enum VerticalAlignment
572                 {
573                         Top = 0,
574                         Center = 1,
575                         Bottom = 2
576                 }
577                 
578                 private VerticalAlignment GetVerticalAlignment (System.Drawing.ContentAlignment align)
579                 {
580                         switch (align) {
581                                 case System.Drawing.ContentAlignment.TopLeft:
582                                 case System.Drawing.ContentAlignment.TopCenter:
583                                 case System.Drawing.ContentAlignment.TopRight:
584                                         return VerticalAlignment.Top;
585                                 case System.Drawing.ContentAlignment.MiddleLeft:
586                                 case System.Drawing.ContentAlignment.MiddleCenter:
587                                 case System.Drawing.ContentAlignment.MiddleRight:
588                                         return VerticalAlignment.Center;
589                                 case System.Drawing.ContentAlignment.BottomLeft:
590                                 case System.Drawing.ContentAlignment.BottomCenter:
591                                 case System.Drawing.ContentAlignment.BottomRight:
592                                         return VerticalAlignment.Bottom;
593                         }
594
595                         return VerticalAlignment.Top;
596                 }
597
598                 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, System.Drawing.ContentAlignment align)
599                 {
600                         int x = 0;
601                         int y = 0;
602
603                         if (align == System.Drawing.ContentAlignment.BottomLeft || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.TopLeft)
604                                 x = outer.X;
605                         else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.TopCenter)
606                                 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
607                         else if (align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.MiddleRight || align == System.Drawing.ContentAlignment.TopRight)
608                                 x = outer.Right - inner.Width;
609                         if (align == System.Drawing.ContentAlignment.TopCenter || align == System.Drawing.ContentAlignment.TopLeft || align == System.Drawing.ContentAlignment.TopRight)
610                                 y = outer.Y;
611                         else if (align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.MiddleRight)
612                                 y = outer.Y + (outer.Height - inner.Height) / 2;
613                         else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.BottomLeft)
614                                 y = outer.Bottom - inner.Height;
615
616                         return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
617                 }
618                 #endregion
619                 #endregion
620
621                 #region ButtonBase
622                 public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button)
623                 {
624                         // Draw the button: Draw border, etc.
625                         ButtonBase_DrawButton(button, dc);
626
627                         // Draw the image
628                         if (button.FlatStyle != FlatStyle.System && ((button.image != null) || (button.image_list != null)))
629                                 ButtonBase_DrawImage(button, dc);
630                         
631                         // Draw the focus rectangle
632                         if (ShouldPaintFocusRectagle (button))
633                                 ButtonBase_DrawFocus(button, dc);
634                         
635                         // Now the text
636                         if (button.Text != null && button.Text != String.Empty)
637                                 ButtonBase_DrawText(button, dc);
638                 }
639
640                 protected static bool ShouldPaintFocusRectagle (ButtonBase button)
641                 {
642                         return (button.Focused || button.paint_as_acceptbutton) && button.Enabled && button.ShowFocusCues;
643                 }
644
645                 protected virtual void ButtonBase_DrawButton (ButtonBase button, Graphics dc)
646                 {
647                         Rectangle borderRectangle;
648                         bool check_or_radio = false;
649                         bool check_or_radio_checked = false;
650                         
651                         bool is_ColorControl = button.BackColor.ToArgb () == ColorControl.ToArgb () ? true : false;
652                         
653                         CPColor cpcolor = is_ColorControl ? CPColor.Empty : ResPool.GetCPColor (button.BackColor);
654                         
655                         if (button is CheckBox) {
656                                 check_or_radio = true;
657                                 check_or_radio_checked = ((CheckBox)button).Checked;
658                         } else if (button is RadioButton) {
659                                 check_or_radio = true;
660                                 check_or_radio_checked = ((RadioButton)button).Checked;
661                         }
662                         
663                         if ((button.Focused || button.paint_as_acceptbutton) && button.Enabled && !check_or_radio) {
664                                 // shrink the rectangle for the normal button drawing inside the focus rectangle
665                                 borderRectangle = Rectangle.Inflate (button.ClientRectangle, -1, -1);
666                         } else {
667                                 borderRectangle = button.ClientRectangle;
668                         }
669                         
670                         if (button.FlatStyle == FlatStyle.Popup) {
671                                 if (!button.is_pressed && !button.is_entered && !check_or_radio_checked)
672                                         Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
673                                 else if (!button.is_pressed && button.is_entered &&!check_or_radio_checked)
674                                         Internal_DrawButton (dc, borderRectangle, 2, cpcolor, is_ColorControl, button.BackColor);
675                                 else if (button.is_pressed || check_or_radio_checked)
676                                         Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
677                         } else if (button.FlatStyle == FlatStyle.Flat) {
678                                 if (button.is_entered && !button.is_pressed && !check_or_radio_checked) {
679                                         if ((button.image == null) && (button.image_list == null)) {
680                                                 Brush brush = is_ColorControl ? SystemBrushes.ControlDark : ResPool.GetSolidBrush (cpcolor.Dark);
681                                                 dc.FillRectangle (brush, borderRectangle);
682                                         }
683                                 } else if (button.is_pressed || check_or_radio_checked) {
684                                         if ((button.image == null) && (button.image_list == null)) {
685                                                 Brush brush = is_ColorControl ? SystemBrushes.ControlLightLight : ResPool.GetSolidBrush (cpcolor.LightLight);
686                                                 dc.FillRectangle (brush, borderRectangle);
687                                         }
688                                         
689                                         Pen pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
690                                         dc.DrawRectangle (pen, borderRectangle.X + 4, borderRectangle.Y + 4,
691                                                           borderRectangle.Width - 9, borderRectangle.Height - 9);
692                                 }
693                                 
694                                 Internal_DrawButton (dc, borderRectangle, 3, cpcolor, is_ColorControl, button.BackColor);
695                         } else {
696                                 if ((!button.is_pressed || !button.Enabled) && !check_or_radio_checked)
697                                         Internal_DrawButton (dc, borderRectangle, 0, cpcolor, is_ColorControl, button.BackColor);
698                                 else
699                                         Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
700                         }
701                 }
702                 
703                 private void Internal_DrawButton (Graphics dc, Rectangle rect, int state, CPColor cpcolor, bool is_ColorControl, Color backcolor)
704                 {
705                         switch (state) {
706                         case 0: // normal or normal disabled button
707                                 Pen pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
708                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
709                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
710                                 
711                                 pen = is_ColorControl ? SystemPens.Control : ResPool.GetPen (backcolor);
712                                 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3);
713                                 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1);
714                                 
715                                 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
716                                 dc.DrawLine (pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
717                                 dc.DrawLine (pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 3);
718                                 
719                                 pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
720                                 dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
721                                 dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
722                                 break;
723                         case 1: // popup button normal (or pressed normal or popup button)
724                                 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
725                                 dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
726                                 break;
727                         case 2: // popup button poped up
728                                 pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
729                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
730                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
731                                 
732                                 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
733                                 dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
734                                 dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
735                                 break;
736                         case 3: // flat button not entered
737                                 pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
738                                 dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
739                                 break;
740                         default:
741                                 break;
742                         }
743                 }
744                 
745                 protected virtual void ButtonBase_DrawImage(ButtonBase button, Graphics dc)
746                 {
747                         // Need to draw a picture
748                         Image   i;
749                         int     image_x;
750                         int     image_y;
751                         int     image_width;
752                         int     image_height;
753                         
754                         int width = button.ClientSize.Width;
755                         int height = button.ClientSize.Height;
756
757                         if (button.ImageIndex != -1) {   // We use ImageIndex instead of image_index since it will return -1 if image_list is null
758                                 i = button.image_list.Images[button.ImageIndex];
759                         } else {
760                                 i = button.image;
761                         }
762
763                         image_width = i.Width;
764                         image_height = i.Height;
765                         
766                         switch (button.ImageAlign) {
767                                 case ContentAlignment.TopLeft: {
768                                         image_x = 5;
769                                         image_y = 5;
770                                         break;
771                                 }
772                                         
773                                 case ContentAlignment.TopCenter: {
774                                         image_x = (width - image_width) / 2;
775                                         image_y = 5;
776                                         break;
777                                 }
778                                         
779                                 case ContentAlignment.TopRight: {
780                                         image_x = width - image_width - 5;
781                                         image_y = 5;
782                                         break;
783                                 }
784                                         
785                                 case ContentAlignment.MiddleLeft: {
786                                         image_x = 5;
787                                         image_y = (height - image_height) / 2;
788                                         break;
789                                 }
790                                         
791                                 case ContentAlignment.MiddleCenter: {
792                                         image_x = (width - image_width) / 2;
793                                         image_y = (height - image_height) / 2;
794                                         break;
795                                 }
796                                         
797                                 case ContentAlignment.MiddleRight: {
798                                         image_x = width - image_width - 4;
799                                         image_y = (height - image_height) / 2;
800                                         break;
801                                 }
802                                         
803                                 case ContentAlignment.BottomLeft: {
804                                         image_x = 5;
805                                         image_y = height - image_height - 4;
806                                         break;
807                                 }
808                                         
809                                 case ContentAlignment.BottomCenter: {
810                                         image_x = (width - image_width) / 2;
811                                         image_y = height - image_height - 4;
812                                         break;
813                                 }
814                                         
815                                 case ContentAlignment.BottomRight: {
816                                         image_x = width - image_width - 4;
817                                         image_y = height - image_height - 4;
818                                         break;
819                                 }
820                                         
821                                 default: {
822                                         image_x = 5;
823                                         image_y = 5;
824                                         break;
825                                 }
826                         }
827                         
828                         dc.SetClip (new Rectangle(3, 3, width - 5, height - 5));
829
830                         if (button.Enabled)
831                                 dc.DrawImage (i, image_x, image_y, image_width, image_height);
832                         else
833                                 CPDrawImageDisabled (dc, i, image_x, image_y, ColorControl);
834
835                         dc.ResetClip ();
836                 }
837                 
838                 protected virtual void ButtonBase_DrawFocus(ButtonBase button, Graphics dc)
839                 {
840                         Color focus_color = button.ForeColor;
841                         
842                         int inflate_value = -3;
843                         
844                         if (!(button is CheckBox) && !(button is RadioButton)) {
845                                 inflate_value = -4;
846                                 
847                                 if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed)
848                                         focus_color = ControlPaint.Dark(button.BackColor);
849                                 
850                                 dc.DrawRectangle (ResPool.GetPen (focus_color), button.ClientRectangle.X, button.ClientRectangle.Y, 
851                                                   button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1);
852                         }
853                         
854                         if (button.Focused) {
855                                 Rectangle rect = Rectangle.Inflate (button.ClientRectangle, inflate_value, inflate_value);
856                                 ControlPaint.DrawFocusRectangle (dc, rect);
857                         }
858                 }
859                 
860                 protected virtual void ButtonBase_DrawText(ButtonBase button, Graphics dc)
861                 {
862                         Rectangle buttonRectangle = button.ClientRectangle;
863                         Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4);
864                         
865                         if (button.is_pressed) {
866                                 text_rect.X++;
867                                 text_rect.Y++;
868                         }
869                         
870                         // Ensure that at least one line is going to get displayed.
871                         // Line limit does not ensure that despite its description.
872                         text_rect.Height = Math.Max (button.Font.Height, text_rect.Height);
873                         
874                         if (button.Enabled) {                                   
875                                 dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format);
876                         } else {
877                                 if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
878                                         dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (ColorGrayText), text_rect, button.text_format);
879                                 } else {
880                                         CPDrawStringDisabled (dc, button.Text, button.Font, button.BackColor, text_rect, button.text_format);
881                                 }
882                         }
883                 }
884                 
885                 public override Size ButtonBaseDefaultSize {
886                         get {
887                                 return new Size (75, 23);
888                         }
889                 }
890                 #endregion      // ButtonBase
891
892                 #region CheckBox
893 #if NET_2_0
894                 public override void DrawCheckBox (Graphics g, CheckBox cb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
895                 {
896                         // Draw Button Background
897                         if (cb.Appearance == Appearance.Button && cb.FlatStyle != FlatStyle.Flat)
898                                 ButtonBase_DrawButton (cb, g);
899                         else if (cb.Appearance != Appearance.Button)
900                                 DrawCheckBoxGlyph (g, cb, glyphArea);
901
902                         // Draw the borders and such for a Flat CheckBox Button
903                         if (cb.Appearance == Appearance.Button && cb.FlatStyle == FlatStyle.Flat)
904                         DrawFlatButton (g, cb, textBounds, imageBounds, clipRectangle);
905                         
906                         // If we have an image, draw it
907                         if (imageBounds.Size != Size.Empty)
908                                 DrawCheckBoxImage (g, cb, imageBounds);
909
910                         if (cb.Focused && cb.Enabled && cb.ShowFocusCues && textBounds != Rectangle.Empty)
911                                 DrawCheckBoxFocus (g, cb, textBounds);
912
913                         // If we have text, draw it
914                         if (textBounds != Rectangle.Empty)
915                                 DrawCheckBoxText (g, cb, textBounds);
916                 }
917
918                 public virtual void DrawCheckBoxGlyph (Graphics g, CheckBox cb, Rectangle glyphArea)
919                 {
920                         if (cb.Pressed)
921                                 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Pressed, cb.FlatStyle, cb.CheckState);
922                         else if (cb.InternalSelected)
923                                 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
924                         else if (cb.Entered)
925                                 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Hot, cb.FlatStyle, cb.CheckState);
926                         else if (!cb.Enabled)
927                                 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Disabled, cb.FlatStyle, cb.CheckState);
928                         else
929                                 ThemeElements.CurrentTheme.CheckBoxPainter.PaintCheckBox (g, glyphArea, cb.BackColor, cb.ForeColor, ElementState.Normal, cb.FlatStyle, cb.CheckState);
930                 }
931
932                 public virtual void DrawCheckBoxFocus (Graphics g, CheckBox cb, Rectangle focusArea)
933                 {
934                         ControlPaint.DrawFocusRectangle (g, focusArea);
935                 }
936
937                 public virtual void DrawCheckBoxImage (Graphics g, CheckBox cb, Rectangle imageBounds)
938                 {
939                         if (cb.Enabled)
940                                 g.DrawImage (cb.Image, imageBounds);
941                         else
942                                 CPDrawImageDisabled (g, cb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
943                 }
944
945                 public virtual void DrawCheckBoxText (Graphics g, CheckBox cb, Rectangle textBounds)
946                 {
947                         if (cb.Enabled)
948                                 TextRenderer.DrawTextInternal (g, cb.Text, cb.Font, textBounds, cb.ForeColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
949                         else
950                                 DrawStringDisabled20 (g, cb.Text, cb.Font, textBounds, cb.BackColor, cb.TextFormatFlags, cb.UseCompatibleTextRendering);
951                 }
952
953                 public override void CalculateCheckBoxTextAndImageLayout (ButtonBase button, Point p, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
954                 {
955                         int check_size = 13;
956                         
957                         if (button is CheckBox)
958                                 check_size = (button as CheckBox).Appearance == Appearance.Normal ? 13 : 0;
959                                 
960                         glyphArea = new Rectangle (0, (button.Height - check_size) / 2, check_size, check_size);
961                         
962                         Image image = button.Image;
963                         string text = button.Text;
964                         Rectangle content_rect = button.ClientRectangle;
965                         content_rect.Width -= check_size;
966                         content_rect.Offset (check_size, 0);
967                         
968                         Size proposed = Size.Empty;
969                         
970                         // Force wrapping if we aren't AutoSize and our text is too long
971                         if (!button.AutoSize)
972                                 proposed.Width = button.Width - glyphArea.Width - 2;
973
974                         Size text_size = TextRenderer.MeasureTextInternal (text, button.Font, proposed, button.TextFormatFlags, button.UseCompatibleTextRendering);
975                         
976                         // Text can't be bigger than the content rectangle
977                         text_size.Height = Math.Min (text_size.Height, content_rect.Height);
978                         text_size.Width = Math.Min (text_size.Width, content_rect.Width);
979                         
980                         Size image_size = image == null ? Size.Empty : image.Size;
981
982                         textRectangle = Rectangle.Empty;
983                         imageRectangle = Rectangle.Empty;
984
985                         switch (button.TextImageRelation) {
986                                 case TextImageRelation.Overlay:
987                                         // Text is centered vertically, and 2 pixels to the right
988                                         textRectangle.X = content_rect.Left + 2;
989                                         textRectangle.Y = ((content_rect.Height - text_size.Height) / 2) - 1;
990                                         textRectangle.Size = text_size;
991
992                                         // Image is dependent on ImageAlign
993                                         if (image == null)
994                                                 return;
995
996                                         int image_x = 0;
997                                         int image_y = 0;
998                                         int image_height = image.Height;
999                                         int image_width = image.Width;
1000
1001                                         switch (button.ImageAlign) {
1002                                                 case System.Drawing.ContentAlignment.TopLeft:
1003                                                         image_x = 5;
1004                                                         image_y = 5;
1005                                                         break;
1006                                                 case System.Drawing.ContentAlignment.TopCenter:
1007                                                         image_x = (content_rect.Width - image_width) / 2;
1008                                                         image_y = 5;
1009                                                         break;
1010                                                 case System.Drawing.ContentAlignment.TopRight:
1011                                                         image_x = content_rect.Width - image_width - 5;
1012                                                         image_y = 5;
1013                                                         break;
1014                                                 case System.Drawing.ContentAlignment.MiddleLeft:
1015                                                         image_x = 5;
1016                                                         image_y = (content_rect.Height - image_height) / 2;
1017                                                         break;
1018                                                 case System.Drawing.ContentAlignment.MiddleCenter:
1019                                                         image_x = (content_rect.Width - image_width) / 2;
1020                                                         image_y = (content_rect.Height - image_height) / 2;
1021                                                         break;
1022                                                 case System.Drawing.ContentAlignment.MiddleRight:
1023                                                         image_x = content_rect.Width - image_width - 4;
1024                                                         image_y = (content_rect.Height - image_height) / 2;
1025                                                         break;
1026                                                 case System.Drawing.ContentAlignment.BottomLeft:
1027                                                         image_x = 5;
1028                                                         image_y = content_rect.Height - image_height - 4;
1029                                                         break;
1030                                                 case System.Drawing.ContentAlignment.BottomCenter:
1031                                                         image_x = (content_rect.Width - image_width) / 2;
1032                                                         image_y = content_rect.Height - image_height - 4;
1033                                                         break;
1034                                                 case System.Drawing.ContentAlignment.BottomRight:
1035                                                         image_x = content_rect.Width - image_width - 4;
1036                                                         image_y = content_rect.Height - image_height - 4;
1037                                                         break;
1038                                                 default:
1039                                                         image_x = 5;
1040                                                         image_y = 5;
1041                                                         break;
1042                                         }
1043
1044                                         imageRectangle = new Rectangle (image_x + check_size, image_y, image_width, image_height);
1045                                         break;
1046                                 case TextImageRelation.ImageAboveText:
1047                                         content_rect.Inflate (-4, -4);
1048                                         LayoutTextAboveOrBelowImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1049                                         break;
1050                                 case TextImageRelation.TextAboveImage:
1051                                         content_rect.Inflate (-4, -4);
1052                                         LayoutTextAboveOrBelowImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1053                                         break;
1054                                 case TextImageRelation.ImageBeforeText:
1055                                         content_rect.Inflate (-4, -4);
1056                                         LayoutTextBeforeOrAfterImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1057                                         break;
1058                                 case TextImageRelation.TextBeforeImage:
1059                                         content_rect.Inflate (-4, -4);
1060                                         LayoutTextBeforeOrAfterImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
1061                                         break;
1062                         }
1063                 }
1064
1065                 public override Size CalculateCheckBoxAutoSize (CheckBox checkBox)
1066                 {
1067                         Size ret_size = Size.Empty;
1068                         Size text_size = TextRenderer.MeasureTextInternal (checkBox.Text, checkBox.Font, checkBox.UseCompatibleTextRendering);
1069                         Size image_size = checkBox.Image == null ? Size.Empty : checkBox.Image.Size;
1070
1071                         // Pad the text size
1072                         if (checkBox.Text.Length != 0) {
1073                                 text_size.Height += 4;
1074                                 text_size.Width += 4;
1075                         }
1076
1077                         switch (checkBox.TextImageRelation) {
1078                                 case TextImageRelation.Overlay:
1079                                         ret_size.Height = Math.Max (checkBox.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
1080                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
1081                                         break;
1082                                 case TextImageRelation.ImageAboveText:
1083                                 case TextImageRelation.TextAboveImage:
1084                                         ret_size.Height = text_size.Height + image_size.Height;
1085                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
1086                                         break;
1087                                 case TextImageRelation.ImageBeforeText:
1088                                 case TextImageRelation.TextBeforeImage:
1089                                         ret_size.Height = Math.Max (text_size.Height, image_size.Height);
1090                                         ret_size.Width = text_size.Width + image_size.Width;
1091                                         break;
1092                         }
1093
1094                         // Pad the result
1095                         ret_size.Height += (checkBox.Padding.Vertical);
1096                         ret_size.Width += (checkBox.Padding.Horizontal) + 15;
1097
1098                         // There seems to be a minimum height
1099                         if (ret_size.Height == checkBox.Padding.Vertical)
1100                                 ret_size.Height += 14;
1101                                 
1102                         return ret_size;
1103                 }
1104 #endif
1105
1106                 public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) {
1107                         StringFormat            text_format;
1108                         Rectangle               client_rectangle;
1109                         Rectangle               text_rectangle;
1110                         Rectangle               checkbox_rectangle;
1111                         int                     checkmark_size=13;
1112                         int                     checkmark_space = 4;
1113
1114                         client_rectangle = checkbox.ClientRectangle;
1115                         text_rectangle = client_rectangle;
1116                         checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size);
1117
1118                         text_format = new StringFormat();
1119                         text_format.Alignment = StringAlignment.Near;
1120                         text_format.LineAlignment = StringAlignment.Center;
1121                         if (checkbox.ShowKeyboardCuesInternal)
1122                                 text_format.HotkeyPrefix = HotkeyPrefix.Show;
1123                         else
1124                                 text_format.HotkeyPrefix = HotkeyPrefix.Hide;
1125
1126                         /* Calculate the position of text and checkbox rectangle */
1127                         if (checkbox.appearance!=Appearance.Button) {
1128                                 switch(checkbox.check_alignment) {
1129                                         case ContentAlignment.BottomCenter: {
1130                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1131                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1132                                                 text_rectangle.X=client_rectangle.X;
1133                                                 text_rectangle.Width=client_rectangle.Width;
1134                                                 text_rectangle.Height=client_rectangle.Height-checkbox_rectangle.Y-checkmark_space;
1135                                                 break;
1136                                         }
1137
1138                                         case ContentAlignment.BottomLeft: {
1139                                                 checkbox_rectangle.X=client_rectangle.Left;
1140                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1141                                                 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1142                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;                                             
1143                                                 break;
1144                                         }
1145
1146                                         case ContentAlignment.BottomRight: {
1147                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1148                                                 checkbox_rectangle.Y=client_rectangle.Bottom-checkmark_size;
1149                                                 text_rectangle.X=client_rectangle.X;
1150                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;                                             
1151                                                 break;
1152                                         }
1153
1154                                         case ContentAlignment.MiddleCenter: {
1155                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1156                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1157                                                 text_rectangle.X=client_rectangle.X;
1158                                                 text_rectangle.Width=client_rectangle.Width;
1159                                                 break;
1160                                         }
1161
1162                                         default:
1163                                         case ContentAlignment.MiddleLeft: {
1164                                                 checkbox_rectangle.X=client_rectangle.Left;
1165                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1166                                                 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1167                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;                                                                                             
1168                                                 break;
1169                                         }
1170
1171                                         case ContentAlignment.MiddleRight: {
1172                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1173                                                 checkbox_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-checkmark_size/2;
1174                                                 text_rectangle.X=client_rectangle.X;
1175                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1176                                                 break;
1177                                         }
1178
1179                                         case ContentAlignment.TopCenter: {
1180                                                 checkbox_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-checkmark_size/2;
1181                                                 checkbox_rectangle.Y=client_rectangle.Top;
1182                                                 text_rectangle.X=client_rectangle.X;
1183                                                 text_rectangle.Width=client_rectangle.Width;
1184                                                 text_rectangle.Y=checkmark_size+checkmark_space;
1185                                                 text_rectangle.Height=client_rectangle.Height-checkmark_size-checkmark_space;
1186                                                 break;
1187                                         }
1188
1189                                         case ContentAlignment.TopLeft: {
1190                                                 checkbox_rectangle.X=client_rectangle.Left;
1191                                                 text_rectangle.X=client_rectangle.X+checkmark_size+checkmark_space;
1192                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1193                                                 break;
1194                                         }
1195
1196                                         case ContentAlignment.TopRight: {
1197                                                 checkbox_rectangle.X=client_rectangle.Right-checkmark_size;
1198                                                 text_rectangle.X=client_rectangle.X;
1199                                                 text_rectangle.Width=client_rectangle.Width-checkmark_size-checkmark_space;
1200                                                 break;
1201                                         }
1202                                 }
1203                         } else {
1204                                 text_rectangle.X=client_rectangle.X;
1205                                 text_rectangle.Width=client_rectangle.Width;
1206                         }
1207                         
1208                         /* Set the horizontal alignment of our text */
1209                         switch(checkbox.text_alignment) {
1210                                 case ContentAlignment.BottomLeft:
1211                                 case ContentAlignment.MiddleLeft:
1212                                 case ContentAlignment.TopLeft: {
1213                                         text_format.Alignment=StringAlignment.Near;
1214                                         break;
1215                                 }
1216
1217                                 case ContentAlignment.BottomCenter:
1218                                 case ContentAlignment.MiddleCenter:
1219                                 case ContentAlignment.TopCenter: {
1220                                         text_format.Alignment=StringAlignment.Center;
1221                                         break;
1222                                 }
1223
1224                                 case ContentAlignment.BottomRight:
1225                                 case ContentAlignment.MiddleRight:
1226                                 case ContentAlignment.TopRight: {
1227                                         text_format.Alignment=StringAlignment.Far;
1228                                         break;
1229                                 }
1230                         }
1231
1232                         /* Set the vertical alignment of our text */
1233                         switch(checkbox.text_alignment) {
1234                                 case ContentAlignment.TopLeft: 
1235                                 case ContentAlignment.TopCenter: 
1236                                 case ContentAlignment.TopRight: {
1237                                         text_format.LineAlignment=StringAlignment.Near;
1238                                         break;
1239                                 }
1240
1241                                 case ContentAlignment.BottomLeft:
1242                                 case ContentAlignment.BottomCenter:
1243                                 case ContentAlignment.BottomRight: {
1244                                         text_format.LineAlignment=StringAlignment.Far;
1245                                         break;
1246                                 }
1247
1248                                 case ContentAlignment.MiddleLeft:
1249                                 case ContentAlignment.MiddleCenter:
1250                                 case ContentAlignment.MiddleRight: {
1251                                         text_format.LineAlignment=StringAlignment.Center;
1252                                         break;
1253                                 }
1254                         }
1255
1256                         ButtonState state = ButtonState.Normal;
1257                         if (checkbox.FlatStyle == FlatStyle.Flat) {
1258                                 state |= ButtonState.Flat;
1259                         }
1260                         
1261                         if (checkbox.Checked) {
1262                                 state |= ButtonState.Checked;
1263                         }
1264                         
1265                         if (checkbox.ThreeState && (checkbox.CheckState == CheckState.Indeterminate)) {
1266                                 state |= ButtonState.Checked;
1267                                 state |= ButtonState.Pushed;                            
1268                         }
1269                         
1270                         // finally make sure the pushed and inavtive states are rendered
1271                         if (!checkbox.Enabled) {
1272                                 state |= ButtonState.Inactive;
1273                         }
1274                         else if (checkbox.is_pressed) {
1275                                 state |= ButtonState.Pushed;
1276                         }
1277                         
1278                         // Start drawing
1279                         
1280                         CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle);
1281                         
1282                         if ((checkbox.image != null) || (checkbox.image_list != null))
1283                                 ButtonBase_DrawImage(checkbox, dc);
1284                         
1285                         CheckBox_DrawText(checkbox, text_rectangle, dc, text_format);
1286
1287                         if (checkbox.Focused && checkbox.Enabled && checkbox.appearance != Appearance.Button && checkbox.Text != String.Empty && checkbox.ShowFocusCues) {
1288                                 SizeF text_size = dc.MeasureString (checkbox.Text, checkbox.Font);
1289                                 
1290                                 Rectangle focus_rect = Rectangle.Empty;
1291                                 focus_rect.X = text_rectangle.X;
1292                                 focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
1293                                 focus_rect.Size = text_size.ToSize ();
1294                                 CheckBox_DrawFocus (checkbox, dc, focus_rect);
1295                         }
1296
1297                         text_format.Dispose ();
1298                 }
1299
1300                 protected virtual void CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle )
1301                 {
1302                         Brush brush = checkbox.BackColor.ToArgb () == ColorControl.ToArgb () ? SystemBrushes.Control : ResPool.GetSolidBrush (checkbox.BackColor);
1303                         dc.FillRectangle (brush, checkbox.ClientRectangle);                     
1304                         // render as per normal button
1305                         if (checkbox.appearance==Appearance.Button) {
1306                                 ButtonBase_DrawButton (checkbox, dc);
1307                                 
1308                                 if ((checkbox.Focused) && checkbox.Enabled)
1309                                         ButtonBase_DrawFocus(checkbox, dc);
1310                         } else {
1311                                 // establish if we are rendering a flat style of some sort
1312                                 if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
1313                                         DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox);
1314                                 } else {
1315                                         CPDrawCheckBox (dc, checkbox_rectangle, state);
1316                                 }
1317                         }
1318                 }
1319                 
1320                 protected virtual void CheckBox_DrawText( CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format )
1321                 {
1322                         DrawCheckBox_and_RadioButtonText (checkbox, text_rectangle, dc, 
1323                                                           text_format, checkbox.Appearance, checkbox.Checked);
1324                 }
1325                 
1326                 protected virtual void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle )
1327                 {
1328                         DrawInnerFocusRectangle (dc, text_rectangle, checkbox.BackColor);
1329                 }
1330
1331                 // renders a checkBox with the Flat and Popup FlatStyle
1332                 protected virtual void DrawFlatStyleCheckBox (Graphics graphics, Rectangle rectangle, CheckBox checkbox)
1333                 {
1334                         Pen                     pen;                    
1335                         Rectangle       rect;
1336                         Rectangle       checkbox_rectangle;
1337                         Rectangle       fill_rectangle;
1338                         int                     lineWidth;
1339                         int                     Scale;
1340                         
1341                         // set up our rectangles first
1342                         if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered) {
1343                                 // clip one pixel from bottom right for non popup rendered checkboxes
1344                                 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-1, 0), Math.Max(rectangle.Height-1,0));
1345                                 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));
1346                         } else {
1347                                 // clip two pixels from bottom right for non popup rendered checkboxes
1348                                 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-2, 0), Math.Max(rectangle.Height-2,0));
1349                                 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));
1350                         }       
1351                         
1352                         
1353                         // if disabled render in disabled state
1354                         if (checkbox.Enabled) {
1355                                 // process the state of the checkbox
1356                                 if (checkbox.is_entered || checkbox.Capture) {
1357                                         // decide on which background color to use
1358                                         if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered && checkbox.Capture) {
1359                                                 graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
1360                                         } else if (checkbox.FlatStyle == FlatStyle.Flat) { 
1361                                                 if (!checkbox.is_pressed) {
1362                                                         graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
1363                                                 } else
1364                                                         graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1365                                         } else {
1366                                                 // use regular window background color
1367                                                 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
1368                                         }
1369                                         
1370                                         // render the outer border
1371                                         if (checkbox.FlatStyle == FlatStyle.Flat) {
1372                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
1373                                         } else {
1374                                                 // draw sunken effect
1375                                                 CPDrawBorder3D (graphics, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, checkbox.BackColor);
1376                                         }
1377                                 } else {
1378                                         graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);                           
1379                                         
1380                                         if (checkbox.FlatStyle == FlatStyle.Flat) {
1381                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
1382                                         } else {
1383                                                 // draw the outer border
1384                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ControlPaint.DarkDark (checkbox.BackColor), ButtonBorderStyle.Solid);
1385                                         }                       
1386                                 }
1387                         } else {
1388                                 if (checkbox.FlatStyle == FlatStyle.Popup) {
1389                                         graphics.FillRectangle(SystemBrushes.Control, fill_rectangle);
1390                                 }       
1391                         
1392                                 // draw disabled state,
1393                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ColorControlDark, ButtonBorderStyle.Solid);
1394                         }               
1395                         
1396                         if (checkbox.Checked) {
1397                                 /* Need to draw a check-mark */
1398                                 
1399                                 /* Make sure we've got at least a line width of 1 */
1400                                 lineWidth = Math.Max(3, fill_rectangle.Width/3);
1401                                 Scale=Math.Max(1, fill_rectangle.Width/9);
1402                                 
1403                                 // flat style check box is rendered inside a rectangle shifted down by one
1404                                 rect=new Rectangle(fill_rectangle.X, fill_rectangle.Y+1, fill_rectangle.Width, fill_rectangle.Height);
1405                                 if (checkbox.Enabled) {
1406                                         pen=ResPool.GetPen(checkbox.ForeColor);
1407                                 } else {
1408                                         pen=SystemPens.ControlDark;
1409                                 }
1410                                 
1411                                 for (int i=0; i<lineWidth; i++) {
1412                                         graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
1413                                         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);
1414                                 }
1415                         }                                       
1416                 }
1417
1418                 private void DrawCheckBox_and_RadioButtonText (ButtonBase button_base, Rectangle text_rectangle, Graphics dc, 
1419                                                                StringFormat text_format, Appearance appearance, bool ischecked)
1420                 {
1421                         // offset the text if it's pressed and a button
1422                         if (appearance == Appearance.Button) {
1423                                 if (ischecked || (button_base.Capture && button_base.FlatStyle != FlatStyle.Flat)) {
1424                                         text_rectangle.X ++;
1425                                         text_rectangle.Y ++;
1426                                 }
1427                                 
1428                                 text_rectangle.Inflate (-4, -4);
1429                         }
1430                         
1431                         /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
1432                         
1433                         // Windows seems to not wrap text in certain situations, this matches as close as I could get it
1434                         if ((float)(button_base.Font.Height * 1.5f) > text_rectangle.Height) {
1435                                 text_format.FormatFlags |= StringFormatFlags.NoWrap;
1436                         }
1437                         if (button_base.Enabled) {
1438                                 dc.DrawString (button_base.Text, button_base.Font, ResPool.GetSolidBrush (button_base.ForeColor), text_rectangle, text_format);                 
1439                         } else if (button_base.FlatStyle == FlatStyle.Flat || button_base.FlatStyle == FlatStyle.Popup) {
1440                                 dc.DrawString (button_base.Text, button_base.Font, SystemBrushes.ControlDarkDark, text_rectangle, text_format);
1441                         } else {
1442                                 CPDrawStringDisabled (dc, button_base.Text, button_base.Font, button_base.BackColor, text_rectangle, text_format);
1443                         }
1444                 }
1445                 #endregion      // CheckBox
1446                 
1447                 #region CheckedListBox
1448                 
1449                 public override void DrawCheckedListBoxItem (CheckedListBox ctrl, DrawItemEventArgs e)
1450                 {                       
1451                         Color back_color, fore_color;
1452                         Rectangle item_rect = e.Bounds;
1453                         ButtonState state;
1454
1455                         /* Draw checkbox */             
1456
1457                         if ((e.State & DrawItemState.Checked) == DrawItemState.Checked) {
1458                                 state = ButtonState.Checked;
1459                                 if ((e.State & DrawItemState.Inactive) == DrawItemState.Inactive)
1460                                         state |= ButtonState.Inactive;
1461                         } else
1462                                 state = ButtonState.Normal;
1463
1464                         if (ctrl.ThreeDCheckBoxes == false)
1465                                 state |= ButtonState.Flat;
1466
1467                         Rectangle checkbox_rect = new Rectangle (2, (item_rect.Height - 11) / 2, 13, 13);
1468                         ControlPaint.DrawCheckBox (e.Graphics,
1469                                 item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y,
1470                                 checkbox_rect.Width, checkbox_rect.Height,
1471                                 state);
1472
1473                         item_rect.X += checkbox_rect.Right;
1474                         item_rect.Width -= checkbox_rect.Right;
1475                         
1476                         /* Draw text*/
1477                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1478                                 back_color = ColorHighlight;
1479                                 fore_color = ColorHighlightText;
1480                         }
1481                         else {
1482                                 back_color = e.BackColor;
1483                                 fore_color = e.ForeColor;
1484                         }
1485                         
1486                         e.Graphics.FillRectangle (ResPool.GetSolidBrush
1487                                 (back_color), item_rect);
1488
1489                         e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1490                                 ResPool.GetSolidBrush (fore_color),
1491                                 item_rect, ctrl.StringFormat);
1492                                         
1493                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1494                                 CPDrawFocusRectangle (e.Graphics, item_rect,
1495                                         fore_color, back_color);
1496                         }
1497                 }
1498                 
1499                 #endregion // CheckedListBox
1500                 
1501                 #region ComboBox                
1502                 public override void DrawComboBoxItem (ComboBox ctrl, DrawItemEventArgs e)
1503                 {
1504                         Color back_color, fore_color;
1505                         Rectangle text_draw = e.Bounds;
1506                         StringFormat string_format = new StringFormat ();
1507                         string_format.FormatFlags = StringFormatFlags.LineLimit;
1508                         
1509                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1510                                 back_color = ColorHighlight;
1511                                 fore_color = ColorHighlightText;
1512                         }
1513                         else {
1514                                 back_color = e.BackColor;
1515                                 fore_color = e.ForeColor;
1516                         }
1517                         
1518                         if (!ctrl.Enabled)
1519                                 fore_color = ColorInactiveCaptionText;
1520                                                         
1521                         e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
1522
1523                         if (e.Index != -1) {
1524                                 e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1525                                         ResPool.GetSolidBrush (fore_color),
1526                                         text_draw, string_format);
1527                         }
1528                         
1529                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1530                                 CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
1531                         }
1532
1533                         string_format.Dispose ();
1534                 }
1535                 
1536                 public override void DrawFlatStyleComboButton (Graphics graphics, Rectangle rectangle, ButtonState state)
1537                 {
1538                         Point[]                 arrow = new Point[3];
1539                         Point                           P1;
1540                         Point                           P2;
1541                         Point                           P3;
1542                         int                             centerX;
1543                         int                             centerY;
1544                         int                             shiftX;
1545                         int                             shiftY;
1546                         Rectangle               rect;
1547
1548                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
1549                         centerX=rect.Left+rect.Width/2;
1550                         centerY=rect.Top+rect.Height/2;
1551                         shiftX=Math.Max(1, rect.Width/8);
1552                         shiftY=Math.Max(1, rect.Height/8);
1553
1554                         if ((state & ButtonState.Pushed)!=0) {
1555                                 shiftX++;
1556                                 shiftY++;
1557                         }
1558
1559                         rect.Y-=shiftY;
1560                         centerY-=shiftY;
1561                         P1=new Point(rect.Left + 1, centerY);
1562                         P2=new Point(rect.Right - 1, centerY);
1563                         P3=new Point(centerX, rect.Bottom - 1);
1564
1565                         arrow[0]=P1;
1566                         arrow[1]=P2;
1567                         arrow[2]=P3;
1568                         
1569                         /* Draw the arrow */
1570                         if ((state & ButtonState.Inactive)!=0) {
1571                                 /* Move away from the shadow */
1572                                 arrow[0].X += 1;        arrow[0].Y += 1;
1573                                 arrow[1].X += 1;        arrow[1].Y += 1;
1574                                 arrow[2].X += 1;        arrow[2].Y += 1;
1575                                 
1576                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
1577
1578                                 arrow[0]=P1;
1579                                 arrow[1]=P2;
1580                                 arrow[2]=P3;
1581
1582                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
1583                         } else {
1584                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
1585                         }               
1586                 }
1587                 public override void ComboBoxDrawNormalDropDownButton (ComboBox comboBox, Graphics g, Rectangle clippingArea, Rectangle area, ButtonState state)
1588                 {
1589                         CPDrawComboButton (g, area, state);
1590                 }
1591                 public override bool ComboBoxNormalDropDownButtonHasTransparentBackground (ComboBox comboBox, ButtonState state)
1592                 {
1593                         return true;
1594                 }
1595                 public override bool ComboBoxDropDownButtonHasHotElementStyle (ComboBox comboBox)
1596                 {
1597                         return false;
1598                 }
1599                 public override void ComboBoxDrawBackground (ComboBox comboBox, Graphics g, Rectangle clippingArea, FlatStyle style)
1600                 {
1601                         if (!comboBox.Enabled)
1602                                 g.FillRectangle (ResPool.GetSolidBrush (ColorControl), comboBox.Bounds);
1603
1604                         if (comboBox.DropDownStyle == ComboBoxStyle.Simple)
1605                                 g.FillRectangle (ResPool.GetSolidBrush (comboBox.Parent.BackColor), comboBox.ClientRectangle);
1606
1607                         if (style == FlatStyle.Popup && (comboBox.Entered || comboBox.Focused)) {
1608                                 Rectangle area = comboBox.TextArea;
1609                                 area.Height -= 1;
1610                                 area.Width -= 1;
1611                                 g.DrawRectangle (ResPool.GetPen (SystemColors.ControlDark), area);
1612                                 g.DrawLine (ResPool.GetPen (SystemColors.ControlDark), comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Top, comboBox.ButtonArea.X - 1, comboBox.ButtonArea.Bottom);
1613                         }
1614                         bool is_flat = style == FlatStyle.Flat || style == FlatStyle.Popup;
1615                         if (!is_flat && clippingArea.IntersectsWith (comboBox.TextArea))
1616                                 ControlPaint.DrawBorder3D (g, comboBox.TextArea, Border3DStyle.Sunken);
1617                 }
1618                 public override bool CombBoxBackgroundHasHotElementStyle (ComboBox comboBox)
1619                 {
1620                         return false;
1621                 }
1622                 #endregion ComboBox
1623                 
1624                 #region Datagrid
1625                 public override int DataGridPreferredColumnWidth { get { return 75;} }
1626                 public override int DataGridMinimumColumnCheckBoxHeight { get { return 16;} }
1627                 public override int DataGridMinimumColumnCheckBoxWidth { get { return 16;} }
1628                 public override Color DataGridAlternatingBackColor { get { return ColorWindow;} }
1629                 public override Color DataGridBackColor { get  { return  ColorWindow;} }                
1630                 public override Color DataGridBackgroundColor { get  { return  ColorAppWorkspace;} }
1631                 public override Color DataGridCaptionBackColor { get  { return ColorActiveCaption;} }
1632                 public override Color DataGridCaptionForeColor { get  { return ColorActiveCaptionText;} }
1633                 public override Color DataGridGridLineColor { get { return ColorControl;} }
1634                 public override Color DataGridHeaderBackColor { get  { return ColorControl;} }
1635                 public override Color DataGridHeaderForeColor { get  { return ColorControlText;} }
1636                 public override Color DataGridLinkColor { get  { return ColorHotTrack;} }
1637                 public override Color DataGridLinkHoverColor { get  { return ColorHotTrack;} }
1638                 public override Color DataGridParentRowsBackColor { get  { return ColorControl;} }
1639                 public override Color DataGridParentRowsForeColor { get  { return ColorWindowText;} }
1640                 public override Color DataGridSelectionBackColor { get  { return ColorActiveCaption;} }
1641                 public override Color DataGridSelectionForeColor { get  { return ColorActiveCaptionText;} }
1642                 
1643                 public override void DataGridPaint (PaintEventArgs pe, DataGrid grid)
1644                 {
1645                         DataGridPaintCaption (pe.Graphics, pe.ClipRectangle, grid);
1646                         DataGridPaintParentRows (pe.Graphics, pe.ClipRectangle, grid);
1647                         DataGridPaintColumnHeaders (pe.Graphics, pe.ClipRectangle, grid);
1648                         DataGridPaintRows (pe.Graphics, grid.cells_area, pe.ClipRectangle, grid);
1649
1650                         // Paint scrollBar corner
1651                         if (grid.VScrollBar.Visible && grid.HScrollBar.Visible) {
1652
1653                                 Rectangle corner = new Rectangle (grid.ClientRectangle.X + grid.ClientRectangle.Width - grid.VScrollBar.Width,
1654                                                                   grid.ClientRectangle.Y + grid.ClientRectangle.Height - grid.HScrollBar.Height,
1655                                                                   grid.VScrollBar.Width, grid.HScrollBar.Height);
1656
1657                                 if (pe.ClipRectangle.IntersectsWith (corner)) {
1658                                         pe.Graphics.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
1659                                                                    corner);
1660                                 }
1661                         }
1662                 }
1663
1664                 public override void DataGridPaintCaption (Graphics g, Rectangle clip, DataGrid grid)
1665                 {
1666                         Rectangle bounds = clip;
1667                         bounds.Intersect (grid.caption_area);
1668
1669                         // Background
1670                         g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor), bounds);
1671
1672                         // Bottom line
1673                 g.DrawLine (ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor),
1674                                         bounds.X, bounds.Y + bounds.Height -1, 
1675                     bounds.X + bounds.Width, bounds.Y + bounds.Height -1);
1676
1677                         // Caption text
1678                         if (grid.CaptionText != String.Empty) {
1679                                 Rectangle text_rect = grid.caption_area;
1680                                 text_rect.Y += text_rect.Height / 2 - grid.CaptionFont.Height / 2;
1681                                 text_rect.Height = grid.CaptionFont.Height;
1682
1683                                 g.DrawString (grid.CaptionText, grid.CaptionFont,
1684                                               ResPool.GetSolidBrush (grid.CaptionForeColor),
1685                                               text_rect);
1686                         }
1687
1688                         // Back button
1689                         if (bounds.IntersectsWith (grid.back_button_rect)) {
1690                                 g.DrawImage (grid.back_button_image, grid.back_button_rect);
1691                                 if (grid.back_button_mouseover) {
1692                                         CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1693                                 }
1694                         }
1695
1696                         // Rows button
1697                         if (bounds.IntersectsWith (grid.parent_rows_button_rect)) {
1698                                 g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect);
1699                                 if (grid.parent_rows_button_mouseover) {
1700                                         CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1701                                 }
1702                         }
1703                 }
1704
1705                 public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid)
1706                 {
1707                         Rectangle columns_area = grid.column_headers_area;
1708
1709             // Paint corner shared between row and column header
1710                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
1711                                 Rectangle rect_bloc = grid.column_headers_area;
1712                                 rect_bloc.Width = grid.RowHeaderWidth;
1713                                 if (clip.IntersectsWith (rect_bloc)) {
1714                                         if (grid.VisibleColumnCount > 0) {
1715                                                 if (grid.FlatMode)
1716                                                         g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc);
1717                                                 else
1718                                                         CPDrawBorder3D (g, rect_bloc, Border3DStyle.RaisedInner, 
1719                                                                 Border3DSide.Left | Border3DSide.Right | 
1720                                                                 Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Middle, 
1721                                                                 grid.CurrentTableStyle.CurrentHeaderBackColor);
1722                                         } else {
1723                                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), rect_bloc);
1724                                         }
1725                                 }
1726
1727                                 columns_area.X += grid.RowHeaderWidth;
1728                                 columns_area.Width -= grid.RowHeaderWidth;
1729                         }
1730
1731                         // Set unused area
1732                         Rectangle column_headers_area_complete = columns_area;
1733                         column_headers_area_complete.Width = grid.column_headers_max_width;
1734                         
1735                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
1736                                 column_headers_area_complete.Width -= grid.RowHeaderWidth;
1737                         }               
1738
1739                         // Set column painting
1740                         Rectangle rect_columnhdr = new Rectangle ();
1741                         int col_pixel;
1742                         Region current_clip;
1743                         Region prev_clip = g.Clip;
1744                         rect_columnhdr.Y = columns_area.Y;
1745                         rect_columnhdr.Height = columns_area.Height;
1746
1747                         int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
1748                         for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
1749                                 if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
1750                                         continue;
1751                                 
1752                                 col_pixel = grid.GetColumnStartingPixel (column);
1753                                 rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset;
1754                                 rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
1755
1756                                 if (clip.IntersectsWith (rect_columnhdr) == false)
1757                                         continue;
1758
1759                                 current_clip = new Region (rect_columnhdr);
1760                                 current_clip.Intersect (columns_area);
1761                                 current_clip.Intersect (prev_clip);
1762                                 g.Clip = current_clip;
1763
1764                                 DataGridPaintColumnHeader (g, rect_columnhdr, grid, column);
1765
1766                                 current_clip.Dispose ();
1767                         }
1768
1769                         g.Clip = prev_clip;
1770                                 
1771                         Rectangle not_usedarea = column_headers_area_complete;                          
1772                         not_usedarea.X = rect_columnhdr.X + rect_columnhdr.Width;
1773                         not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - rect_columnhdr.X - rect_columnhdr.Height;            
1774                         g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
1775                         
1776                 }
1777
1778                 public override void DataGridPaintColumnHeader (Graphics g, Rectangle bounds, DataGrid grid, int col)
1779                 {
1780                         // Background
1781                         g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.HeaderBackColor), bounds);
1782
1783                         // Paint Borders
1784                         if (!grid.FlatMode) {
1785                                 g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1786                                         bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
1787                                 
1788                                 if (col == 0) {
1789                                         g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1790                                                 bounds.X, bounds.Y, bounds.X, bounds.Y + bounds.Height);
1791                                 } else {
1792                                         g.DrawLine (ResPool.GetPen (ColorControlLightLight),
1793                                                 bounds.X, bounds.Y + 2, bounds.X, bounds.Y + bounds.Height - 3);
1794                                 }
1795                                 
1796                                 if (col == (grid.VisibleColumnCount -1)) {
1797                                         g.DrawLine (ResPool.GetPen (ColorControlDark),
1798                                                 bounds.X + bounds.Width - 1, bounds.Y, 
1799                                                 bounds.X + bounds.Width - 1, bounds.Y + bounds.Height);
1800                                 } else {
1801                                         g.DrawLine (ResPool.GetPen (ColorControlDark),
1802                                                 bounds.X + bounds.Width - 1, bounds.Y + 2, 
1803                                                 bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 3);
1804                                 }
1805
1806                                 g.DrawLine (ResPool.GetPen (ColorControlDark),
1807                                         bounds.X, bounds.Y + bounds.Height - 1, 
1808                                         bounds.X + bounds.Width, bounds.Y + bounds.Height - 1);
1809                         }
1810
1811                         bounds.X += 2;
1812                         bounds.Width -= 2;
1813
1814                         DataGridColumnStyle style = grid.CurrentTableStyle.GridColumnStyles[col];
1815
1816                         if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No)
1817                                 bounds.Width -= 16;
1818
1819                         // Caption
1820                         StringFormat format = new StringFormat ();
1821                         format.FormatFlags |= StringFormatFlags.NoWrap;
1822                         format.LineAlignment = StringAlignment.Center;
1823                         format.Trimming = StringTrimming.Character;
1824
1825                         g.DrawString (style.HeaderText, grid.CurrentTableStyle.HeaderFont, 
1826                                 ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor), 
1827                                 bounds, format);
1828
1829                         // Arrow (6 x 6)
1830                         if (style.ArrowDrawingMode != DataGridColumnStyle.ArrowDrawing.No) {
1831                                 Point pnt = new Point (bounds.X + bounds.Width + 4, bounds.Y + ((bounds.Height - 6)/2));
1832                                 
1833                                 if (style.ArrowDrawingMode == DataGridColumnStyle.ArrowDrawing.Ascending) {
1834                                         g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y + 6, pnt.X + 3, pnt.Y);
1835                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 6, pnt.Y + 6);
1836                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y + 6, pnt.X + 3, pnt.Y);
1837                                 } else {
1838                                         g.DrawLine (SystemPens.ControlLightLight, pnt.X + 6, pnt.Y, pnt.X + 3, pnt.Y + 6);
1839                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 6, pnt.Y);
1840                                         g.DrawLine (SystemPens.ControlDark, pnt.X, pnt.Y, pnt.X + 3, pnt.Y + 6);
1841                                 }
1842                         }
1843                 }
1844
1845                 public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid)
1846                 {
1847                         Rectangle rect_row = new Rectangle ();
1848
1849                         rect_row.X = grid.ParentRowsArea.X;
1850                         rect_row.Width = grid.ParentRowsArea.Width;
1851                         rect_row.Height = (grid.CaptionFont.Height + 3);
1852
1853                         object[] parentRows = grid.data_source_stack.ToArray();
1854                         
1855                         Region current_clip;
1856                         Region prev_clip = g.Clip;
1857                         for (int row = 0; row < parentRows.Length; row++) {
1858                                 rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height;
1859
1860                                 if (clip.IntersectsWith (rect_row) == false)
1861                                         continue;
1862
1863                                 current_clip = new Region (rect_row);
1864                                 current_clip.Intersect (prev_clip);
1865                                 g.Clip = current_clip;
1866
1867                                 DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid);
1868
1869                                 current_clip.Dispose ();
1870                         }
1871                         
1872                         g.Clip = prev_clip;
1873                 }
1874
1875                 public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid)
1876                 {
1877                         // Background
1878                         g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
1879                                          bounds);
1880
1881                         Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold);
1882                         // set up some standard string formating variables
1883                         StringFormat text_format = new StringFormat();
1884                         text_format.LineAlignment = StringAlignment.Center;
1885                         text_format.Alignment = StringAlignment.Near;
1886
1887                         string table_name = "";
1888                         if (row.view is DataRowView)
1889                                 table_name = ((ITypedList)((DataRowView)row.view).DataView).GetListName (null) + ": ";
1890                         // XXX else?
1891
1892                         Rectangle       text_rect;
1893                         Size            text_size;
1894
1895                         text_size = g.MeasureString (table_name, bold_font).ToSize();
1896                         text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size);
1897
1898                         g.DrawString (table_name,
1899                                       bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1900
1901                         foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) {
1902                                 if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType))
1903                                         continue;
1904
1905                                 text_rect.X += text_rect.Size.Width + 5;
1906
1907                                 string text = String.Format ("{0}: {1}",
1908                                                              pd.Name,
1909                                                              pd.GetValue (row.view));
1910
1911                                 text_rect.Size = g.MeasureString (text, grid.Font).ToSize();
1912                                 text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX
1913
1914                                 g.DrawString (text,
1915                                               grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1916                         }
1917
1918             // Paint Borders
1919                         if (!grid.FlatMode) {
1920                 CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner, 
1921                     Border3DSide.Left | Border3DSide.Right | 
1922                     Border3DSide.Top | Border3DSide.Bottom);
1923                         }
1924                 }
1925
1926                 public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid) 
1927                 {               
1928                         Point[] arrow = new Point[3];
1929                         Point P1, P2, P3;
1930                         int centerX, centerY, shiftX;                   
1931                         Rectangle rect;
1932                         
1933                         rect = new Rectangle (bounds.X + bounds.Width /4, 
1934                                 bounds.Y + bounds.Height/4, bounds.Width / 2, bounds.Height / 2);
1935                         
1936                         centerX = rect.Left + rect.Width / 2;
1937                         centerY = rect.Top + rect.Height / 2;
1938                         shiftX = Math.Max (1, rect.Width / 8);                  
1939                         rect.X -= shiftX;
1940                         centerX -= shiftX;                      
1941                         P1 = new Point (centerX, rect.Top - 1);
1942                         P2 = new Point (centerX, rect.Bottom);
1943                         P3 = new Point (rect.Right, centerY);                   
1944                         arrow[0] = P1;
1945                         arrow[1] = P2;
1946                         arrow[2] = P3;
1947                         
1948                         g.FillPolygon (ResPool.GetSolidBrush 
1949                                 (grid.CurrentTableStyle.CurrentHeaderForeColor), arrow, FillMode.Winding);
1950                 }
1951
1952                 public override void DataGridPaintRowHeaderStar (Graphics g, Rectangle bounds, DataGrid grid) 
1953                 {
1954                         int x = bounds.X + 4;
1955                         int y = bounds.Y + 3;
1956                         Pen pen = ResPool.GetPen (grid.CurrentTableStyle.CurrentHeaderForeColor);
1957
1958                         g.DrawLine (pen, x + 4, y, x + 4, y + 8);
1959                         g.DrawLine (pen, x, y + 4, x + 8, y + 4);
1960                         g.DrawLine (pen, x + 1, y + 1, x + 7, y + 7);
1961                         g.DrawLine (pen, x + 7, y + 1, x + 1, y + 7);
1962                 }               
1963
1964                 public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid)
1965                 {
1966                         bool is_add_row = grid.ShowEditRow && row == grid.DataGridRows.Length - 1;
1967                         bool is_current_row = row == grid.CurrentCell.RowNumber;
1968
1969                         // Background
1970                         g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), bounds);
1971
1972                         // Draw arrow
1973                         if (is_current_row) {
1974                                 if (grid.IsChanging) {
1975                                         g.DrawString ("...", grid.Font,
1976                                                       ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
1977                                                       bounds);
1978                                 } else {
1979                                         Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);
1980                                         DataGridPaintRowHeaderArrow (g, rect, grid);
1981                                 }
1982                         }
1983                         else if (is_add_row) {
1984                                 DataGridPaintRowHeaderStar (g, bounds, grid);
1985                         }
1986
1987                         if (!grid.FlatMode && !is_add_row) {
1988                                 CPDrawBorder3D (g, bounds, Border3DStyle.RaisedInner, 
1989                                         Border3DSide.Left | Border3DSide.Right | 
1990                                         Border3DSide.Top | Border3DSide.Bottom);
1991                         }
1992                 }
1993                 
1994                 public override void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid)
1995                 {
1996                         Rectangle rect_row = new Rectangle ();
1997                         Rectangle not_usedarea = new Rectangle ();
1998
1999                         int rowcnt = grid.VisibleRowCount;
2000                         
2001                         bool showing_add_row = false;
2002
2003                         if (grid.RowsCount < grid.DataGridRows.Length) {
2004                                 /* the table has an add row */
2005
2006                                 if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.DataGridRows.Length) {
2007                                         showing_add_row = true;
2008                                 }
2009                         }
2010
2011                         rect_row.Width = cells.Width + grid.RowHeadersArea.Width;
2012                         for (int r = 0; r < rowcnt; r++) {
2013                                 int row = grid.FirstVisibleRow + r;
2014                                 if (row == grid.DataGridRows.Length - 1)
2015                                         rect_row.Height = grid.DataGridRows[row].Height;
2016                                 else
2017                                         rect_row.Height = grid.DataGridRows[row + 1].VerticalOffset - grid.DataGridRows[row].VerticalOffset;
2018                                 rect_row.Y = cells.Y + grid.DataGridRows[row].VerticalOffset - grid.DataGridRows[grid.FirstVisibleRow].VerticalOffset;
2019                                 if (clip.IntersectsWith (rect_row)) {
2020                                         if (grid.CurrentTableStyle.HasRelations
2021                                             && !(showing_add_row && row == grid.DataGridRows.Length - 1))
2022                                                 DataGridPaintRelationRow (g, row, rect_row, false, clip, grid);
2023                                         else
2024                                                 DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.DataGridRows.Length - 1, clip, grid);
2025                                 }
2026                         }
2027
2028                         not_usedarea.X = 0;
2029                         // the rowcnt == 0 check is needed because
2030                         // otherwise we'd draw over the caption on
2031                         // empty datasources (since rect_row would be
2032                         // Empty)
2033                         if (rowcnt == 0)
2034                                 not_usedarea.Y = cells.Y;
2035                         else
2036                                 not_usedarea.Y = rect_row.Y + rect_row.Height;
2037                         not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height;
2038                         not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width;
2039
2040                         g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
2041                 }
2042
2043                 public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2044                                                                Rectangle clip, DataGrid grid)
2045                 {
2046                         Rectangle rect_header;
2047                         Rectangle icon_bounds = new Rectangle ();
2048                         Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor);
2049
2050                         /* paint the header if it's visible and intersects the clip */
2051                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
2052                                 rect_header = row_rect;
2053                                 rect_header.Width = grid.RowHeaderWidth;
2054                                 row_rect.X += grid.RowHeaderWidth;
2055                                 if (clip.IntersectsWith (rect_header)) {
2056                                         DataGridPaintRowHeader (g, rect_header, row, grid);
2057                                 }
2058
2059                                 icon_bounds = rect_header;
2060                                 icon_bounds.X += icon_bounds.Width / 2;
2061                                 icon_bounds.Y += 3;
2062                                 icon_bounds.Width = 8;
2063                                 icon_bounds.Height = 8;
2064
2065                                 g.DrawRectangle (pen, icon_bounds);
2066
2067                                 /* the - part of the icon */
2068                                 g.DrawLine (pen,
2069                                             icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2,
2070                                             icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2);
2071                                             
2072                                 if (!grid.IsExpanded (row)) {
2073                                         /* the | part of the icon */
2074                                         g.DrawLine (pen,
2075                                                     icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2,
2076                                                     icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2);
2077                                 }
2078                         }
2079
2080                         Rectangle nested_rect = row_rect;
2081
2082                         if (grid.DataGridRows[row].IsExpanded)
2083                                 nested_rect.Height -= grid.DataGridRows[row].RelationHeight;
2084
2085                         DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid);
2086
2087                         if (grid.DataGridRows[row].IsExpanded) {
2088                                 // XXX we should create this in the
2089                                 // datagrid and cache it for use by
2090                                 // the theme instead of doing it each
2091                                 // time through here
2092                                 string[] relations = grid.CurrentTableStyle.Relations;
2093                                 StringBuilder relation_builder = new StringBuilder ("");
2094
2095                                 for (int i = 0; i < relations.Length; i ++) {
2096                                         if (i > 0)
2097                                                 relation_builder.Append ("\n");
2098
2099                                         relation_builder.Append (relations[i]);
2100                                 }
2101                                 string relation_text = relation_builder.ToString ();
2102
2103                                 StringFormat string_format = new StringFormat ();
2104                                 string_format.FormatFlags |= StringFormatFlags.NoWrap;
2105
2106
2107                                 //Region prev_clip = g.Clip;
2108                                 //Region current_clip;
2109                                 Rectangle rect_cell = row_rect;
2110
2111                                 rect_cell.X = nested_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset;
2112                                 rect_cell.Y += nested_rect.Height;
2113                                 rect_cell.Height = grid.DataGridRows[row].RelationHeight;
2114
2115                                 rect_cell.Width = 0;
2116                                 int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2117                                 for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2118                                         if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2119                                                 continue;
2120                                         rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width;
2121                                 }
2122                                 rect_cell.Width = Math.Max (rect_cell.Width, grid.DataGridRows[row].relation_area.Width);
2123
2124                                 g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor),
2125                                                  rect_cell);
2126
2127
2128                                 /* draw the line leading from the +/- to the relation area */
2129                                 Rectangle outline = grid.DataGridRows[row].relation_area;
2130                                 outline.Y = rect_cell.Y;
2131                                 outline.Height --;
2132
2133                                 g.DrawLine (pen,
2134                                             icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height,
2135                                             icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2);
2136
2137                                 g.DrawLine (pen,
2138                                             icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2,
2139                                             outline.X, outline.Y + outline.Height / 2);
2140
2141                                 g.DrawRectangle (pen, outline);
2142
2143                                 g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor),
2144                                               outline, string_format);
2145
2146                                 if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2147                                         Rectangle not_usedarea = new Rectangle ();
2148                                         not_usedarea.X = rect_cell.X + rect_cell.Width;
2149                                         not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2150                                         not_usedarea.Y = row_rect.Y;
2151                                         not_usedarea.Height = row_rect.Height;
2152                                         if (clip.IntersectsWith (not_usedarea))
2153                                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2154                                                                  not_usedarea);
2155                                 }
2156                         }
2157                 }
2158
2159                 public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2160                                                                Rectangle clip, DataGrid grid)
2161                 {
2162                         Rectangle rect_cell = new Rectangle ();
2163                         int col_pixel;
2164                         Color backcolor, forecolor;
2165                         Brush backBrush, foreBrush;
2166                         Rectangle not_usedarea = Rectangle.Empty;
2167
2168                         rect_cell.Y = row_rect.Y;
2169                         rect_cell.Height = row_rect.Height;
2170
2171                         if (grid.IsSelected (row)) {
2172                                 backcolor =  grid.SelectionBackColor;
2173                                 forecolor =  grid.SelectionForeColor;
2174                         } else {
2175                                 if (row % 2 == 0) {
2176                                         backcolor =  grid.BackColor;
2177                                 } else {
2178                                         backcolor =  grid.AlternatingBackColor;
2179                                 }
2180
2181                                 forecolor =  grid.ForeColor;
2182                         }                       
2183
2184
2185                         backBrush = ResPool.GetSolidBrush (backcolor);
2186                         foreBrush = ResPool.GetSolidBrush (forecolor);
2187
2188                         // PaintCells at row, column
2189                         int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2190
2191                         if (column_cnt > 0) {
2192                                 Region prev_clip = g.Clip;
2193                                 Region current_clip;
2194
2195                                 for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2196                                         if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2197                                                 continue;
2198
2199                                         col_pixel = grid.GetColumnStartingPixel (column);
2200
2201                                         rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset;
2202                                         rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
2203
2204                                         if (clip.IntersectsWith (rect_cell)) {
2205                                                 current_clip = new Region (rect_cell);
2206                                                 current_clip.Intersect (row_rect);
2207                                                 current_clip.Intersect (prev_clip);
2208                                                 g.Clip = current_clip;
2209
2210                                                 if (is_newrow) {
2211                                                         grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, 
2212                                                                                                                      backBrush,
2213                                                                                                                      foreBrush);
2214                                                 } else {
2215                                                         grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
2216                                                                                                                backBrush,
2217                                                                                                                foreBrush,
2218                                                                                                                grid.RightToLeft == RightToLeft.Yes);
2219                                                 }
2220
2221                                                 current_clip.Dispose ();
2222                                         }
2223                                 }
2224
2225                                 g.Clip = prev_clip;
2226                         
2227                                 if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2228                                         not_usedarea.X = rect_cell.X + rect_cell.Width;
2229                                         not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2230                                         not_usedarea.Y = row_rect.Y;
2231                                         not_usedarea.Height = row_rect.Height;
2232                                 }
2233                         }
2234                         else {
2235                                 not_usedarea = row_rect;
2236                         }
2237
2238                         if (!not_usedarea.IsEmpty && clip.IntersectsWith (not_usedarea))
2239                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2240                                                  not_usedarea);
2241                 }
2242
2243                 public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2244                                                        Rectangle clip, DataGrid grid)
2245                 {                       
2246                         /* paint the header if it's visible and intersects the clip */
2247                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
2248                                 Rectangle rect_header = row_rect;
2249                                 rect_header.Width = grid.RowHeaderWidth;
2250                                 row_rect.X += grid.RowHeaderWidth;
2251                                 if (clip.IntersectsWith (rect_header)) {
2252                                         DataGridPaintRowHeader (g, rect_header, row, grid);
2253                                 }
2254                         }
2255
2256                         DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid);
2257                 }
2258                 
2259                 #endregion // Datagrid
2260
2261 #if NET_2_0
2262                 #region DataGridView
2263                 #region DataGridViewHeaderCell
2264                 #region DataGridViewRowHeaderCell
2265                 public override bool DataGridViewRowHeaderCellDrawBackground (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2266                 {
2267                         return false;
2268                 }
2269
2270                 public override bool DataGridViewRowHeaderCellDrawSelectionBackground (DataGridViewRowHeaderCell cell)
2271                 {
2272                         return false;
2273                 }
2274
2275                 public override bool DataGridViewRowHeaderCellDrawBorder (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2276                 {
2277                         return false;
2278                 }
2279                 #endregion
2280
2281                 #region DataGridViewColumnHeaderCell
2282                 public override bool DataGridViewColumnHeaderCellDrawBackground (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2283                 {
2284                         return false;
2285                 }
2286
2287                 public override bool DataGridViewColumnHeaderCellDrawBorder (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2288                 {
2289                         return false;
2290                 }
2291                 #endregion
2292
2293                 public override bool DataGridViewHeaderCellHasPressedStyle  (DataGridView dataGridView)
2294                 {
2295                         return false;
2296                 }
2297
2298                 public override bool DataGridViewHeaderCellHasHotStyle (DataGridView dataGridView)
2299                 {
2300                         return false;
2301                 }
2302                 #endregion
2303                 #endregion
2304 #endif
2305
2306                 #region DateTimePicker
2307                 protected virtual void DateTimePickerDrawBorder (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)
2308                 {
2309                         this.CPDrawBorder3D (g, dateTimePicker.ClientRectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, dateTimePicker.BackColor);
2310                 }
2311
2312                 protected virtual void DateTimePickerDrawDropDownButton (DateTimePicker dateTimePicker, Graphics g, Rectangle clippingArea)
2313                 {
2314                         ButtonState state = dateTimePicker.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal;
2315                         g.FillRectangle (ResPool.GetSolidBrush (ColorControl), dateTimePicker.drop_down_arrow_rect);
2316                         this.CPDrawComboButton ( 
2317                           g, 
2318                           dateTimePicker.drop_down_arrow_rect, 
2319                           state);
2320                 }
2321
2322                 public override void DrawDateTimePicker(Graphics dc, Rectangle clip_rectangle, DateTimePicker dtp)
2323                 {
2324
2325                         if (!clip_rectangle.IntersectsWith (dtp.ClientRectangle))
2326                                 return;
2327
2328                         // draw the outer border
2329                         Rectangle button_bounds = dtp.ClientRectangle;
2330                         DateTimePickerDrawBorder (dtp, dc, clip_rectangle);
2331
2332                         // deflate by the border width
2333                         if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) {
2334                                 button_bounds.Inflate (-2,-2);
2335                                 if (!dtp.ShowUpDown) {
2336                                         DateTimePickerDrawDropDownButton (dtp, dc, clip_rectangle);
2337                                 } else {
2338                                         ButtonState up_state = dtp.is_up_pressed ? ButtonState.Pushed : ButtonState.Normal;
2339                                         ButtonState down_state = dtp.is_down_pressed ? ButtonState.Pushed : ButtonState.Normal;
2340                                         Rectangle up_bounds = dtp.drop_down_arrow_rect;
2341                                         Rectangle down_bounds = dtp.drop_down_arrow_rect;
2342
2343                                         up_bounds.Height = up_bounds.Height / 2;
2344                                         down_bounds.Y = up_bounds.Height;
2345                                         down_bounds.Height = dtp.Height - up_bounds.Height;
2346                                         if (down_bounds.Height > up_bounds.Height)
2347                                         {
2348                                                 down_bounds.Y += 1;
2349                                                 down_bounds.Height -= 1;
2350                                         }
2351
2352                                         up_bounds.Inflate (-1, -1);
2353                                         down_bounds.Inflate (-1, -1);
2354
2355                                         ControlPaint.DrawScrollButton (dc, up_bounds, ScrollButton.Up, up_state);
2356                                         ControlPaint.DrawScrollButton (dc, down_bounds, ScrollButton.Down, down_state);
2357                                 }
2358                         }
2359
2360                         // render the date part
2361                         if (!clip_rectangle.IntersectsWith (dtp.date_area_rect))
2362                                 return;
2363
2364                         // fill the background
2365                         dc.FillRectangle (SystemBrushes.Window, dtp.date_area_rect);
2366
2367                         // Update date_area_rect if we are drawing the checkbox
2368                         Rectangle date_area_rect = dtp.date_area_rect;
2369                         if (dtp.ShowCheckBox) {
2370                                 Rectangle check_box_rect = dtp.CheckBoxRect;
2371                                 date_area_rect.X = date_area_rect.X + check_box_rect.Width + DateTimePicker.check_box_space * 2;
2372                                 date_area_rect.Width = date_area_rect.Width - check_box_rect.Width - DateTimePicker.check_box_space * 2;
2373
2374                                 ButtonState bs = dtp.Checked ? ButtonState.Checked : ButtonState.Normal;
2375                                 CPDrawCheckBox(dc, check_box_rect, bs);
2376
2377                                 if (dtp.is_checkbox_selected)
2378                                         CPDrawFocusRectangle (dc, check_box_rect, dtp.foreground_color, dtp.background_color);
2379                         }
2380
2381                         // render each text part
2382                         using (StringFormat text_format = StringFormat.GenericTypographic)
2383                         {
2384                                 text_format.LineAlignment = StringAlignment.Near;
2385                                 text_format.Alignment = StringAlignment.Near;
2386                                 text_format.FormatFlags = text_format.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox;
2387                                 text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2388
2389                                 // Calculate the rectangles for each part 
2390                                 if (dtp.part_data.Length > 0 && dtp.part_data[0].drawing_rectangle.IsEmpty)
2391                                 {
2392                                         Graphics gr = dc;
2393                                         for (int i = 0; i < dtp.part_data.Length; i++)
2394                                         {
2395                                                 DateTimePicker.PartData fd = dtp.part_data[i];
2396                                                 RectangleF text_rect = new RectangleF();
2397                                                 string text = fd.GetText(dtp.Value);
2398                                                 text_rect.Size = gr.MeasureString (text, dtp.Font, 250, text_format);
2399                                                 if (!fd.is_literal)
2400                                                         text_rect.Width = Math.Max (dtp.CalculateMaxWidth(fd.value, gr, text_format), text_rect.Width);
2401
2402                                                 if (i > 0) {
2403                                                         text_rect.X = dtp.part_data[i - 1].drawing_rectangle.Right;
2404                                                 } else {
2405                                                         text_rect.X = date_area_rect.X;
2406                                                 }
2407                                                 text_rect.Y = 2;
2408                                                 text_rect.Inflate (1, 0);
2409                                                 fd.drawing_rectangle = text_rect;
2410                                         }
2411                                 }
2412                                 
2413                                 // draw the text part
2414                                 Brush text_brush = ResPool.GetSolidBrush (dtp.ShowCheckBox && dtp.Checked == false ?
2415                                                 SystemColors.GrayText : dtp.ForeColor); // Use GrayText if Checked is false
2416                                 RectangleF clip_rectangleF = clip_rectangle;
2417
2418                                 for (int i = 0; i < dtp.part_data.Length; i++)
2419                                 {
2420                                         DateTimePicker.PartData fd = dtp.part_data [i];
2421                                         string text;
2422
2423                                         if (!clip_rectangleF.IntersectsWith (fd.drawing_rectangle))
2424                                                 continue;
2425
2426                                         text = dtp.editing_part_index == i ? dtp.editing_text : fd.GetText (dtp.Value);
2427
2428                                         PointF text_position = new PointF ();
2429                                         SizeF text_size;
2430                                         RectangleF text_rect;
2431
2432                                         text_size = dc.MeasureString (text, dtp.Font, 250, text_format);
2433                                         text_position.X = (fd.drawing_rectangle.Left + fd.drawing_rectangle.Width / 2) - text_size.Width / 2;
2434                                         text_position.Y = (fd.drawing_rectangle.Top + fd.drawing_rectangle.Height / 2) - text_size.Height / 2;
2435                                         text_rect = new RectangleF (text_position, text_size);
2436                                         text_rect = RectangleF.Intersect (text_rect, date_area_rect);
2437                                         
2438                                         if (text_rect.IsEmpty)
2439                                                 break;
2440
2441                                         if (text_rect.Right >= date_area_rect.Right)
2442                                                 text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2443                                         else
2444                                                 text_format.FormatFlags |= StringFormatFlags.NoClip;
2445                                         
2446                                         if (fd.Selected) {
2447                                                 dc.FillRectangle (SystemBrushes.Highlight, text_rect);
2448                                                 dc.DrawString (text, dtp.Font, SystemBrushes.HighlightText, text_rect, text_format);
2449                                         
2450                                         } else {
2451                                                 dc.DrawString (text, dtp.Font, text_brush, text_rect, text_format);
2452                                         }
2453
2454                                         if (fd.drawing_rectangle.Right > date_area_rect.Right)
2455                                                 break; // the next part would be not be visible, so don't draw anything more.
2456                                 }
2457                         }
2458                 }
2459
2460                 public override bool DateTimePickerBorderHasHotElementStyle {
2461                         get {
2462                                 return false;
2463                         }
2464                 }
2465
2466                 public override Rectangle DateTimePickerGetDropDownButtonArea (DateTimePicker dateTimePicker)
2467                 {
2468                         Rectangle rect = dateTimePicker.ClientRectangle;
2469                         rect.X = rect.Right - SystemInformation.VerticalScrollBarWidth - 2;
2470                         if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 2)) {
2471                                 rect.Width = SystemInformation.VerticalScrollBarWidth;
2472                         } else {
2473                                 rect.Width = Math.Max (rect.Width - 2, 0);
2474                         }
2475                         
2476                         rect.Inflate (0, -2);
2477                         return rect;
2478                 }
2479
2480                 public override Rectangle DateTimePickerGetDateArea (DateTimePicker dateTimePicker)
2481                 {
2482                         Rectangle rect = dateTimePicker.ClientRectangle;
2483                         if (dateTimePicker.ShowUpDown) {
2484                                 // set the space to the left of the up/down button
2485                                 if (rect.Width > (DateTimePicker.up_down_width + 4)) {
2486                                         rect.Width -= (DateTimePicker.up_down_width + 4);
2487                                 } else {
2488                                         rect.Width = 0;
2489                                 }
2490                         } else {
2491                                 // set the space to the left of the up/down button
2492                                 // TODO make this use up down button
2493                                 if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 4)) {
2494                                         rect.Width -= SystemInformation.VerticalScrollBarWidth;
2495                                 } else {
2496                                         rect.Width = 0;
2497                                 }
2498                         }
2499                         
2500                         rect.Inflate (-2, -2);
2501                         return rect;
2502                 }
2503                 public override bool DateTimePickerDropDownButtonHasHotElementStyle {
2504                         get {
2505                                 return false;
2506                         }
2507                 }
2508                 #endregion // DateTimePicker
2509
2510                 #region GroupBox
2511                 public override void DrawGroupBox (Graphics dc,  Rectangle area, GroupBox box) {
2512                         StringFormat    text_format;
2513                         SizeF           size;
2514                         int             width;
2515                         int             y;
2516
2517                         dc.FillRectangle (GetControlBackBrush (box.BackColor), box.ClientRectangle);
2518                         
2519                         text_format = new StringFormat();
2520                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
2521
2522                         size = dc.MeasureString (box.Text, box.Font);
2523                         width = 0;
2524
2525                         if (size.Width > 0) {
2526                                 width = ((int) size.Width) + 7;
2527                         
2528                                 if (width > box.Width - 16)
2529                                         width = box.Width - 16;
2530                         }
2531                         
2532                         y = box.Font.Height / 2;
2533
2534                         // Clip the are that the text will be in
2535                         Region prev_clip = dc.Clip;
2536                         dc.SetClip (new Rectangle (10, 0, width, box.Font.Height), CombineMode.Exclude);
2537                         /* Draw group box*/
2538                         CPDrawBorder3D (dc, new Rectangle (0, y, box.Width, box.Height - y), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, box.BackColor);
2539                         dc.Clip = prev_clip;
2540
2541                         /* Text */
2542                         if (box.Text.Length != 0) {
2543                                 if (box.Enabled) {
2544                                         dc.DrawString (box.Text, box.Font, ResPool.GetSolidBrush (box.ForeColor), 10, 0, text_format);
2545                                 } else {
2546                                         CPDrawStringDisabled (dc, box.Text, box.Font, box.BackColor, 
2547                                                               new RectangleF (10, 0, width,  box.Font.Height), text_format);
2548                                 }
2549                         }
2550                         
2551                         text_format.Dispose (); 
2552                 }
2553
2554                 public override Size GroupBoxDefaultSize {
2555                         get {
2556                                 return new Size (200,100);
2557                         }
2558                 }
2559                 #endregion
2560
2561                 #region HScrollBar
2562                 public override Size HScrollBarDefaultSize {
2563                         get {
2564                                 return new Size (80, this.ScrollBarButtonSize);
2565                         }
2566                 }
2567
2568                 #endregion      // HScrollBar
2569
2570                 #region ListBox
2571
2572                 public override void DrawListBoxItem (ListBox ctrl, DrawItemEventArgs e)
2573                 {
2574                         Color back_color, fore_color;
2575                         
2576                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
2577                                 back_color = ColorHighlight;
2578                                 fore_color = ColorHighlightText;
2579                         } else {
2580                                 back_color = e.BackColor;
2581                                 fore_color = e.ForeColor;
2582                         }
2583
2584                         e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
2585
2586                         e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
2587                                                ResPool.GetSolidBrush (fore_color),
2588                                                e.Bounds, ctrl.StringFormat);
2589                                         
2590                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
2591                                 CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
2592                 }
2593                 
2594                 #endregion ListBox
2595
2596                 #region ListView
2597                 // Drawing
2598                 public override void DrawListViewItems (Graphics dc, Rectangle clip, ListView control)
2599                 {
2600                         bool details = control.View == View.Details;
2601                         int first = control.FirstVisibleIndex;  
2602                         int lastvisibleindex = control.LastVisibleIndex;
2603
2604 #if NET_2_0
2605                         if (control.VirtualMode)
2606                                 control.OnCacheVirtualItems (new CacheVirtualItemsEventArgs (first, lastvisibleindex));
2607 #endif
2608
2609                         for (int i = first; i <= lastvisibleindex; i++) {                                       
2610                                 ListViewItem item = control.GetItemAtDisplayIndex (i);
2611                                 if (clip.IntersectsWith (item.Bounds)) {
2612 #if NET_2_0
2613                                         bool owner_draw = false;
2614                                         if (control.OwnerDraw)
2615                                                 owner_draw = DrawListViewItemOwnerDraw (dc, item, i);
2616                                         if (!owner_draw)
2617 #endif
2618                                         {
2619                                                 DrawListViewItem (dc, control, item);
2620                                                 if (control.View == View.Details)
2621                                                         DrawListViewSubItems (dc, control, item);
2622                                         }
2623                                 }
2624                         }       
2625
2626 #if NET_2_0
2627                         if (control.ShowGroups && control.View != View.List && control.Groups.Count > 0) {
2628                                 // Use InternalCount instead of Count to take into account Default Group as needed
2629                                 for (int i = 0; i < control.Groups.InternalCount; i++) {
2630                                         ListViewGroup group = control.Groups.GetInternalGroup (i);
2631                                         if (group.ItemCount > 0 && clip.IntersectsWith (group.HeaderBounds))
2632                                                 DrawListViewGroupHeader (dc, control, group);
2633                                 }
2634                         }
2635
2636                         ListViewInsertionMark insertion_mark = control.InsertionMark;
2637                         int insertion_mark_index = insertion_mark.Index;
2638                         if (insertion_mark.Bounds != Rectangle.Empty &&
2639                                         (control.View != View.Details && control.View != View.List) &&
2640                                         insertion_mark_index > -1 && insertion_mark_index < control.Items.Count) {
2641
2642                                 Brush brush = ResPool.GetSolidBrush (insertion_mark.Color);
2643                                 dc.FillRectangle (brush, insertion_mark.Line);
2644                                 dc.FillPolygon (brush, insertion_mark.TopTriangle);
2645                                 dc.FillPolygon (brush, insertion_mark.BottomTriangle);
2646                         }
2647 #endif
2648                         
2649                         // draw the gridlines
2650                         if (details && control.GridLines) {
2651                                 int top = (control.HeaderStyle == ColumnHeaderStyle.None) ?
2652                                         2 : control.Font.Height + 2;
2653
2654                                 // draw vertical gridlines
2655                                 foreach (ColumnHeader col in control.Columns)
2656                                         dc.DrawLine (SystemPens.Control,
2657                                                      col.Rect.Right, top,
2658                                                      col.Rect.Right, control.TotalHeight);
2659                                 // draw horizontal gridlines
2660                                 ListViewItem last_item = null;
2661                                 foreach (ListViewItem item in control.Items) {
2662                                         dc.DrawLine (SystemPens.Control,
2663                                                      item.GetBounds (ItemBoundsPortion.Entire).Left, item.GetBounds (ItemBoundsPortion.Entire).Top,
2664                                                      control.TotalWidth, item.GetBounds (ItemBoundsPortion.Entire).Top);
2665                                         last_item = item;
2666                                 }
2667
2668                                 // draw a line after at the bottom of the last item
2669                                 if (last_item != null) {
2670                                         dc.DrawLine (SystemPens.Control,
2671                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Left,
2672                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Bottom,
2673                                                      control.TotalWidth,
2674                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Bottom);
2675                                 }
2676                         }                       
2677                         
2678                         // Draw corner between the two scrollbars
2679                         if (control.h_scroll.Visible == true && control.v_scroll.Visible == true) {
2680                                 Rectangle rect = new Rectangle ();
2681                                 rect.X = control.h_scroll.Location.X + control.h_scroll.Width;
2682                                 rect.Width = control.v_scroll.Width;
2683                                 rect.Y = control.v_scroll.Location.Y + control.v_scroll.Height;
2684                                 rect.Height = control.h_scroll.Height;
2685                                 dc.FillRectangle (SystemBrushes.Control, rect);
2686                         }
2687
2688                         Rectangle box_select_rect = control.item_control.BoxSelectRectangle;
2689                         if (!box_select_rect.Size.IsEmpty)
2690                                 dc.DrawRectangle (ResPool.GetDashPen (ColorControlText, DashStyle.Dot), box_select_rect);
2691
2692                 }
2693
2694                 public override void DrawListViewHeader (Graphics dc, Rectangle clip, ListView control)
2695                 {       
2696                         bool details = (control.View == View.Details);
2697                                 
2698                         // border is drawn directly in the Paint method
2699                         if (details && control.HeaderStyle != ColumnHeaderStyle.None) {                         
2700                                 dc.FillRectangle (SystemBrushes.Control,
2701                                                   0, 0, control.TotalWidth, control.Font.Height + 5);
2702                                 if (control.Columns.Count > 0) {
2703                                         foreach (ColumnHeader col in control.Columns) {
2704                                                 Rectangle rect = col.Rect;
2705                                                 rect.X -= control.h_marker;
2706
2707 #if NET_2_0
2708                                                 bool owner_draw = false;
2709                                                 if (control.OwnerDraw)
2710                                                         owner_draw = DrawListViewColumnHeaderOwnerDraw (dc, control, col, rect);
2711                                                 if (owner_draw)
2712                                                         continue;
2713 #endif
2714
2715                                                 ListViewDrawColumnHeaderBackground (control, col, dc, rect, clip);
2716                                                 rect.X += 5;
2717                                                 rect.Width -= 10;
2718                                                 if (rect.Width <= 0)
2719                                                         continue;
2720
2721                                                 dc.DrawString (col.Text, control.Font,
2722                                                                SystemBrushes.ControlText,
2723                                                                rect, col.Format);
2724                                         }
2725                                         int right = control.GetReorderedColumn (control.Columns.Count - 1).Rect.Right - control.h_marker;
2726                                         if (right < control.Right) {
2727                                                 Rectangle rect = control.Columns [0].Rect;
2728                                                 rect.X = right;
2729                                                 rect.Width = control.Right - right;
2730                                                 ListViewDrawUnusedHeaderBackground (control, dc, rect, clip);
2731                                         }
2732                                 }
2733                         }
2734                 }
2735
2736                 protected virtual void ListViewDrawColumnHeaderBackground (ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea)
2737                 {
2738                         ButtonState state;
2739                         if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2740                                 state = columnHeader.Pressed ? ButtonState.Pushed : ButtonState.Normal;
2741                         else
2742                                 state = ButtonState.Flat;
2743                         CPDrawButton (g, area, state);
2744                 }
2745                 
2746                 protected virtual void ListViewDrawUnusedHeaderBackground (ListView listView, Graphics g, Rectangle area, Rectangle clippingArea)
2747                 {
2748                         ButtonState state;
2749                         if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2750                                 state = ButtonState.Normal;
2751                         else
2752                                 state = ButtonState.Flat;
2753                         CPDrawButton (g, area, state);
2754                 }
2755
2756                 public override void DrawListViewHeaderDragDetails (Graphics dc, ListView view, ColumnHeader col, int target_x)
2757                 {
2758                         Rectangle rect = col.Rect;
2759                         rect.X -= view.h_marker;
2760                         Color color = Color.FromArgb (0x7f, ColorControlDark.R, ColorControlDark.G, ColorControlDark.B);
2761                         dc.FillRectangle (ResPool.GetSolidBrush (color), rect);
2762                         rect.X += 3;
2763                         rect.Width -= 8;
2764                         if (rect.Width <= 0)
2765                                 return;
2766                         color = Color.FromArgb (0x7f, ColorControlText.R, ColorControlText.G, ColorControlText.B);
2767                         dc.DrawString (col.Text, view.Font, ResPool.GetSolidBrush (color), rect, col.Format);
2768                         dc.DrawLine (ResPool.GetSizedPen (ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height);
2769                 }
2770
2771 #if NET_2_0
2772                 protected virtual bool DrawListViewColumnHeaderOwnerDraw (Graphics dc, ListView control, ColumnHeader column, Rectangle bounds)
2773                 {
2774                         ListViewItemStates state = ListViewItemStates.ShowKeyboardCues;
2775                         if (column.Pressed)
2776                                 state |= ListViewItemStates.Selected;
2777
2778                         DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs (dc,
2779                                         bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont);
2780                         control.OnDrawColumnHeader (args);
2781
2782                         return !args.DrawDefault;
2783                 }
2784
2785                 protected virtual bool DrawListViewItemOwnerDraw (Graphics dc, ListViewItem item, int index)
2786                 {
2787                         ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues;
2788                         if (item.Selected)
2789                                 item_state |= ListViewItemStates.Selected;
2790                         if (item.Focused)
2791                                 item_state |= ListViewItemStates.Focused;
2792                                                 
2793                         DrawListViewItemEventArgs args = new DrawListViewItemEventArgs (dc,
2794                                         item, item.Bounds, index, item_state);
2795                         item.ListView.OnDrawItem (args);
2796
2797                         if (args.DrawDefault)
2798                                 return false;
2799
2800                         if (item.ListView.View == View.Details) {
2801                                 int count = Math.Min (item.ListView.Columns.Count, item.SubItems.Count);
2802                                 
2803                                 // Do system drawing for subitems if no owner draw is done
2804                                 for (int j = 0; j < count; j++) {
2805                                         if (!DrawListViewSubItemOwnerDraw (dc, item, item_state, j)) {
2806                                                 if (j == 0) // The first sub item contains the main item semantics
2807                                                         DrawListViewItem (dc, item.ListView, item);
2808                                                 else
2809                                                         DrawListViewSubItem (dc, item.ListView, item, j);
2810                                         }
2811                                 }
2812                         }
2813                         
2814                         return true;
2815                 }
2816 #endif
2817
2818                 protected virtual void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
2819                 {                               
2820                         Rectangle rect_checkrect = item.CheckRectReal;
2821                         Rectangle icon_rect = item.GetBounds (ItemBoundsPortion.Icon);
2822                         Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire);
2823                         Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);                 
2824
2825 #if NET_2_0
2826                         // Tile view doesn't support CheckBoxes
2827                         if (control.CheckBoxes && control.View != View.Tile) {
2828 #else
2829                         if (control.CheckBoxes) {
2830 #endif
2831                                 if (control.StateImageList == null) {
2832                                         // Make sure we've got at least a line width of 1
2833                                         int check_wd = Math.Max (3, rect_checkrect.Width / 6);
2834                                         int scale = Math.Max (1, rect_checkrect.Width / 12);
2835
2836                                         // set the checkbox background
2837                                         dc.FillRectangle (SystemBrushes.Window,
2838                                                           rect_checkrect);
2839                                         // define a rectangle inside the border area
2840                                         Rectangle rect = new Rectangle (rect_checkrect.X + 2,
2841                                                                         rect_checkrect.Y + 2,
2842                                                                         rect_checkrect.Width - 4,
2843                                                                         rect_checkrect.Height - 4);
2844                                         Pen pen = ResPool.GetSizedPen (this.ColorWindowText, 2);
2845                                         dc.DrawRectangle (pen, rect);
2846
2847                                         // Need to draw a check-mark
2848                                         if (item.Checked) {
2849                                                 Pen check_pen = ResPool.GetSizedPen (this.ColorWindowText, 1);
2850                                                 // adjustments to get the check-mark at the right place
2851                                                 rect.X ++; rect.Y ++;
2852                                                 // following logic is taken from DrawFrameControl method
2853                                                 int x_offset = rect.Width / 5;
2854                                                 int y_offset = rect.Height / 3;
2855                                                 for (int i = 0; i < check_wd; i++) {
2856                                                         dc.DrawLine (check_pen, rect.Left + x_offset,
2857                                                                      rect.Top + y_offset + i,
2858                                                                      rect.Left + x_offset + 2 * scale,
2859                                                                      rect.Top + y_offset + 2 * scale + i);
2860                                                         dc.DrawLine (check_pen,
2861                                                                      rect.Left + x_offset + 2 * scale,
2862                                                                      rect.Top + y_offset + 2 * scale + i,
2863                                                                      rect.Left + x_offset + 6 * scale,
2864                                                                      rect.Top + y_offset - 2 * scale + i);
2865                                                 }
2866                                         }
2867                                 }
2868                                 else {
2869                                         int simage_idx;
2870                                         if (item.Checked)
2871 #if NET_2_0
2872                                                 simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1;
2873 #else
2874                                                 simage_idx = control.StateImageList.Images.Count > 1 ? 1 : 0;
2875 #endif
2876                                         else
2877                                                 simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1;
2878
2879                                         if (simage_idx > -1)
2880                                                 control.StateImageList.Draw (dc, rect_checkrect.Location, simage_idx);
2881                                 }
2882                         }
2883
2884                         ImageList image_list = control.View == View.LargeIcon 
2885 #if NET_2_0
2886                                 || control.View == View.Tile
2887 #endif
2888                                 ? control.LargeImageList : control.SmallImageList;
2889                         if (image_list != null) {
2890                                 int idx;
2891
2892 #if NET_2_0
2893                                 if (item.ImageKey != String.Empty)
2894                                         idx = image_list.Images.IndexOfKey (item.ImageKey);
2895                                 else
2896 #endif
2897                                         idx = item.ImageIndex;
2898
2899                                 if (idx > -1 && idx < image_list.Images.Count)
2900                                         image_list.Draw (dc, icon_rect.Location, idx);
2901                         }
2902
2903                         // draw the item text                   
2904                         // format for the item text
2905                         StringFormat format = new StringFormat ();
2906                         if (control.View == View.SmallIcon || control.View == View.LargeIcon)
2907                                 format.LineAlignment = StringAlignment.Near;
2908                         else
2909                                 format.LineAlignment = StringAlignment.Center;
2910                         if (control.View == View.LargeIcon)
2911                                 format.Alignment = StringAlignment.Center;
2912                         else
2913                                 format.Alignment = StringAlignment.Near;
2914                         
2915 #if NET_2_0
2916                         if (control.LabelWrap && control.View != View.Details && control.View != View.Tile)
2917 #else
2918                         if (control.LabelWrap && control.View != View.Details)
2919 #endif
2920                                 format.FormatFlags = StringFormatFlags.LineLimit;
2921                         else
2922                                 format.FormatFlags = StringFormatFlags.NoWrap;
2923
2924                         if ((control.View == View.LargeIcon && !item.Focused)
2925                                         || control.View == View.Details 
2926 #if NET_2_0
2927                                         || control.View == View.Tile
2928 #endif
2929                            )
2930                                 format.Trimming = StringTrimming.EllipsisCharacter;
2931
2932                         Rectangle highlight_rect = text_rect;
2933                         if (control.View == View.Details) { // Adjustments for Details view
2934                                 Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
2935
2936                                 if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
2937                                         highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
2938                         }
2939
2940                         if (item.Selected && control.Focused)
2941                                 dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
2942                         else if (item.Selected && !control.HideSelection)
2943                                 dc.FillRectangle (SystemBrushes.Control, highlight_rect);
2944                         else
2945                                 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
2946                         
2947                         Brush textBrush =
2948                                 !control.Enabled ? SystemBrushes.ControlLight :
2949                                 (item.Selected && control.Focused) ? SystemBrushes.HighlightText :
2950                                 this.ResPool.GetSolidBrush (item.ForeColor);
2951
2952 #if NET_2_0
2953                         // Tile view renders its Text in a different fashion
2954                         if (control.View == View.Tile) {
2955                                 // Item.Text is drawn using its first subitem's bounds
2956                                 dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
2957
2958                                 int count = Math.Min (control.Columns.Count, item.SubItems.Count);
2959                                 for (int i = 1; i < count; i++) {
2960                                         ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
2961                                         if (sub_item.Text == null || sub_item.Text.Length == 0)
2962                                                 continue;
2963
2964                                         Brush itemBrush = item.Selected && control.Focused ? 
2965                                                 SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
2966                                         dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
2967                                 }
2968                         } else
2969 #endif
2970                         
2971                         if (item.Text != null && item.Text.Length > 0) {
2972                                 Font font = item.Font;
2973 #if NET_2_0
2974                                 if (control.HotTracking && item.Hot)
2975                                         font = item.HotFont;
2976 #endif
2977
2978                                 if (item.Selected && control.Focused)
2979                                         dc.DrawString (item.Text, font, textBrush, highlight_rect, format);
2980                                 else
2981                                         dc.DrawString (item.Text, font, textBrush, text_rect, format);
2982                         }
2983
2984                         if (item.Focused && control.Focused) {                          
2985                                 Rectangle focus_rect = highlight_rect;
2986                                 if (control.FullRowSelect && control.View == View.Details) {
2987                                         int width = 0;
2988                                         foreach (ColumnHeader col in control.Columns)
2989                                                 width += col.Width;
2990                                         focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height);
2991                                 }
2992                                 if (item.Selected)
2993                                         CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight);
2994                                 else
2995                                         CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor);
2996                         }
2997
2998                         format.Dispose ();
2999                 }
3000
3001                 protected virtual void DrawListViewSubItems (Graphics dc, ListView control, ListViewItem item)
3002                 {
3003                         int columns_count = control.Columns.Count;
3004                         int count = Math.Min (item.SubItems.Count, columns_count);
3005                         // 0th item already done (in this case)
3006                         for (int i = 1; i < count; i++)
3007                                 DrawListViewSubItem (dc, control, item, i);
3008
3009                         // Fill in selection for remaining columns if Column.Count > SubItems.Count
3010                         Rectangle sub_item_rect = item.GetBounds (ItemBoundsPortion.Label);
3011                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3012                                 for (int index = count; index < columns_count; index++) {
3013                                         ColumnHeader col = control.Columns [index];
3014                                         sub_item_rect.X = col.Rect.X - control.h_marker;
3015                                         sub_item_rect.Width = col.Wd;
3016                                         dc.FillRectangle (control.Focused ? SystemBrushes.Highlight : SystemBrushes.Control, 
3017                                                         sub_item_rect);
3018                                 }
3019                         }
3020                 }
3021
3022                 protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index)
3023                 {
3024                         ListViewItem.ListViewSubItem subItem = item.SubItems [index];
3025                         ColumnHeader col = control.Columns [index];
3026                         StringFormat format = new StringFormat ();
3027                         format.Alignment = col.Format.Alignment;
3028                         format.FormatFlags = StringFormatFlags.NoWrap;
3029                         format.Trimming = StringTrimming.EllipsisCharacter;
3030
3031                         Rectangle sub_item_rect = subItem.Bounds;
3032                         Rectangle sub_item_text_rect = sub_item_rect;
3033                         sub_item_text_rect.X += 3;
3034                         sub_item_text_rect.Width -= ListViewItemPaddingWidth;
3035                                                 
3036                         SolidBrush sub_item_back_br = null;
3037                         SolidBrush sub_item_fore_br = null;
3038                         Font sub_item_font = null;
3039                                                 
3040                         if (item.UseItemStyleForSubItems) {
3041                                 sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
3042                                 sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
3043 #if NET_2_0
3044                                 // Hot tracking for subitems only applies when UseStyle is true
3045                                 if (control.HotTracking && item.Hot)
3046                                         sub_item_font = item.HotFont;
3047                                 else
3048 #endif
3049                                         sub_item_font = item.Font;
3050                         } else {
3051                                 sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
3052                                 sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
3053                                 sub_item_font = subItem.Font;
3054                         }
3055                                                 
3056                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3057                                 Brush bg, text;
3058                                 if (control.Focused) {
3059                                         bg = SystemBrushes.Highlight;
3060                                         text = SystemBrushes.HighlightText;
3061                                 } else {
3062                                         bg = SystemBrushes.Control;
3063                                         text = sub_item_fore_br;
3064                                                         
3065                                 }
3066                                                         
3067                                 dc.FillRectangle (bg, sub_item_rect);
3068                                 if (subItem.Text != null && subItem.Text.Length > 0)
3069                                         dc.DrawString (subItem.Text, sub_item_font,
3070                                                         text, sub_item_text_rect, format);
3071                         } else {
3072                                 dc.FillRectangle (sub_item_back_br, sub_item_rect);
3073                                 if (subItem.Text != null && subItem.Text.Length > 0)
3074                                         dc.DrawString (subItem.Text, sub_item_font,
3075                                                         sub_item_fore_br,
3076                                                         sub_item_text_rect, format);
3077                         }
3078
3079                         format.Dispose ();
3080                 }
3081
3082 #if NET_2_0
3083                 protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index)
3084                 {
3085                         ListView control = item.ListView;
3086                         ListViewItem.ListViewSubItem subitem = item.SubItems [index];
3087
3088                         DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item, 
3089                                         subitem, item.Index, index, control.Columns [index], state);
3090                         control.OnDrawSubItem (args);
3091                         
3092                         return !args.DrawDefault;
3093                 }
3094
3095                 protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group)
3096                 {
3097                         Rectangle text_bounds = group.HeaderBounds;
3098                         Rectangle header_bounds = group.HeaderBounds;
3099                         text_bounds.Offset (8, 0);
3100                         text_bounds.Inflate (-8, 0);
3101                         Size text_size = control.text_size;
3102
3103                         Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
3104                         Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0), 
3105                                         SystemColors.Desktop, Color.White);
3106                         Pen pen = new Pen (brush);
3107
3108                         StringFormat sformat = new StringFormat ();
3109                         switch (group.HeaderAlignment) {
3110                                 case HorizontalAlignment.Left:
3111                                         sformat.Alignment = StringAlignment.Near;
3112                                         break;
3113                                 case HorizontalAlignment.Center:
3114                                         sformat.Alignment = StringAlignment.Center;
3115                                         break;
3116                                 case HorizontalAlignment.Right:
3117                                         sformat.Alignment = StringAlignment.Far;
3118                                         break;
3119                         }
3120
3121                         sformat.LineAlignment = StringAlignment.Near;
3122                         dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat);
3123                         dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_size.Height, header_bounds.Left + ListViewGroupLineWidth, 
3124                                         header_bounds.Top + text_size.Height);
3125
3126                         sformat.Dispose ();
3127                         font.Dispose ();
3128                         pen.Dispose ();
3129                         brush.Dispose ();
3130                 }
3131 #endif
3132
3133                 public override bool ListViewHasHotHeaderStyle {
3134                         get {
3135                                 return false;
3136                         }
3137                 }
3138
3139                 // Sizing
3140                 public override int ListViewGetHeaderHeight (ListView listView, Font font)
3141                 {
3142                         return font.Height + 5;
3143                 }
3144
3145                 public override Size ListViewCheckBoxSize {
3146                         get { return new Size (16, 16); }
3147                 }
3148
3149                 public override int ListViewColumnHeaderHeight {
3150                         get { return 16; }
3151                 }
3152
3153                 public override int ListViewDefaultColumnWidth {
3154                         get { return 60; }
3155                 }
3156
3157                 public override int ListViewVerticalSpacing {
3158                         get { return 22; }
3159                 }
3160
3161                 public override int ListViewEmptyColumnWidth {
3162                         get { return 10; }
3163                 }
3164
3165                 public override int ListViewHorizontalSpacing {
3166                         get { return 4; }
3167                 }
3168
3169                 public override int ListViewItemPaddingWidth {
3170                         get { return 6; }
3171                 }
3172
3173                 public override Size ListViewDefaultSize {
3174                         get { return new Size (121, 97); }
3175                 }
3176
3177                 public override int ListViewGroupHeight { 
3178                         get { return 20; }
3179                 }
3180
3181                 public int ListViewGroupLineWidth {
3182                         get { return 200; }
3183                 }
3184
3185                 public override int ListViewTileWidthFactor {
3186                         get { return 22; }
3187                 }
3188
3189                 public override int ListViewTileHeightFactor {
3190                         get { return 3; }
3191                 }
3192                 #endregion      // ListView
3193                 
3194                 #region Menus
3195                 
3196                 public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
3197                 {
3198                         item.X = x;
3199                         item.Y = y;
3200
3201                         if (item.Visible == false) {
3202                                 item.Width = 0;
3203                                 item.Height = 0;
3204                                 return;
3205                         }
3206
3207                         if (item.Separator == true) {
3208                                 item.Height = SEPARATOR_HEIGHT;
3209                                 item.Width = SEPARATOR_MIN_WIDTH;
3210                                 return;
3211                         }
3212                         
3213                         if (item.MeasureEventDefined) {
3214                                 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
3215                                 item.PerformMeasureItem (mi);
3216                                 item.Height = mi.ItemHeight;
3217                                 item.Width = mi.ItemWidth;
3218                                 return;
3219                         } else {                
3220                                 SizeF size;
3221                                 size =  dc.MeasureString (item.Text, MenuFont, int.MaxValue, string_format_menu_text);
3222                                 item.Width = (int) size.Width;
3223                                 item.Height = (int) size.Height;
3224         
3225                                 if (!menuBar) {
3226                                         if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
3227                                                 item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
3228                                                 size =  dc.MeasureString (" " + item.GetShortCutText (), MenuFont);
3229                                                 item.Width += MENU_TAB_SPACE + (int) size.Width;
3230                                         }
3231         
3232                                         item.Width += 4 + (MenuCheckSize.Width * 2);
3233                                 } else {
3234                                         item.Width += MENU_BAR_ITEMS_SPACE;
3235                                         x += item.Width;
3236                                 }
3237         
3238                                 if (item.Height < MenuHeight)
3239                                         item.Height = MenuHeight;
3240                         }
3241                 }
3242                 
3243                 // Updates the menu rect and returns the height
3244                 public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
3245                 {
3246                         int x = 0;
3247                         int y = 0;
3248                         menu.Height = 0;
3249
3250                         foreach (MenuItem item in menu.MenuItems) {
3251
3252                                 CalcItemSize (dc, item, y, x, true);
3253
3254                                 if (x + item.Width > width) {
3255                                         item.X = 0;
3256                                         y += item.Height;
3257                                         item.Y = y;
3258                                         x = 0;
3259                                 }
3260
3261                                 x += item.Width;
3262                                 item.MenuBar = true;                            
3263
3264                                 if (y + item.Height > menu.Height)
3265                                         menu.Height = item.Height + y;
3266                         }
3267
3268                         menu.Width = width;                                             
3269                         return menu.Height;
3270                 }
3271
3272                 public override void CalcPopupMenuSize (Graphics dc, Menu menu)
3273                 {
3274                         int x = 3;
3275                         int start = 0;
3276                         int i, n, y, max;
3277
3278                         menu.Height = 0;
3279
3280                         while (start < menu.MenuItems.Count) {
3281                                 y = 3;
3282                                 max = 0;
3283                                 for (i = start; i < menu.MenuItems.Count; i++) {
3284                                         MenuItem item = menu.MenuItems [i];
3285
3286                                         if ((i != start) && (item.Break || item.BarBreak))
3287                                                 break;
3288
3289                                         CalcItemSize (dc, item, y, x, false);
3290                                         y += item.Height;
3291
3292                                         if (item.Width > max)
3293                                                 max = item.Width;
3294                                 }
3295
3296                                 // Replace the -1 by the menu width (separators)
3297                                 for (n = start; n < i; n++, start++)
3298                                         menu.MenuItems [n].Width = max;
3299
3300                                 if (y > menu.Height)
3301                                         menu.Height = y;
3302
3303                                 x+= max;
3304                         }
3305
3306                         menu.Width = x;
3307                         
3308                         //space for border
3309                         menu.Width += 2;
3310                         menu.Height += 2;
3311
3312                         menu.Width += SM_CXBORDER;
3313                 menu.Height += SM_CYBORDER;
3314                 }
3315                 
3316                 // Draws a menu bar in a window
3317                 public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
3318                 {
3319                         if (menu.Height == 0)
3320                                 CalcMenuBarSize (dc, menu, rect.Width);
3321
3322                         bool keynav = (menu as MainMenu).tracker.hotkey_active;
3323                         HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
3324                         string_format_menu_menubar_text.HotkeyPrefix = hp;
3325                         string_format_menu_text.HotkeyPrefix = hp;
3326
3327                         rect.Height = menu.Height;
3328                         dc.FillRectangle (SystemBrushes.Menu, rect);
3329                         
3330                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3331                                 MenuItem item = menu.MenuItems [i];
3332                                 Rectangle item_rect = item.bounds;
3333                                 item_rect.X += rect.X;
3334                                 item_rect.Y += rect.Y;
3335                                 item.MenuHeight = menu.Height;
3336                                 item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status)); 
3337                         }       
3338                 }               
3339                 
3340                 protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color)
3341                 {
3342                         Color bg_color;
3343                         if (color.R == 0 && color.G == 0 && color.B == 0)
3344                                 bg_color = Color.White;
3345                         else
3346                                 bg_color = Color.Black;
3347                         
3348                         Bitmap  bmp = new Bitmap (size.Width, size.Height);
3349                         Graphics gr = Graphics.FromImage (bmp);
3350                         Rectangle rect = new Rectangle (Point.Empty, size);
3351                         gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
3352                         CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty);
3353                         bmp.MakeTransparent (bg_color);
3354                         gr.Dispose ();
3355                         
3356                         return bmp;
3357                 }
3358
3359                 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
3360                 {
3361                         StringFormat string_format;
3362                         Rectangle rect_text = e.Bounds;
3363                         
3364                         if (item.Visible == false)
3365                                 return;
3366
3367                         if (item.MenuBar)
3368                                 string_format = string_format_menu_menubar_text;
3369                         else
3370                                 string_format = string_format_menu_text;
3371
3372                         if (item.Separator == true) {
3373                                 int liney = e.Bounds.Y + (e.Bounds.Height / 2);
3374                                 
3375                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3376                                         e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney);
3377
3378                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3379                                         e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1);
3380
3381                                 return;
3382                         }
3383
3384                         if (!item.MenuBar)
3385                                 rect_text.X += MenuCheckSize.Width;
3386
3387                         if (item.BarBreak) { /* Draw vertical break bar*/
3388                                 Rectangle rect = e.Bounds;
3389                                 rect.Y++;
3390                                 rect.Width = 3;
3391                                 rect.Height = item.MenuHeight - 6;
3392
3393                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3394                                         rect.X, rect.Y , rect.X, rect.Y + rect.Height);
3395
3396                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3397                                         rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
3398                         }                       
3399                         
3400                         Color color_text;
3401                         Color color_back;
3402                         Brush brush_text = null;
3403                         Brush brush_back = null;
3404                         
3405                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) {
3406                                 color_text = ColorHighlightText;
3407                                 color_back = ColorHighlight;
3408                                 brush_text = SystemBrushes.HighlightText;
3409                                 brush_back = SystemBrushes.Highlight;
3410                         } else {
3411                                 color_text = ColorMenuText;
3412                                 color_back = ColorMenu;
3413                                 brush_text = ResPool.GetSolidBrush (ColorMenuText);
3414                                 brush_back = SystemBrushes.Menu;
3415                         }
3416
3417                         /* Draw background */
3418                         if (!item.MenuBar)
3419                                 e.Graphics.FillRectangle (brush_back, e.Bounds);
3420                         
3421                         if (item.Enabled) {
3422                                 e.Graphics.DrawString (item.Text, e.Font,
3423                                         brush_text,
3424                                         rect_text, string_format);
3425                                 
3426                                 if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
3427                                         string str = item.GetShortCutText ();
3428                                         Rectangle rect = rect_text;
3429                                         rect.X = item.XTab;
3430                                         rect.Width -= item.XTab;
3431
3432                                         e.Graphics.DrawString (str, e.Font, brush_text,
3433                                                 rect, string_format_menu_shortcut);
3434                                 }
3435                                 
3436                                 if (item.MenuBar) {
3437                                         Border3DStyle border_style = Border3DStyle.Adjust;
3438                                         if ((item.Status & DrawItemState.HotLight) != 0)
3439                                                 border_style = Border3DStyle.RaisedInner;
3440                                         else if ((item.Status & DrawItemState.Selected) != 0)
3441                                                 border_style = Border3DStyle.SunkenOuter;
3442                                         
3443                                         if (border_style != Border3DStyle.Adjust)
3444                                                 CPDrawBorder3D(e.Graphics, e.Bounds, border_style,  Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu);
3445                                 }
3446                         } else {
3447                                 if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3448                                         e.Graphics.DrawString (item.Text, e.Font, Brushes.White, 
3449                                                                new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height),
3450                                                                string_format);
3451                                 }
3452                                 
3453                                 e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format);
3454                         }
3455
3456                         /* Draw arrow */
3457                         if (item.MenuBar == false && (item.IsPopup || item.MdiList)) {
3458
3459                                 int cx = MenuCheckSize.Width;
3460                                 int cy = MenuCheckSize.Height;
3461                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text);
3462                                 
3463                                 if (item.Enabled) {
3464                                         e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
3465                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
3466                                 } else {
3467                                         ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
3468                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
3469                                 }
3470  
3471                                 bmp.Dispose ();
3472                         }
3473
3474                         /* Draw checked or radio */
3475                         if (item.MenuBar == false && item.Checked) {
3476
3477                                 Rectangle area = e.Bounds;
3478                                 int cx = MenuCheckSize.Width;
3479                                 int cy = MenuCheckSize.Height;
3480                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text);
3481
3482                                 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
3483
3484                                 bmp.Dispose ();
3485                         }                       
3486                 }               
3487                         
3488                 public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
3489                 {
3490                         // Fill rectangle area
3491                         dc.FillRectangle (SystemBrushes.Menu, cliparea);
3492                         
3493                         // Draw menu borders
3494                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
3495                         
3496                         // Draw menu items
3497                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3498                                 if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
3499                                         MenuItem item = menu.MenuItems [i];
3500                                         item.MenuHeight = menu.Height;
3501                                         item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status));
3502                                 }
3503                         }
3504                 }
3505                 
3506                 #endregion // Menus
3507
3508                 #region MonthCalendar
3509
3510                 // draw the month calendar
3511                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) 
3512                 {
3513                         Rectangle client_rectangle = mc.ClientRectangle;
3514                         Size month_size = mc.SingleMonthSize;
3515                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3516                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
3517                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3518                         
3519                         // draw the singlecalendars
3520                         int x_offset = 1;
3521                         int y_offset = 1;
3522                         // adjust for the position of the specific month
3523                         for (int i=0; i < mc.CalendarDimensions.Height; i++) 
3524                         {
3525                                 if (i > 0) 
3526                                 {
3527                                         y_offset += month_size.Height + calendar_spacing.Height;
3528                                 }
3529                                 // now adjust for x position    
3530                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) 
3531                                 {
3532                                         if (j > 0) 
3533                                         {
3534                                                 x_offset += month_size.Width + calendar_spacing.Width;
3535                                         } 
3536                                         else 
3537                                         {
3538                                                 x_offset = 1;
3539                                         }
3540
3541                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
3542                                         if (month_rect.IntersectsWith (clip_rectangle)) {
3543                                                 DrawSingleMonth (
3544                                                         dc,
3545                                                         clip_rectangle,
3546                                                         month_rect,
3547                                                         mc,
3548                                                         i,
3549                                                         j);
3550                                         }
3551                                 }
3552                         }
3553                         
3554                         Rectangle bottom_rect = new Rectangle (
3555                                                 client_rectangle.X,
3556                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
3557                                                 client_rectangle.Width,
3558                                                 date_cell_size.Height + 2);
3559                         // draw the today date if it's set
3560                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) 
3561                         {
3562                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect);
3563                                 if (mc.ShowToday) {
3564                                         int today_offset = 5;
3565                                         if (mc.ShowTodayCircle) 
3566                                         {
3567                                                 Rectangle today_circle_rect = new Rectangle (
3568                                                         client_rectangle.X + 5,
3569                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
3570                                                         date_cell_size.Width,
3571                                                         date_cell_size.Height);
3572                                                         DrawTodayCircle (dc, today_circle_rect);
3573                                                 today_offset += date_cell_size.Width + 5;
3574                                         }
3575                                         // draw today's date
3576                                         StringFormat text_format = new StringFormat();
3577                                         text_format.LineAlignment = StringAlignment.Center;
3578                                         text_format.Alignment = StringAlignment.Near;
3579                                         Rectangle today_rect = new Rectangle (
3580                                                         today_offset + client_rectangle.X,
3581                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
3582                                                         Math.Max(client_rectangle.Width - today_offset, 0),
3583                                                         date_cell_size.Height);
3584                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format);
3585                                         text_format.Dispose ();
3586                                 }                               
3587                         }
3588                         
3589                         Brush border_brush;
3590                         
3591                         if (mc.owner == null)
3592                                 border_brush = GetControlBackBrush (mc.BackColor);
3593                         else
3594                                 border_brush = SystemBrushes.ControlDarkDark;
3595                                 
3596                         // finally paint the borders of the calendars as required
3597                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
3598                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
3599                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height);
3600                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
3601                                         dc.FillRectangle (border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height);
3602                                 } else { 
3603                                         Rectangle rect = new Rectangle (
3604                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
3605                                                 client_rectangle.Y,
3606                                                 calendar_spacing.Width,
3607                                                 client_rectangle.Height);
3608                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3609                                                 dc.FillRectangle (border_brush, rect);
3610                                         }
3611                                 }
3612                         }
3613                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
3614                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
3615                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1);
3616                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
3617                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1);
3618                                 } else { 
3619                                         Rectangle rect = new Rectangle (
3620                                                 client_rectangle.X,
3621                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
3622                                                 client_rectangle.Width,
3623                                                 calendar_spacing.Height);
3624                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3625                                                 dc.FillRectangle (border_brush, rect);
3626                                         }
3627                                 }
3628                         }
3629                         
3630                         // draw the drop down border if need
3631                         if (mc.owner != null) {
3632                                 Rectangle bounds = mc.ClientRectangle;
3633                                 if (clip_rectangle.Contains (mc.Location)) {
3634                                         // find out if top or left line to draw
3635                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3636                                         
3637                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
3638                                         }
3639                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3640                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
3641                                         }
3642                                 }
3643                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
3644                                         // find out if bottom or right line to draw
3645                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3646                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
3647                                         }
3648                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3649                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
3650                                         }
3651                                 }
3652                         }
3653                 }
3654
3655                 // darws a single part of the month calendar (with one month)
3656                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) 
3657                 {
3658                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3659                         Size title_size = (Size)((object)mc.title_size);
3660                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3661                         DateTime current_month = (DateTime)((object)mc.current_month);
3662                         DateTime sunday = new DateTime(2006, 10, 1);
3663                         
3664                         // draw the title back ground
3665                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
3666                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
3667                         if (title_rect.IntersectsWith (clip_rectangle)) {
3668                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
3669                                 // draw the title                               
3670                                 string title_text = this_month.ToString ("MMMM yyyy");
3671                                 dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format);
3672
3673                                 if (mc.ShowYearUpDown) {
3674                                         Rectangle year_rect;
3675                                         Rectangle upRect, downRect;
3676                                         ButtonState upState, downState;
3677                                         
3678                                         mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect);
3679                                         dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect);
3680                                         dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format);
3681                                         
3682                                         upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal;
3683                                         downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal;
3684
3685                                         ControlPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState);
3686                                         ControlPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState);
3687                                 }
3688
3689                                 // draw previous and next buttons if it's time
3690                                 if (row == 0 && col == 0) 
3691                                 {
3692                                         // draw previous button
3693                                         DrawMonthCalendarButton (
3694                                                 dc,
3695                                                 rectangle,
3696                                                 mc,
3697                                                 title_size,
3698                                                 mc.button_x_offset,
3699                                                 (System.Drawing.Size)((object)mc.button_size),
3700                                                 true);
3701                                 }
3702                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) 
3703                                 {
3704                                         // draw next button
3705                                         DrawMonthCalendarButton (
3706                                                 dc,
3707                                                 rectangle,
3708                                                 mc,
3709                                                 title_size,
3710                                                 mc.button_x_offset,
3711                                                 (System.Drawing.Size)((object)mc.button_size),
3712                                                 false);
3713                                 }
3714                         }
3715                         
3716                         // set the week offset and draw week nums if needed
3717                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
3718                         Rectangle day_name_rect = new Rectangle(
3719                                 rectangle.X,
3720                                 rectangle.Y + title_size.Height,
3721                                 (7 + col_offset) * date_cell_size.Width,
3722                                 date_cell_size.Height);
3723                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
3724                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect);
3725                                 // draw the day names 
3726                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
3727                                 for (int i=0; i < 7; i++) 
3728                                 {
3729                                         int position = i - (int) first_day_of_week;
3730                                         if (position < 0) 
3731                                         {
3732                                                 position = 7 + position;
3733                                         }
3734                                         // draw it
3735                                         Rectangle day_rect = new Rectangle(
3736                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
3737                                                 day_name_rect.Y,
3738                                                 date_cell_size.Width,
3739                                                 date_cell_size.Height);
3740                                         dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format);
3741                                 }
3742                                 
3743                                 // draw the vertical divider
3744                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
3745                                 dc.DrawLine (
3746                                         ResPool.GetPen (mc.ForeColor),
3747                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
3748                                         rectangle.Y + vert_divider_y,
3749                                         rectangle.Right - mc.divider_line_offset,
3750                                         rectangle.Y + vert_divider_y);
3751                         }
3752
3753
3754                         // draw the actual date items in the grid (including the week numbers)
3755                         Rectangle date_rect = new Rectangle (
3756                                 rectangle.X,
3757                                 rectangle.Y + title_size.Height + date_cell_size.Height,
3758                                 date_cell_size.Width,
3759                                 date_cell_size.Height);
3760                         int month_row_count = 0;
3761                         bool draw_week_num_divider = false;
3762                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
3763                         for (int i=0; i < 6; i++) 
3764                         {
3765                                 // establish if this row is in our clip_area
3766                                 Rectangle row_rect = new Rectangle (
3767                                         rectangle.X,
3768                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
3769                                         date_cell_size.Width * 7,
3770                                         date_cell_size.Height);
3771                                 if (mc.ShowWeekNumbers) {
3772                                         row_rect.Width += date_cell_size.Width;
3773                                 }
3774                 
3775                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
3776                                 if (draw_row) {
3777                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect);
3778                                 }
3779                                 // establish if this is a valid week to draw
3780                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
3781                                         month_row_count = i;
3782                                 }
3783                                 
3784                                 // draw the week number if required
3785                                 if (mc.ShowWeekNumbers && month_row_count == i) {
3786                                         if (!draw_week_num_divider) {
3787                                                 draw_week_num_divider = draw_row;
3788                                         }
3789                                         // get the week for this row
3790                                         int week = mc.GetWeekOfYear (current_date);     
3791
3792                                         if (draw_row) {
3793                                                 dc.DrawString (
3794                                                         week.ToString(),
3795                                                         mc.Font,
3796                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
3797                                                         date_rect,
3798                                                         mc.centered_format);
3799                                         }
3800                                         date_rect.Offset(date_cell_size.Width, 0);
3801                                 }
3802                                                                 
3803                                 // only draw the days if we have to
3804                                 if(month_row_count == i) {
3805                                         for (int j=0; j < 7; j++) 
3806                                         {
3807                                                 if (draw_row) {
3808                                                         DrawMonthCalendarDate (
3809                                                                 dc,
3810                                                                 date_rect,
3811                                                                 mc,
3812                                                                 current_date,
3813                                                                 this_month,
3814                                                                 row,
3815                                                                 col);
3816                                                 }
3817
3818                                                 // move the day on
3819                                                 current_date = current_date.AddDays(1);
3820                                                 date_rect.Offset(date_cell_size.Width, 0);
3821                                         }
3822
3823                                         // shift the rectangle down one row
3824                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
3825                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
3826                                 }
3827                         }
3828
3829                         // month_row_count is zero based, so add one
3830                         month_row_count++;
3831
3832                         // draw week numbers if required
3833                         if (draw_week_num_divider) {
3834                                 col_offset = 1;
3835                                 dc.DrawLine (
3836                                         ResPool.GetPen (mc.ForeColor),
3837                                         rectangle.X + date_cell_size.Width - 1,
3838                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
3839                                         rectangle.X + date_cell_size.Width - 1,
3840                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
3841                         }
3842                 }
3843
3844                 // draws the pervious or next button
3845                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) 
3846                 {
3847                         const int arrow_width = 4;
3848                         const int arrow_height = 7;
3849
3850                         bool is_clicked = false;
3851                         Rectangle button_rect;
3852                         PointF arrow_center;
3853                         PointF [] arrow_path = new PointF [3];
3854                         
3855                         // prepare the button
3856                         if (is_previous) 
3857                         {
3858                                 is_clicked = mc.is_previous_clicked;
3859
3860                                 button_rect = new Rectangle (
3861                                         rectangle.X + 1 + x_offset,
3862                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3863                                         Math.Max(button_size.Width - 1, 0),
3864                                         Math.Max(button_size.Height - 1, 0));
3865
3866                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3867                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3868                                 if (is_clicked) {
3869                                         arrow_center.X += 1;
3870                                         arrow_center.Y += 1;
3871                                 }
3872
3873                                 arrow_path [0].X = arrow_center.X;
3874                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3875                                 arrow_path [1].X = arrow_center.X;
3876                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3877                                 arrow_path [2].X = arrow_center.X - arrow_width;
3878                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3879                         }
3880                         else
3881                         {
3882                                 is_clicked = mc.is_next_clicked;
3883
3884                                 button_rect = new Rectangle (
3885                                         rectangle.Right - 1 - x_offset - button_size.Width,
3886                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3887                                         Math.Max(button_size.Width - 1, 0),
3888                                         Math.Max(button_size.Height - 1, 0));
3889
3890                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3891                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3892                                 if (is_clicked) {
3893                                         arrow_center.X += 1;
3894                                         arrow_center.Y += 1;
3895                                 }
3896
3897                                 arrow_path [0].X = arrow_center.X - arrow_width;
3898                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3899                                 arrow_path [1].X = arrow_center.X - arrow_width;
3900                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3901                                 arrow_path [2].X = arrow_center.X;
3902                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3903                         }
3904
3905                         // fill the background
3906                         dc.FillRectangle (SystemBrushes.Control, button_rect);
3907                         // draw the border
3908                         if (is_clicked) {
3909                                 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
3910                         }
3911                         else {
3912                                 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
3913                         }
3914                         // draw the arrow
3915                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);                 
3916                         //dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding);
3917                 }
3918                 
3919
3920                 // draws one day in the calendar grid
3921                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
3922                         Color date_color = mc.ForeColor;
3923                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
3924
3925                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
3926                         if (date.Year != month.Year || date.Month != month.Month) {
3927                                 DateTime check_date = month.AddMonths (-1);
3928                                 // check if it's the month before 
3929                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
3930                                         date_color = mc.TrailingForeColor;
3931                                 } else {
3932                                         // check if it's the month after
3933                                         check_date = month.AddMonths (1);
3934                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
3935                                                 date_color = mc.TrailingForeColor;
3936                                         } else {
3937                                                 return;
3938                                         }
3939                                 }
3940                         } else {
3941                                 date_color = mc.ForeColor;
3942                         }
3943
3944                         const int inflate = -1;
3945
3946                         if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) {
3947                                 // see if the date is in the start of selection
3948                                 date_color = mc.BackColor;
3949                                 // draw the left hand of the back ground
3950                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
3951                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360);
3952                         } else if (date == mc.SelectionStart.Date) {
3953                                 // see if the date is in the start of selection
3954                                 date_color = mc.BackColor;
3955                                 // draw the left hand of the back ground
3956                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
3957                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
3958                                 // fill the other side as a straight rect
3959                                 if (date < mc.SelectionEnd.Date) 
3960                                 {
3961                                         // use rectangle instead of rectangle to go all the way to edge of rect
3962                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
3963                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
3964                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3965                                 }
3966                         } else if (date == mc.SelectionEnd.Date) {
3967                                 // see if it is the end of selection
3968                                 date_color = mc.BackColor;
3969                                 // draw the left hand of the back ground
3970                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
3971                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
3972                                 // fill the other side as a straight rect
3973                                 if (date > mc.SelectionStart.Date) {
3974                                         selection_rect.X = rectangle.X;
3975                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
3976                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3977                                 }
3978                         } else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) {
3979                                 // now see if it's in the middle
3980                                 date_color = mc.BackColor;
3981                                 // draw the left hand of the back ground
3982                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate);
3983                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3984                         }
3985
3986                         // establish if it's a bolded font
3987                         Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font;
3988
3989                         // just draw the date now
3990                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format);
3991
3992                         // today circle if needed
3993                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
3994                                 DrawTodayCircle (dc, interior);
3995                         }
3996
3997                         // draw the selection grid
3998                         if (mc.is_date_clicked && mc.clicked_date == date) {
3999                                 Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot);
4000                                 dc.DrawRectangle (pen, interior);
4001                         }
4002                 }
4003
4004                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
4005                         Color circle_color = Color.FromArgb (248, 0, 0);
4006                         // draw the left hand of the circle 
4007                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
4008                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
4009                         Point [] curve_points = new Point [3];
4010                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
4011                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
4012                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
4013
4014                         Pen pen = ResPool.GetSizedPen(circle_color, 2);
4015                         dc.DrawArc (pen, lhs_circle_rect, 90, 180);
4016                         dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
4017                         dc.DrawCurve (pen, curve_points);
4018                         dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
4019                 }
4020
4021                 #endregion      // MonthCalendar
4022
4023                 #region Panel
4024                 public override Size PanelDefaultSize {
4025                         get {
4026                                 return new Size (200, 100);
4027                         }
4028                 }
4029                 #endregion      // Panel
4030
4031                 #region PictureBox
4032                 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
4033                         Rectangle client = pb.ClientRectangle;
4034
4035                         // FIXME - instead of drawing the whole picturebox every time
4036                         // intersect the clip rectangle with the drawn picture and only draw what's needed,
4037                         // Also, we only need a background fill where no image goes
4038                         if (pb.Image != null) {
4039                                 switch (pb.SizeMode) {
4040                                 case PictureBoxSizeMode.StretchImage:
4041                                         dc.DrawImage (pb.Image, 0, 0, client.Width, client.Height);
4042                                         break;
4043
4044                                 case PictureBoxSizeMode.CenterImage:
4045                                         dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
4046                                         break;
4047 #if NET_2_0
4048                                 case PictureBoxSizeMode.Zoom:
4049                                         Size image_size;
4050                                         
4051                                         if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height))
4052                                                 image_size = new Size (client.Width, (pb.Image.Height * client.Width) / pb.Image.Width);
4053                                         else
4054                                                 image_size = new Size ((pb.Image.Width * client.Height) / pb.Image.Height, client.Height);
4055
4056                                         dc.DrawImage (pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height);
4057                                         break;
4058 #endif
4059                                 default:
4060                                         // Normal, AutoSize
4061                                         dc.DrawImage(pb.Image, 0, 0, pb.Image.Width, pb.Image.Height);
4062                                         break;
4063                                 }
4064
4065                                 return;
4066                         }
4067                 }
4068
4069                 public override Size PictureBoxDefaultSize {
4070                         get {
4071                                 return new Size (100, 50);
4072                         }
4073                 }
4074                 #endregion      // PictureBox
4075
4076                 #region PrintPreviewControl
4077                 public override int PrintPreviewControlPadding {
4078                         get { return 8; }
4079                 }
4080
4081                 public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview)
4082                 {
4083                         int page_width, page_height;
4084                         int padding = PrintPreviewControlPadding;
4085                         PreviewPageInfo[] pis = preview.page_infos;
4086
4087                         if (preview.AutoZoom) {
4088                                 int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding;
4089                                 int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding;
4090
4091                                 float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height;
4092
4093                                 /* try to lay things out using the width to determine the size */
4094                                 page_width = width_available / preview.Columns;
4095                                 page_height = (int)(page_width / image_ratio);
4096
4097                                 /* does the height fit? */
4098                                 if (page_height * (preview.Rows + 1) > height_available) {
4099                                         /* no, lay things out via the height */
4100                                         page_height = height_available / (preview.Rows + 1);
4101                                         page_width = (int)(page_height * image_ratio);
4102                                 }
4103                         }
4104                         else {
4105                                 page_width = (int)(pis[0].Image.Width * preview.Zoom);
4106                                 page_height = (int)(pis[0].Image.Height * preview.Zoom);
4107                         }
4108
4109                         return new Size (page_width, page_height);
4110                 }
4111
4112                 public override void PrintPreviewControlPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size)
4113                 {
4114                         int padding = 8;
4115                         PreviewPageInfo[] pis = preview.page_infos;
4116                         if (pis == null)
4117                                 return;
4118
4119                         int page_x, page_y;
4120
4121                         int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding;
4122                         int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding;
4123
4124                         Rectangle viewport = preview.ViewPort;
4125
4126                         pe.Graphics.Clip = new Region (viewport);
4127
4128                         /* center things if we can */
4129                         int off_x = viewport.Width / 2 - width / 2;
4130                         if (off_x < 0) off_x = 0;
4131                         int off_y = viewport.Height / 2 - height / 2;
4132                         if (off_y < 0) off_y = 0;
4133
4134                         page_y = off_y + padding - preview.vbar_value;
4135
4136                         if (preview.StartPage > 0) {
4137                                 int p = preview.StartPage - 1;
4138                                 for (int py = 0; py < preview.Rows + 1; py ++) {
4139                                         page_x = off_x + padding - preview.hbar_value;
4140                                         for (int px = 0; px < preview.Columns; px ++) {
4141                                                 if (p >= pis.Length)
4142                                                         continue;
4143                                                 Image image = preview.image_cache[p];
4144                                                 if (image == null)
4145                                                         image = pis[p].Image;
4146                                                 Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size);
4147
4148                                                 pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
4149
4150                                                 page_x += padding + page_size.Width;
4151                                                 p++;
4152                                         }
4153                                         page_y += padding + page_size.Height;
4154                                 }
4155                         }
4156                 }
4157                 #endregion      // PrintPreviewControl
4158
4159                 #region ProgressBar
4160                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) 
4161                 {
4162                         Rectangle client_area = ctrl.client_area;
4163                         
4164                         /* Draw border */
4165                         CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl);
4166                         
4167                         /* Draw Blocks */
4168                         int draw_mode = 0;
4169                         int max_blocks = int.MaxValue;
4170                         int start_pixel = client_area.X;
4171 #if NET_2_0
4172                         draw_mode = (int) ctrl.Style;
4173 #endif
4174                         switch (draw_mode) {
4175 #if NET_2_0
4176                         case 1: { // Continuous
4177                                 int pixels_to_draw;
4178                                 pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1))));
4179                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
4180                                 break;
4181                         }
4182                         case 2: // Marquee
4183                                 if (XplatUI.ThemesEnabled) {
4184                                         int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds;
4185                                         double percent_done = (double) ms_diff % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
4186                                         max_blocks = 5;
4187                                         start_pixel = client_area.X + (int) (client_area.Width * percent_done);
4188                                 }
4189                                 
4190                                 goto case 0;
4191 #endif
4192                         case 0:
4193                         default:  // Blocks
4194                                 Rectangle block_rect;
4195                                 int space_betweenblocks = 2;
4196                                 int block_width;
4197                                 int increment;
4198                                 int barpos_pixels;
4199                                 int block_count = 0;
4200                                 
4201                                 block_width = (client_area.Height * 2) / 3;
4202                                 barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)));
4203                                 increment = block_width + space_betweenblocks;
4204                                 
4205                                 block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
4206                                 while (true) {
4207                                         if (max_blocks != int.MaxValue) {
4208                                                 if (block_count >= max_blocks)
4209                                                         break;
4210                                                 if (block_rect.X > client_area.Width)
4211                                                         block_rect.X -= client_area.Width;
4212                                         } else {
4213                                                 if ((block_rect.X - client_area.X) >= barpos_pixels)
4214                                                         break;
4215                                         }
4216                                         
4217                                         if (clip_rect.IntersectsWith (block_rect) == true) {                            
4218                                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), block_rect);
4219                                         }                               
4220                                         
4221                                         block_rect.X  += increment;
4222                                         block_count++;
4223                                 }
4224                                 break;
4225                         
4226                         }
4227                 }
4228                 
4229                 public override Size ProgressBarDefaultSize {
4230                         get {
4231                                 return new Size (100, 23);
4232                         }
4233                 }
4234
4235                 #endregion      // ProgressBar
4236
4237                 #region RadioButton
4238                 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
4239                         StringFormat    text_format;
4240                         Rectangle       client_rectangle;
4241                         Rectangle       text_rectangle;
4242                         Rectangle       radiobutton_rectangle;
4243                         int             radiobutton_size = 13;
4244                         int     radiobutton_space = 4;
4245
4246                         client_rectangle = radio_button.ClientRectangle;
4247                         text_rectangle = client_rectangle;
4248                         radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
4249
4250                         text_format = new StringFormat();
4251                         text_format.Alignment = StringAlignment.Near;
4252                         text_format.LineAlignment = StringAlignment.Center;
4253                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
4254
4255                         /* Calculate the position of text and checkbox rectangle */
4256                         if (radio_button.appearance!=Appearance.Button) {
4257                                 switch(radio_button.radiobutton_alignment) {
4258                                 case ContentAlignment.BottomCenter: {
4259                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4260                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4261                                         text_rectangle.X=client_rectangle.X;
4262                                         text_rectangle.Width=client_rectangle.Width;
4263                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4264                                         break;
4265                                 }
4266
4267                                 case ContentAlignment.BottomLeft: {
4268                                         radiobutton_rectangle.X=client_rectangle.Left;
4269                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4270                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4271                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;                                 
4272                                         break;
4273                                 }
4274
4275                                 case ContentAlignment.BottomRight: {
4276                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4277                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4278                                         text_rectangle.X=client_rectangle.X;
4279                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4280                                         break;
4281                                 }
4282
4283                                 case ContentAlignment.MiddleCenter: {
4284                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4285                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4286                                         text_rectangle.X=client_rectangle.X;
4287                                         text_rectangle.Width=client_rectangle.Width;
4288                                         break;
4289                                 }
4290
4291                                 default:
4292                                 case ContentAlignment.MiddleLeft: {
4293                                         radiobutton_rectangle.X=client_rectangle.Left;
4294                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4295                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4296                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4297                                         break;
4298                                 }
4299
4300                                 case ContentAlignment.MiddleRight: {
4301                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4302                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4303                                         text_rectangle.X=client_rectangle.X;
4304                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4305                                         break;
4306                                 }
4307
4308                                 case ContentAlignment.TopCenter: {
4309                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4310                                         radiobutton_rectangle.Y=client_rectangle.Top;
4311                                         text_rectangle.X=client_rectangle.X;
4312                                         text_rectangle.Y=radiobutton_size+radiobutton_space;
4313                                         text_rectangle.Width=client_rectangle.Width;
4314                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4315                                         break;
4316                                 }
4317
4318                                 case ContentAlignment.TopLeft: {
4319                                         radiobutton_rectangle.X=client_rectangle.Left;
4320                                         radiobutton_rectangle.Y=client_rectangle.Top;
4321                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4322                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4323                                         break;
4324                                 }
4325
4326                                 case ContentAlignment.TopRight: {
4327                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4328                                         radiobutton_rectangle.Y=client_rectangle.Top;
4329                                         text_rectangle.X=client_rectangle.X;
4330                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4331                                         break;
4332                                 }
4333                                 }
4334                         } else {
4335                                 text_rectangle.X=client_rectangle.X;
4336                                 text_rectangle.Width=client_rectangle.Width;
4337                         }
4338                         
4339                         /* Set the horizontal alignment of our text */
4340                         switch(radio_button.text_alignment) {
4341                                 case ContentAlignment.BottomLeft:
4342                                 case ContentAlignment.MiddleLeft:
4343                                 case ContentAlignment.TopLeft: {
4344                                         text_format.Alignment=StringAlignment.Near;
4345                                         break;
4346                                 }
4347
4348                                 case ContentAlignment.BottomCenter:
4349                                 case ContentAlignment.MiddleCenter:
4350                                 case ContentAlignment.TopCenter: {
4351                                         text_format.Alignment=StringAlignment.Center;
4352                                         break;
4353                                 }
4354
4355                                 case ContentAlignment.BottomRight:
4356                                 case ContentAlignment.MiddleRight:
4357                                 case ContentAlignment.TopRight: {
4358                                         text_format.Alignment=StringAlignment.Far;
4359                                         break;
4360                                 }
4361                         }
4362
4363                         /* Set the vertical alignment of our text */
4364                         switch(radio_button.text_alignment) {
4365                                 case ContentAlignment.TopLeft: 
4366                                 case ContentAlignment.TopCenter: 
4367                                 case ContentAlignment.TopRight: {
4368                                         text_format.LineAlignment=StringAlignment.Near;
4369                                         break;
4370                                 }
4371
4372                                 case ContentAlignment.BottomLeft:
4373                                 case ContentAlignment.BottomCenter:
4374                                 case ContentAlignment.BottomRight: {
4375                                         text_format.LineAlignment=StringAlignment.Far;
4376                                         break;
4377                                 }
4378
4379                                 case ContentAlignment.MiddleLeft:
4380                                 case ContentAlignment.MiddleCenter:
4381                                 case ContentAlignment.MiddleRight: {
4382                                         text_format.LineAlignment=StringAlignment.Center;
4383                                         break;
4384                                 }
4385                         }
4386
4387                         ButtonState state = ButtonState.Normal;
4388                         if (radio_button.FlatStyle == FlatStyle.Flat) {
4389                                 state |= ButtonState.Flat;
4390                         }
4391                         
4392                         if (radio_button.Checked) {
4393                                 state |= ButtonState.Checked;
4394                         }
4395                         
4396                         if (!radio_button.Enabled) {
4397                                 state |= ButtonState.Inactive;
4398                         }
4399
4400                         // Start drawing
4401                         RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
4402                         
4403                         if ((radio_button.image != null) || (radio_button.image_list != null))
4404                                 ButtonBase_DrawImage(radio_button, dc);
4405                         
4406                         RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
4407
4408                         if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) {
4409                                 SizeF text_size = dc.MeasureString (radio_button.Text, radio_button.Font);
4410                                 
4411                                 Rectangle focus_rect = Rectangle.Empty;
4412                                 focus_rect.X = text_rectangle.X;
4413                                 focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
4414                                 focus_rect.Size = text_size.ToSize ();
4415
4416                                 RadioButton_DrawFocus (radio_button, dc, focus_rect);
4417                         }
4418                         
4419                         text_format.Dispose ();
4420                 }
4421
4422                 protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
4423                 {
4424                         dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle);
4425                         
4426                         if (radio_button.appearance==Appearance.Button) {
4427                                 ButtonBase_DrawButton (radio_button, dc);
4428                                 
4429                                 if ((radio_button.Focused) && radio_button.Enabled)
4430                                         ButtonBase_DrawFocus(radio_button, dc);
4431                         } else {
4432                                 // establish if we are rendering a flat style of some sort
4433                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
4434                                         DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
4435                                 } else {
4436                                         CPDrawRadioButton(dc, radiobutton_rectangle, state);
4437                                 }
4438                         }
4439                 }
4440                 
4441                 protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
4442                 {
4443                         DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc, 
4444                                                           text_format, radio_button.Appearance, radio_button.Checked);
4445                 }
4446                 
4447                 protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
4448                 {
4449                         DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
4450                 }
4451                 
4452                 
4453                 // renders a radio button with the Flat and Popup FlatStyle
4454                 protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
4455                 {
4456                         int     lineWidth;
4457                         
4458                         if (radio_button.Enabled) {
4459                                 
4460                                 // draw the outer flatstyle arcs
4461                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
4462                                         graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359);
4463                                         
4464                                         // fill in the area depending on whether or not the mouse is hovering
4465                                         if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) {
4466                                                 graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4467                                         } else {
4468                                                 graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4469                                         }
4470                                 } else {
4471                                         // must be a popup radio button
4472                                         // fill the control
4473                                         graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359);
4474
4475                                         if (radio_button.is_entered || radio_button.Capture) {
4476                                                 // draw the popup 3d button knob
4477                                                 graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
4478
4479                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180);
4480                                                 graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180);
4481                                                 
4482                                         } else {
4483                                                 // just draw lighter flatstyle outer circle
4484                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);                                           
4485                                         }                                                                               
4486                                 }
4487                         } else {
4488                                 // disabled
4489                                 // fill control background color regardless of actual backcolor
4490                                 graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4491                                 // draw the ark as control dark
4492                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4493                         }
4494
4495                         // draw the check
4496                         if (radio_button.Checked) {
4497                                 lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
4498                                 
4499                                 Pen dot_pen = SystemPens.ControlDarkDark;
4500                                 Brush dot_brush = SystemBrushes.ControlDarkDark;
4501
4502                                 if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) {
4503                                         dot_pen = SystemPens.ControlDark;
4504                                         dot_brush = SystemBrushes.ControlDark;
4505                                 } 
4506                                 
4507                                 if (rectangle.Height >  13) {
4508                                         graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
4509                                 } else {
4510                                         int x_half_pos = (rectangle.Width / 2) + rectangle.X;
4511                                         int y_half_pos = (rectangle.Height / 2) + rectangle.Y;
4512                                         
4513                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
4514                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
4515                                         
4516                                         graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
4517                                         graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
4518                                 }
4519                         }
4520                 }
4521
4522                 public override Size RadioButtonDefaultSize {
4523                         get {
4524                                 return new Size (104,24);
4525                         }
4526                 }
4527
4528 #if NET_2_0
4529                 public override void DrawRadioButton (Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
4530                 {
4531                         // Draw Button Background
4532                         if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) {
4533                                 glyphArea.Height -= 2;
4534                                 glyphArea.Width -= 2;
4535                         }
4536                         
4537                         DrawRadioButtonGlyph (g, rb, glyphArea);
4538
4539                         // If we have an image, draw it
4540                         if (imageBounds.Size != Size.Empty)
4541                                 DrawRadioButtonImage (g, rb, imageBounds);
4542
4543                         if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty)
4544                                 DrawRadioButtonFocus (g, rb, textBounds);
4545
4546                         // If we have text, draw it
4547                         if (textBounds != Rectangle.Empty)
4548                                 DrawRadioButtonText (g, rb, textBounds);
4549                 }
4550
4551                 public virtual void DrawRadioButtonGlyph (Graphics g, RadioButton rb, Rectangle glyphArea)
4552                 {
4553                         if (rb.Pressed)
4554                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked);
4555                         else if (rb.InternalSelected)
4556                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4557                         else if (rb.Entered)
4558                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked);
4559                         else if (!rb.Enabled)
4560                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked);
4561                         else
4562                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4563                 }
4564
4565                 public virtual void DrawRadioButtonFocus (Graphics g, RadioButton rb, Rectangle focusArea)
4566                 {
4567                         ControlPaint.DrawFocusRectangle (g, focusArea);
4568                 }
4569
4570                 public virtual void DrawRadioButtonImage (Graphics g, RadioButton rb, Rectangle imageBounds)
4571                 {
4572                         if (rb.Enabled)
4573                                 g.DrawImage (rb.Image, imageBounds);
4574                         else
4575                                 CPDrawImageDisabled (g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
4576                 }
4577
4578                 public virtual void DrawRadioButtonText (Graphics g, RadioButton rb, Rectangle textBounds)
4579                 {
4580                         if (rb.Enabled)
4581                                 TextRenderer.DrawTextInternal (g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4582                         else
4583                                 DrawStringDisabled20 (g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4584                 }
4585
4586                 public override Size CalculateRadioButtonAutoSize (RadioButton rb)
4587                 {
4588                         Size ret_size = Size.Empty;
4589                         Size text_size = TextRenderer.MeasureTextInternal (rb.Text, rb.Font, rb.UseCompatibleTextRendering);
4590                         Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size;
4591
4592                         // Pad the text size
4593                         if (rb.Text.Length != 0) {
4594                                 text_size.Height += 4;
4595                                 text_size.Width += 4;
4596                         }
4597
4598                         switch (rb.TextImageRelation) {
4599                                 case TextImageRelation.Overlay:
4600                                         ret_size.Height = Math.Max (rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
4601                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4602                                         break;
4603                                 case TextImageRelation.ImageAboveText:
4604                                 case TextImageRelation.TextAboveImage:
4605                                         ret_size.Height = text_size.Height + image_size.Height;
4606                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4607                                         break;
4608                                 case TextImageRelation.ImageBeforeText:
4609                                 case TextImageRelation.TextBeforeImage:
4610                                         ret_size.Height = Math.Max (text_size.Height, image_size.Height);
4611                                         ret_size.Width = text_size.Width + image_size.Width;
4612                                         break;
4613                         }
4614
4615                         // Pad the result
4616                         ret_size.Height += (rb.Padding.Vertical);
4617                         ret_size.Width += (rb.Padding.Horizontal) + 15;
4618
4619                         // There seems to be a minimum height
4620                         if (ret_size.Height == rb.Padding.Vertical)
4621                                 ret_size.Height += 14;
4622
4623                         return ret_size;
4624                 }
4625
4626                 public override void CalculateRadioButtonTextAndImageLayout (ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
4627                 {
4628                         CalculateCheckBoxTextAndImageLayout (b, offset, out glyphArea, out textRectangle, out imageRectangle);
4629                 }
4630 #endif
4631                 #endregion      // RadioButton
4632
4633                 #region ScrollBar
4634                 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
4635                 {
4636                         int             scrollbutton_width = bar.scrollbutton_width;
4637                         int             scrollbutton_height = bar.scrollbutton_height;
4638                         Rectangle       first_arrow_area;
4639                         Rectangle       second_arrow_area;                      
4640                         Rectangle       thumb_pos;
4641                         
4642                         thumb_pos = bar.ThumbPos;
4643
4644                         if (bar.vert) {
4645                                 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
4646                                 bar.FirstArrowArea = first_arrow_area;
4647
4648                                 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
4649                                 bar.SecondArrowArea = second_arrow_area;
4650
4651                                 thumb_pos.Width = bar.Width;
4652                                 bar.ThumbPos = thumb_pos;
4653
4654                                 Brush VerticalBrush;
4655                                 /* Background, upper track */
4656                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4657                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4658                                 else
4659                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4660                                 Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom);
4661                                 if (clip.IntersectsWith (UpperTrack))
4662                                         dc.FillRectangle (VerticalBrush, UpperTrack);
4663
4664                                 /* Background, lower track */
4665                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4666                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4667                                 else
4668                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4669                                 Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom);
4670                                 if (clip.IntersectsWith (LowerTrack))
4671                                         dc.FillRectangle (VerticalBrush, LowerTrack);
4672
4673                                 /* Buttons */
4674                                 if (clip.IntersectsWith (first_arrow_area))
4675                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
4676                                 if (clip.IntersectsWith (second_arrow_area))
4677                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
4678                         } else {
4679                                 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
4680                                 bar.FirstArrowArea = first_arrow_area;
4681
4682                                 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
4683                                 bar.SecondArrowArea = second_arrow_area;
4684
4685                                 thumb_pos.Height = bar.Height;
4686                                 bar.ThumbPos = thumb_pos;
4687
4688                                 Brush HorizontalBrush;
4689                                 //Background, left track
4690                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4691                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4692                                 else
4693                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4694                                 Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height);
4695                                 if (clip.IntersectsWith (LeftTrack))
4696                                         dc.FillRectangle (HorizontalBrush, LeftTrack);
4697
4698                                 //Background, right track
4699                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4700                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4701                                 else
4702                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4703                                 Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height);
4704                                 if (clip.IntersectsWith (RightTrack))
4705                                         dc.FillRectangle (HorizontalBrush, RightTrack);
4706
4707                                 /* Buttons */
4708                                 if (clip.IntersectsWith (first_arrow_area))
4709                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
4710                                 if (clip.IntersectsWith (second_arrow_area))
4711                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
4712                         }
4713
4714                         /* Thumb */
4715                         ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);                          
4716                 }
4717
4718                 protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
4719                 {
4720                         if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
4721                                 DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
4722                 }
4723
4724                 public override int ScrollBarButtonSize {
4725                         get { return 16; }
4726                 }
4727
4728                 public override bool ScrollBarHasHotElementStyles {
4729                         get {
4730                                 return false;
4731                         }
4732                 }
4733
4734                 public override bool ScrollBarHasPressedThumbStyle {
4735                         get { 
4736                                 return false;
4737                         }
4738                 }
4739
4740                 public override bool ScrollBarHasHoverArrowButtonStyle {
4741                         get {
4742                                 return false;
4743                         }
4744                 }
4745                 #endregion      // ScrollBar
4746
4747                 #region StatusBar
4748                 public  override void DrawStatusBar (Graphics real_dc, Rectangle clip, StatusBar sb) {
4749                         Rectangle area = sb.ClientRectangle;
4750                         int horz_border = 2;
4751                         int vert_border = 2;
4752
4753                         Image backbuffer = new Bitmap (sb.ClientSize.Width, sb.ClientSize.Height, real_dc);
4754                         Graphics dc = Graphics.FromImage (backbuffer);
4755                         
4756                         DrawStatusBarBackground (dc, clip, sb);
4757                         
4758                         if (!sb.ShowPanels && sb.Text != String.Empty) {
4759                                 string text = sb.Text;
4760                                 StringFormat string_format = new StringFormat ();
4761                                 string_format.Trimming = StringTrimming.Character;
4762                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
4763                                 
4764                                 if (text.Length > 127)
4765                                         text = text.Substring (0, 127);
4766
4767                                 if (text [0] == '\t') {
4768                                         string_format.Alignment = StringAlignment.Center;
4769                                         text = text.Substring (1);
4770                                         if (text [0] == '\t') {
4771                                                 string_format.Alignment = StringAlignment.Far;
4772                                                 text = text.Substring (1);
4773                                         }
4774                                 }
4775                 
4776                                 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
4777                                                 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
4778                                 string_format.Dispose ();
4779                         } else if (sb.ShowPanels) {
4780                                 Brush br_forecolor = GetControlForeBrush (sb.ForeColor);
4781                                 int prev_x = area.X + horz_border;
4782                                 int y = area.Y + vert_border;
4783                                 for (int i = 0; i < sb.Panels.Count; i++) {
4784                                         Rectangle pr = new Rectangle (prev_x, y,
4785                                                 sb.Panels [i].Width, area.Height);
4786                                         prev_x += pr.Width + StatusBarHorzGapWidth;
4787                                         if (pr.IntersectsWith (clip))
4788                                                 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
4789                                 }
4790                         }
4791
4792                         if (sb.SizingGrip)
4793                                 DrawStatusBarSizingGrip (dc, clip, sb, area);
4794                         
4795                         real_dc.DrawImage (backbuffer, 0, 0);
4796                         dc.Dispose ();
4797                         backbuffer.Dispose ();
4798
4799                 }
4800
4801                 protected virtual void DrawStatusBarBackground (Graphics dc, Rectangle clip, StatusBar sb)
4802                 {
4803                         bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
4804
4805                         Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
4806                         dc.FillRectangle (brush, clip);
4807                 }
4808
4809                 protected virtual void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area)
4810                 {
4811                         area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16);
4812                         CPDrawSizeGrip (dc, ColorControl, area);
4813                 }
4814
4815                 protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
4816                         Brush br_forecolor, StatusBarPanel panel) {
4817                         int border_size = 3; // this is actually const, even if the border style is none
4818                         int icon_width = 16;
4819                         
4820                         area.Height -= border_size;
4821
4822                         DrawStatusBarPanelBackground (dc, area, panel);
4823
4824                         if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
4825                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
4826                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
4827                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor);
4828                                 panel.Parent.OnDrawItemInternal (e);
4829                                 return;
4830                         }
4831
4832                         if (panel.Text == String.Empty)
4833                                         return;
4834
4835                         string text = panel.Text;
4836                         StringFormat string_format = new StringFormat ();
4837                         string_format.Trimming = StringTrimming.Character;
4838                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4839
4840                         
4841                         if (text [0] == '\t') {
4842                                 string_format.Alignment = StringAlignment.Center;
4843                                 text = text.Substring (1);
4844                                 if (text [0] == '\t') {
4845                                         string_format.Alignment = StringAlignment.Far;
4846                                         text = text.Substring (1);
4847                                 }
4848                         }
4849
4850                         Rectangle string_rect = Rectangle.Empty;
4851                         int x;
4852                         int len;
4853                         int icon_x = 0;
4854                         int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1;
4855
4856                         switch (panel.Alignment) {
4857                         case HorizontalAlignment.Right:
4858                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4859                                 x = area.Right - len - 4;
4860                                 string_rect = new Rectangle (x, y, 
4861                                                 area.Right - x - border_size,
4862                                                 area.Bottom - y - border_size);
4863                                 if (panel.Icon != null) {
4864                                         icon_x = x - icon_width - 2;
4865                                 }
4866                                 break;
4867                         case HorizontalAlignment.Center:
4868                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4869                                 x = area.Left + ((panel.Width - len) / 2);
4870                                 
4871                                 string_rect = new Rectangle (x, y, 
4872                                                 area.Right - x - border_size,
4873                                                 area.Bottom - y - border_size);
4874
4875                                 if (panel.Icon != null) {
4876                                         icon_x = x - icon_width - 2;
4877                                 }
4878                                 break;
4879
4880                                 
4881                         default:
4882                                 int left = area.Left + border_size;;
4883                                 if (panel.Icon != null) {
4884                                         icon_x = area.Left + 2;
4885                                         left = icon_x + icon_width + 2;
4886                                 }
4887
4888                                 x = left;
4889                                 string_rect = new Rectangle (x, y, 
4890                                                 area.Right - x - border_size,
4891                                                 area.Bottom - y - border_size);
4892                                 break;
4893                         }
4894
4895                         RectangleF clip_bounds = dc.ClipBounds;
4896                         dc.SetClip (area);
4897                         dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format);                      
4898                         dc.SetClip (clip_bounds);
4899
4900                         if (panel.Icon != null) {
4901                                 dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width));
4902                         }
4903                 }
4904
4905                 protected virtual void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel)
4906                 {
4907                         if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
4908                                 Border3DStyle border_style = Border3DStyle.SunkenOuter;
4909                                 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
4910                                         border_style = Border3DStyle.RaisedInner;
4911                                         
4912                                 CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor);
4913                         }
4914                 }
4915
4916                 public override int StatusBarSizeGripWidth {
4917                         get { return 15; }
4918                 }
4919
4920                 public override int StatusBarHorzGapWidth {
4921                         get { return 3; }
4922                 }
4923
4924                 public override Size StatusBarDefaultSize {
4925                         get {
4926                                 return new Size (100, 22);
4927                         }
4928                 }
4929                 #endregion      // StatusBar
4930
4931                 #region TabControl
4932
4933                 #region TabControl settings
4934
4935                 public override Size TabControlDefaultItemSize {
4936                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultItemSize; }
4937                 }
4938
4939                 public override Point TabControlDefaultPadding {
4940                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultPadding; }
4941                 }
4942
4943                 public override int TabControlMinimumTabWidth {
4944                         get { return ThemeElements.CurrentTheme.TabControlPainter.MinimumTabWidth; }
4945                 }
4946
4947                 public override Rectangle TabControlSelectedDelta {
4948                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedTabDelta; }
4949                 }
4950
4951                 public override int TabControlSelectedSpacing {
4952                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedSpacing; }
4953                 }
4954                 
4955                 public override int TabPanelOffsetX {
4956                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.X; }
4957                 }
4958                 
4959                 public override int TabPanelOffsetY {
4960                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.Y; }
4961                 }
4962
4963                 public override int TabControlColSpacing {
4964                         get { return ThemeElements.CurrentTheme.TabControlPainter.ColSpacing; }
4965                 }
4966
4967                 public override Point TabControlImagePadding {
4968                         get { return ThemeElements.CurrentTheme.TabControlPainter.ImagePadding; }
4969                 }
4970
4971                 public override int TabControlScrollerWidth {
4972                         get {return ThemeElements.CurrentTheme.TabControlPainter.ScrollerWidth; }
4973                 }
4974
4975
4976                 public override Size TabControlGetSpacing (TabControl tab) 
4977                 {
4978                         try {
4979                                 return ThemeElements.CurrentTheme.TabControlPainter.RowSpacing (tab);
4980                         } catch {
4981                                 throw new Exception ("Invalid Appearance value: " + tab.Appearance);
4982                         }
4983                 }
4984                 #endregion
4985
4986                 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
4987                 {
4988                         ThemeElements.CurrentTheme.TabControlPainter.Draw (dc, area, tab);
4989                 }
4990
4991                 public override Rectangle TabControlGetLeftScrollRect (TabControl tab)
4992                 {
4993                         return ThemeElements.CurrentTheme.TabControlPainter.GetLeftScrollRect (tab);
4994                 }
4995
4996                 public override Rectangle TabControlGetRightScrollRect (TabControl tab)
4997                 {
4998                         return ThemeElements.CurrentTheme.TabControlPainter.GetRightScrollRect (tab);
4999                 }
5000
5001                 public override Rectangle TabControlGetDisplayRectangle (TabControl tab)
5002                 {
5003                         return ThemeElements.CurrentTheme.TabControlPainter.GetDisplayRectangle (tab);
5004                 }
5005
5006                 public override Rectangle TabControlGetPanelRect (TabControl tab)
5007                 {
5008                         return ThemeElements.CurrentTheme.TabControlPainter.GetTabPanelRect (tab);
5009                 }
5010
5011                 #endregion
5012
5013                 #region TextBox
5014                 public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea)
5015                 {
5016                         if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) {
5017                                 g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea);
5018                         } else {
5019                                 g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea);
5020                         }
5021                 }
5022
5023                 public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m)
5024                 {
5025                         return false;
5026                 }
5027
5028                 public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase)
5029                 {
5030                         return true;
5031                 }
5032                 #endregion
5033
5034                 #region ToolBar
5035                 public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) 
5036                 {
5037                         StringFormat format = new StringFormat ();
5038                         format.Trimming = StringTrimming.EllipsisCharacter;
5039                         format.LineAlignment = StringAlignment.Center;
5040                         if (control.ShowKeyboardCuesInternal)
5041                                 format.HotkeyPrefix = HotkeyPrefix.Show;
5042                         else
5043                                 format.HotkeyPrefix = HotkeyPrefix.Hide;
5044
5045                         if (control.TextAlign == ToolBarTextAlign.Underneath)
5046                                 format.Alignment = StringAlignment.Center;
5047                         else
5048                                 format.Alignment = StringAlignment.Near;
5049 #if !NET_2_0
5050                         if (control is PropertyGrid.PropertyToolBar) {
5051                                 dc.FillRectangle (ResPool.GetSolidBrush(control.BackColor), clip_rectangle);
5052                                 
5053                                 if (clip_rectangle.X == 0) {
5054                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.X, control.Bottom);
5055                                 }
5056
5057                                 if (clip_rectangle.Y < 2) {
5058                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
5059                                 }
5060
5061                                 if (clip_rectangle.Bottom == control.Bottom) {
5062                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, clip_rectangle.Bottom - 1, clip_rectangle.Right, clip_rectangle.Bottom - 1);
5063                                 }
5064
5065                                 if (clip_rectangle.Right == control.Right) {
5066                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.Right - 1, 1, clip_rectangle.Right - 1, control.Bottom - 1);
5067                                 }
5068                         } else {
5069 #endif
5070                                 if (control.Appearance != ToolBarAppearance.Flat || control.Parent == null) {
5071                                         dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5072                                 }
5073
5074                                 if (control.Divider && clip_rectangle.Y < 2) {
5075                                         if (clip_rectangle.Y < 1) {
5076                                                 dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
5077                                         }
5078                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
5079                                 }
5080 #if !NET_2_0
5081                         }
5082 #endif
5083
5084                         foreach (ToolBarItem item in control.items)
5085                                 if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
5086                                         DrawToolBarButton (dc, control, item, format);
5087
5088                         format.Dispose ();
5089                 }
5090
5091                 protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5092                 {
5093                         bool is_flat = (control.Appearance == ToolBarAppearance.Flat);
5094                         
5095                         DrawToolBarButtonBorder (dc, item, is_flat);
5096
5097                         switch (item.Button.Style) {
5098                         case ToolBarButtonStyle.DropDownButton:
5099                                 if (control.DropDownArrows)
5100                                         DrawToolBarDropDownArrow (dc, item, is_flat);
5101                                 DrawToolBarButtonContents (dc, control, item, format);
5102                                 break;
5103
5104                         case ToolBarButtonStyle.Separator:
5105                                 if (is_flat)
5106                                         DrawToolBarSeparator (dc, item);
5107                                 break;
5108
5109                         case ToolBarButtonStyle.ToggleButton:
5110                                 DrawToolBarToggleButtonBackground (dc, item);
5111                                 DrawToolBarButtonContents (dc, control, item, format);
5112                                 break;
5113
5114                         default:
5115                                 DrawToolBarButtonContents (dc, control, item, format);
5116                                 break;
5117                         }
5118                 }
5119
5120                 const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom;
5121
5122                 protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat)
5123                 {
5124                         if (item.Button.Style == ToolBarButtonStyle.Separator)
5125                                 return;
5126
5127                         Border3DStyle style;
5128
5129                         if (is_flat) {
5130                                 if (item.Button.Pushed || item.Pressed)
5131                                         style = Border3DStyle.SunkenOuter;
5132                                 else if (item.Hilight)
5133                                         style = Border3DStyle.RaisedInner;
5134                                 else
5135                                         return;
5136
5137                         } else {
5138                                 if (item.Button.Pushed || item.Pressed)
5139                                         style = Border3DStyle.Sunken;
5140                                 else 
5141                                         style = Border3DStyle.Raised;
5142                         }
5143                         
5144                         Rectangle rect = item.Rectangle;
5145                         if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat)
5146                                 rect.Width -= ToolBarDropDownWidth;
5147
5148                         CPDrawBorder3D (dc, rect, style, all_sides);
5149                 }
5150
5151                 protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item)
5152                 {
5153                         Rectangle area = item.Rectangle;
5154                         int offset = (int) SystemPens.Control.Width + 1;
5155                         dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom);
5156                         dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom);
5157                 }
5158
5159                 protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item)
5160                 {
5161                         Brush brush;
5162                         Rectangle area = item.Rectangle;
5163                         area.X += ToolBarImageGripWidth;
5164                         area.Y += ToolBarImageGripWidth;
5165                         area.Width -= 2 * ToolBarImageGripWidth;
5166                         area.Height -= 2 * ToolBarImageGripWidth;
5167                         
5168                         if (item.Button.Pushed)
5169                                 brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight);
5170                         else if (item.Button.PartialPush)
5171                                 brush = SystemBrushes.ControlLight;
5172                         else
5173                                 brush = SystemBrushes.Control;
5174                          
5175                         dc.FillRectangle (brush, area);
5176                 }
5177
5178                 protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat)
5179                 {
5180                         Rectangle rect = item.Rectangle;
5181                         rect.X = item.Rectangle.Right - ToolBarDropDownWidth;
5182                         rect.Width = ToolBarDropDownWidth;
5183                         
5184                         if (is_flat) {
5185                                 if (item.DDPressed)
5186                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5187                                 else if (item.Button.Pushed || item.Pressed)
5188                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5189                                 else if (item.Hilight)
5190                                         CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides);
5191                         } else {
5192                                 if (item.DDPressed)
5193                                         CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides);
5194                                 else if (item.Button.Pushed || item.Pressed)
5195                                         CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides);
5196                                 else
5197                                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
5198                         }
5199                         
5200                         PointF [] vertices = new PointF [3];
5201                         PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2));
5202                         
5203                         // Increase vertical and horizontal position by 1 when button is pressed
5204                         if (item.Pressed || item.Button.Pushed || item.DDPressed) {
5205                             ddCenter.X += 1;
5206                             ddCenter.Y += 1;
5207                         }
5208                         
5209                         vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5210                         vertices [0].Y = ddCenter.Y;
5211                         vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5212                         vertices [1].Y = ddCenter.Y;
5213                         vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
5214                         vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight;
5215                         dc.FillPolygon (SystemBrushes.ControlText, vertices);
5216                 }
5217
5218                 protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5219                 {
5220                         if (item.Button.Image != null) {
5221                                 int x = item.ImageRectangle.X + ToolBarImageGripWidth;
5222                                 int y = item.ImageRectangle.Y + ToolBarImageGripWidth;
5223                                 
5224                                 // Increase vertical and horizontal position by 1 when button is pressed
5225                                 if (item.Pressed || item.Button.Pushed) {
5226                                     x += 1;
5227                                     y += 1;
5228                                 }
5229                                 
5230                                 if (item.Button.Enabled)
5231                                         dc.DrawImage (item.Button.Image, x, y);
5232                                 else 
5233                                         CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl);
5234                         }
5235
5236                         Rectangle text_rect = item.TextRectangle;
5237                         if (text_rect.Width <= 0 || text_rect.Height <= 0)
5238                                 return;
5239
5240                         if (item.Pressed || item.Button.Pushed) {
5241                                 text_rect.X += 1;
5242                                 text_rect.Y += 1;
5243                         }
5244                         
5245                         if (item.Button.Enabled)
5246                                 dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
5247                         else
5248                                 CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format);
5249                 }
5250
5251                 // Grip width for the ToolBar
5252                 public override int ToolBarGripWidth {
5253                         get { return 2;}
5254                 }
5255
5256                 // Grip width for the Image on the ToolBarButton
5257                 public override int ToolBarImageGripWidth {
5258                         get { return 2;}
5259                 }
5260
5261                 // width of the separator
5262                 public override int ToolBarSeparatorWidth {
5263                         get { return 4; }
5264                 }
5265
5266                 // width of the dropdown arrow rect
5267                 public override int ToolBarDropDownWidth {
5268                         get { return 13; }
5269                 }
5270
5271                 // width for the dropdown arrow on the ToolBarButton
5272                 public override int ToolBarDropDownArrowWidth {
5273                         get { return 5;}
5274                 }
5275
5276                 // height for the dropdown arrow on the ToolBarButton
5277                 public override int ToolBarDropDownArrowHeight {
5278                         get { return 3;}
5279                 }
5280
5281                 public override Size ToolBarDefaultSize {
5282                         get {
5283                                 return new Size (100, 42);
5284                         }
5285                 }
5286
5287                 public override bool ToolBarHasHotElementStyles (ToolBar toolBar)
5288                 {
5289                         return toolBar.Appearance == ToolBarAppearance.Flat;
5290                 }
5291
5292                 public override bool ToolBarHasHotCheckedElementStyles {
5293                         get {
5294                                 return false;
5295                         }
5296                 }
5297                 #endregion      // ToolBar
5298
5299                 #region ToolTip
5300                 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5301                 {
5302                         ToolTipDrawBackground (dc, clip_rectangle, control);
5303
5304                         Rectangle text_rect = Rectangle.Inflate (control.ClientRectangle, -2, -1);
5305 #if NET_2_0
5306                         Color foreground = control.ForeColor;
5307 #else
5308                         Color foreground = this.ColorInfoText;
5309 #endif
5310                         TextFormatFlags flags = TextFormatFlags.HidePrefix | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter;
5311                         TextRenderer.DrawTextInternal (dc, control.Text, control.Font, text_rect, foreground, flags, false);
5312                 }
5313
5314                 protected virtual void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5315                 {
5316 #if NET_2_0
5317                         Brush back_brush = ResPool.GetSolidBrush (control.BackColor);;
5318 #else
5319                         Brush back_brush = SystemBrushes.Info;
5320 #endif
5321                         dc.FillRectangle (back_brush, control.ClientRectangle);
5322                         dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1);
5323                 }
5324
5325                 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text)
5326                 {
5327                         Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false);
5328
5329                         size.Width += 4;
5330                         size.Height += 3;
5331                         
5332                         return size;
5333                 }
5334                 
5335                 public override bool ToolTipTransparentBackground {
5336                         get {
5337                                 return false;
5338                         }
5339                 }
5340                 #endregion      // ToolTip
5341
5342                 #region BalloonWindow
5343 #if NET_2_0
5344                 NotifyIcon.BalloonWindow balloon_window;
5345                 
5346                 public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
5347                 {
5348                         Control control = Control.FromHandle(handle);
5349                         
5350                         if (control == null)
5351                                 return;
5352
5353                         if (balloon_window != null) {
5354                                 balloon_window.Close ();
5355                                 balloon_window.Dispose ();
5356                         }
5357
5358                         balloon_window = new NotifyIcon.BalloonWindow (handle);
5359                         balloon_window.Title = title;
5360                         balloon_window.Text = text;
5361                         balloon_window.Icon = icon;
5362                         balloon_window.Timeout = timeout;
5363                         balloon_window.Show ();
5364                 }
5365
5366                 private const int balloon_iconsize = 16;
5367                 private const int balloon_bordersize = 8; 
5368                 
5369                 public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) 
5370                 {
5371                         Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText);
5372                         Rectangle rect = control.ClientRectangle;
5373                         int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
5374                         
5375                         // Rectangle borders and background.
5376                         dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
5377                         dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1);
5378
5379                         // Icon
5380                         Image image;
5381                         switch (control.Icon) {
5382                                 case ToolTipIcon.Info: {
5383                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
5384                                         break;
5385                                 }
5386
5387                                 case ToolTipIcon.Warning: {
5388                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
5389                                         break;
5390                                 }
5391
5392                                 case ToolTipIcon.Error: {
5393                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
5394                                         break;
5395                                 }
5396                                 
5397                                 default: {
5398                                         image = null;
5399                                         break;
5400                                 }
5401                         }
5402
5403                         if (control.Icon != ToolTipIcon.None)
5404                                 dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize));
5405                         
5406                         // Title
5407                         Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0), 
5408                                                                                                 rect.Y + balloon_bordersize, 
5409                                                                                                 rect.Width - ((3 * balloon_bordersize) + iconsize), 
5410                                                                                                 rect.Height - (2 * balloon_bordersize));
5411                         
5412                         Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
5413                         dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
5414                         
5415                         // Text
5416                         Rectangle textrect = new Rectangle (rect.X + balloon_bordersize, 
5417                                                                                                 rect.Y + balloon_bordersize, 
5418                                                                                                 rect.Width - (2 * balloon_bordersize), 
5419                                                                                                 rect.Height - (2 * balloon_bordersize));
5420
5421                         StringFormat textformat = control.Format;
5422                         textformat.LineAlignment = StringAlignment.Far;
5423                         dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
5424                 }
5425
5426                 public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
5427                 {
5428                         Rectangle deskrect = Screen.GetWorkingArea (control);
5429                         SizeF maxsize = new SizeF (250, 200);
5430
5431                         SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
5432                         SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
5433                         
5434                         if (titlesize.Height < balloon_iconsize)
5435                                 titlesize.Height = balloon_iconsize;
5436                         
5437                         Rectangle rect = new Rectangle ();
5438                         rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
5439                         rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize);
5440                         rect.X = deskrect.Width - rect.Width - 2;
5441                         rect.Y = deskrect.Height - rect.Height - 2;
5442                         
5443                         return rect;
5444                 }
5445 #endif
5446                 #endregion      // BalloonWindow
5447
5448                 #region TrackBar
5449                 public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb)
5450                 {
5451                         int result = tb.Value;
5452                         int value_pos = tb.Value;
5453                         float pixels_betweenticks;
5454                         Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty;
5455                         Point channel_startpoint = Point.Empty, na_point = Point.Empty;
5456                         
5457                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point);
5458                         
5459                         /* Convert thumb position from mouse position to value*/
5460                         if (tb.Orientation == Orientation.Vertical) {
5461                                 value_pos = (int)Math.Round (((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0);
5462
5463                                 if (value_pos + tb.Minimum > tb.Maximum)
5464                                         value_pos = tb.Maximum - tb.Minimum;
5465                                 else if (value_pos + tb.Minimum < tb.Minimum)
5466                                         value_pos = 0;
5467
5468                                 result = value_pos + tb.Minimum;
5469                         } else {
5470                                 value_pos = (int)Math.Round (((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float) pixels_betweenticks), 0);
5471
5472                                 if (value_pos + tb.Minimum > tb.Maximum)
5473                                         value_pos = tb.Maximum - tb.Minimum;
5474                                 else if (value_pos + tb.Minimum < tb.Minimum)
5475                                         value_pos = 0;
5476
5477                                 result = value_pos + tb.Minimum;
5478                         }
5479                         
5480                         return result;
5481                 }
5482                 
5483                 private void GetTrackBarDrawingInfo (TrackBar tb, out float pixels_betweenticks, out Rectangle thumb_area, out Rectangle thumb_pos, out Point channel_startpoint, out Point bottomtick_startpoint, out Point toptick_startpoint)
5484                 {
5485                         thumb_area = Rectangle.Empty;
5486                         thumb_pos = Rectangle.Empty;
5487                         
5488                         if (tb.Orientation == Orientation.Vertical) {
5489                                 toptick_startpoint = new Point ();
5490                                 bottomtick_startpoint = new Point ();
5491                                 channel_startpoint = new Point ();
5492                                 float pixel_len;
5493                                 const int space_from_right = 8;
5494                                 const int space_from_left = 8;
5495                                 const int space_from_bottom = 11;
5496                                 Rectangle area = tb.ClientRectangle;
5497
5498                                 switch (tb.TickStyle) {
5499                                 case TickStyle.BottomRight:
5500                                 case TickStyle.None:
5501                                         channel_startpoint.Y = 8;
5502                                         channel_startpoint.X = 9;
5503                                         bottomtick_startpoint.Y = 13;
5504                                         bottomtick_startpoint.X = 24;
5505                                         break;
5506                                 case TickStyle.TopLeft:
5507                                         channel_startpoint.Y = 8;
5508                                         channel_startpoint.X = 19;
5509                                         toptick_startpoint.Y = 13;
5510                                         toptick_startpoint.X = 8;
5511                                         break;
5512                                 case TickStyle.Both:
5513                                         channel_startpoint.Y = 8;
5514                                         channel_startpoint.X = 18;
5515                                         bottomtick_startpoint.Y = 13;
5516                                         bottomtick_startpoint.X = 32;
5517                                         toptick_startpoint.Y = 13;
5518                                         toptick_startpoint.X = 8;
5519                                         break;
5520                                 default:
5521                                         break;
5522                                 }
5523
5524                                 thumb_area.X = area.X + channel_startpoint.X;
5525                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5526                                 thumb_area.Height = area.Height - space_from_right - space_from_left;
5527                                 thumb_area.Width = 4;
5528
5529                                 pixel_len = thumb_area.Height - 11;
5530                                 if (tb.Maximum == tb.Minimum) {
5531                                         pixels_betweenticks = 0;
5532                                 } else {
5533                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5534                                 }
5535
5536                                 thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum));
5537                         } else {        
5538                                 toptick_startpoint = new Point ();
5539                                 bottomtick_startpoint = new Point ();
5540                                 channel_startpoint = new Point ();
5541                                 float pixel_len;
5542                                 const int space_from_right = 8;
5543                                 const int space_from_left = 8;
5544                                 Rectangle area = tb.ClientRectangle;
5545                                                         
5546                                 switch (tb.TickStyle) {
5547                                 case TickStyle.BottomRight:
5548                                 case TickStyle.None:
5549                                         channel_startpoint.X = 8;
5550                                         channel_startpoint.Y = 9;
5551                                         bottomtick_startpoint.X = 13;
5552                                         bottomtick_startpoint.Y = 24;                           
5553                                         break;
5554                                 case TickStyle.TopLeft:
5555                                         channel_startpoint.X = 8;
5556                                         channel_startpoint.Y = 19;
5557                                         toptick_startpoint.X = 13;
5558                                         toptick_startpoint.Y = 8;
5559                                         break;
5560                                 case TickStyle.Both:
5561                                         channel_startpoint.X = 8;
5562                                         channel_startpoint.Y = 18;      
5563                                         bottomtick_startpoint.X = 13;
5564                                         bottomtick_startpoint.Y = 32;                           
5565                                         toptick_startpoint.X = 13;
5566                                         toptick_startpoint.Y = 8;                               
5567                                         break;
5568                                 default:
5569                                         break;
5570                                 }
5571                                                         
5572                                 thumb_area.X = area.X + channel_startpoint.X;
5573                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5574                                 thumb_area.Width = area.Width - space_from_right - space_from_left;
5575                                 thumb_area.Height = 4;
5576
5577                                 pixel_len = thumb_area.Width - 11;
5578                                 if (tb.Maximum == tb.Minimum) {
5579                                         pixels_betweenticks = 0;
5580                                 } else {
5581                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5582                                 }
5583
5584                                 thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum));
5585                         }
5586
5587                         thumb_pos.Size = TrackBarGetThumbSize (tb);
5588                 }
5589
5590                 protected virtual Size TrackBarGetThumbSize (TrackBar trackBar)
5591                 {
5592                         /* Draw thumb fixed 10x22 size */
5593                         return new Size (10, 22);
5594                 }
5595
5596                 #region Ticks
5597                 protected interface ITrackBarTickPainter
5598                 {
5599                         void Paint (float x1, float y1, float x2, float y2);
5600                 }
5601
5602                 class TrackBarTickPainter : ITrackBarTickPainter
5603                 {
5604                         readonly Graphics g;
5605                         readonly Pen pen;
5606                         public TrackBarTickPainter (Graphics g, Pen pen)
5607                         {
5608                                 this.g = g;
5609                                 this.pen = pen;
5610                         }
5611                         public void Paint (float x1, float y1, float x2, float y2)
5612                         {
5613                                 g.DrawLine (pen, x1, y1, x2, y2);
5614                         }
5615                 }
5616                 protected virtual ITrackBarTickPainter GetTrackBarTickPainter (Graphics g)
5617                 {
5618                         return new TrackBarTickPainter (g, ResPool.GetPen (pen_ticks_color));
5619                 }
5620                 #endregion
5621
5622                 #region DrawTrackBar_Vertical
5623                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5624                         ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
5625                         float ticks, int value_pos, bool mouse_value) {                 
5626
5627                         Point toptick_startpoint = new Point ();
5628                         Point bottomtick_startpoint = new Point ();
5629                         Point channel_startpoint = new Point ();
5630                         float pixel_len;
5631                         float pixels_betweenticks;
5632                         Rectangle area = tb.ClientRectangle;
5633                         
5634                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5635
5636                         #region Track
5637                         TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5638                         #endregion
5639
5640                         #region Thumb
5641                         switch (tb.TickStyle)   {
5642                         case TickStyle.BottomRight:
5643                         case TickStyle.None:
5644                                 thumb_pos.X = channel_startpoint.X - 8;
5645                                 TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5646                                 break;
5647                         case TickStyle.TopLeft:
5648                                 thumb_pos.X = channel_startpoint.X - 10;
5649                                 TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5650                                 break;
5651                         default:
5652                                 thumb_pos.X = area.X + 10;
5653                                 TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5654                                 break;
5655                         }
5656                         #endregion
5657
5658                         pixel_len = thumb_area.Height - 11;
5659                         pixels_betweenticks = pixel_len / ticks;
5660                         
5661                         thumb_area.X = thumb_pos.X;
5662                         thumb_area.Y = channel_startpoint.Y;
5663                         thumb_area.Width = thumb_pos.Height;
5664
5665                         #region Ticks
5666                         if (pixels_betweenticks <= 0)
5667                                 return;
5668                         if (tb.TickStyle == TickStyle.None)
5669                                 return;
5670                         Region outside = new Region (area);
5671                         outside.Exclude (thumb_area);                   
5672                         
5673                         if (outside.IsVisible (clip_rectangle)) {
5674                                 ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter (dc);
5675
5676                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5677                                         float x = area.X + bottomtick_startpoint.X;
5678                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks)    {
5679                                                 float y = area.Y + bottomtick_startpoint.Y + inc;
5680                                                 tick_painter.Paint (
5681                                                         x, y,
5682                                                         x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y);
5683                                         }
5684                                 }
5685
5686                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5687                                         float x = area.X + toptick_startpoint.X; 
5688                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
5689                                                 float y = area.Y + toptick_startpoint.Y + inc;
5690                                                 tick_painter.Paint (
5691                                                         x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y,
5692                                                         x, y);
5693                                         }                       
5694                                 }
5695                         }
5696                         
5697                         outside.Dispose ();
5698                         #endregion
5699                 }
5700
5701                 #region Track
5702                 protected virtual void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5703                 {
5704                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5705                                 1, thumb_area.Height);
5706
5707                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y,
5708                                 1, thumb_area.Height);
5709
5710                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y,
5711                                 1, thumb_area.Height);
5712                 }
5713                 #endregion
5714
5715                 #region Thumb
5716                 protected virtual void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5717                 {
5718                         Pen pen = SystemPens.ControlLightLight;
5719                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10);
5720                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
5721                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
5722
5723                         pen = SystemPens.ControlDark;
5724                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9);
5725                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4);
5726
5727                         pen = SystemPens.ControlDarkDark;
5728                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10);
5729                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5);
5730
5731                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
5732                         dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
5733                         dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
5734                         dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
5735                 }
5736
5737                 protected virtual void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5738                 {
5739                         Pen pen = SystemPens.ControlLightLight;
5740                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
5741                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
5742
5743                         pen = SystemPens.ControlDark;
5744                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9);
5745                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5);
5746                         dc.DrawLine (pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1);
5747
5748                         pen = SystemPens.ControlDarkDark;
5749                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10);
5750                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5);
5751                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10);
5752
5753                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
5754                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
5755                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
5756                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
5757                 }
5758
5759                 protected virtual void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5760                 {
5761                         Pen pen = SystemPens.ControlLightLight;
5762                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
5763                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
5764
5765                         pen = SystemPens.ControlDark;
5766                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9);
5767                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8);
5768
5769                         pen = SystemPens.ControlDarkDark;
5770                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10);
5771                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9);
5772
5773                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
5774                 }
5775                 #endregion
5776
5777                 #region Ticks
5778                 protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g)
5779                 {
5780                         return GetTrackBarTickPainter (g);
5781                 }
5782                 #endregion
5783                 #endregion
5784
5785                 #region DrawTrackBar_Horizontal
5786                 /* 
5787                         Horizontal trackbar 
5788                   
5789                         Does not matter the size of the control, Win32 always draws:
5790                                 - Ticks starting from pixel 13, 8
5791                                 - Channel starting at pos 8, 19 and ends at Width - 8
5792                                 - Autosize makes always the control 45 pixels high
5793                                 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
5794                                 
5795                 */
5796                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5797                         ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5798                         float ticks, int value_pos, bool mouse_value) {                 
5799                         Point toptick_startpoint = new Point ();
5800                         Point bottomtick_startpoint = new Point ();
5801                         Point channel_startpoint = new Point ();
5802                         float pixel_len;
5803                         float pixels_betweenticks;
5804                         Rectangle area = tb.ClientRectangle;
5805                         
5806                         GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5807
5808                         #region Track
5809                         TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5810                         #endregion
5811
5812                         #region Thumb
5813                         switch (tb.TickStyle) {
5814                         case TickStyle.BottomRight:
5815                         case TickStyle.None:
5816                                 thumb_pos.Y = channel_startpoint.Y - 8;
5817                                 TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5818                                 break;
5819                         case TickStyle.TopLeft:
5820                                 thumb_pos.Y = channel_startpoint.Y - 10;
5821                                 TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5822                                 break;
5823                         default:
5824                                 thumb_pos.Y = area.Y + 10;
5825                                 TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5826                                 break;
5827                         }
5828                         #endregion
5829
5830                         pixel_len = thumb_area.Width - 11;
5831                         pixels_betweenticks = pixel_len / ticks;
5832
5833                         thumb_area.Y = thumb_pos.Y;
5834                         thumb_area.X = channel_startpoint.X;
5835                         thumb_area.Height = thumb_pos.Height;
5836                         #region Ticks
5837                         if (pixels_betweenticks <= 0)
5838                                 return;
5839                         if (tb.TickStyle == TickStyle.None)
5840                                 return;
5841                         Region outside = new Region (area);
5842                         outside.Exclude (thumb_area);
5843
5844                         if (outside.IsVisible (clip_rectangle)) {
5845                                 ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter (dc);
5846
5847                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5848                                         float y = area.Y + bottomtick_startpoint.Y;
5849                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5850                                                 float x = area.X + bottomtick_startpoint.X + inc;
5851                                                 tick_painter.Paint (
5852                                                         x, y, 
5853                                                         x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2));
5854                                         }
5855                                 }
5856
5857                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5858                                         float y = area.Y + toptick_startpoint.Y;
5859                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5860                                                 float x = area.X + toptick_startpoint.X + inc;
5861                                                 tick_painter.Paint (
5862                                                         x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2), 
5863                                                         x, y);
5864                                         }                       
5865                                 }
5866                         }
5867                         
5868                         outside.Dispose ();
5869                         #endregion
5870                 }
5871
5872                 #region Track
5873                 protected virtual void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5874                 {
5875                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5876                                 thumb_area.Width, 1);
5877
5878                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1,
5879                                 thumb_area.Width, 1);
5880
5881                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3,
5882                                 thumb_area.Width, 1);
5883                 }
5884                 #endregion
5885
5886                 #region Thumb
5887                 protected virtual void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5888                 {
5889                         Pen pen = SystemPens.ControlLightLight;
5890                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
5891                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
5892                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
5893
5894                         pen = SystemPens.ControlDark;
5895                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15);
5896                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4);
5897
5898                         pen = SystemPens.ControlDarkDark;
5899                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16);
5900                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5);
5901
5902                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
5903                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
5904                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
5905                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
5906                 }
5907
5908                 protected virtual void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5909                 {
5910                         Pen pen = SystemPens.ControlLightLight;
5911                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
5912                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
5913
5914                         pen = SystemPens.ControlDark;
5915                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
5916                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
5917                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19);
5918
5919                         pen = SystemPens.ControlDarkDark;
5920                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
5921                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1);
5922                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
5923
5924                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
5925                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
5926                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
5927                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
5928                 }
5929
5930                 protected virtual void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5931                 {
5932                         Pen pen = SystemPens.ControlLightLight;
5933                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
5934                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
5935
5936                         pen = SystemPens.ControlDark;
5937                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
5938                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
5939
5940                         pen = SystemPens.ControlDarkDark;
5941                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20);
5942                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
5943
5944                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
5945                 }
5946                 #endregion
5947
5948                 #region Ticks
5949                 protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g)
5950                 {
5951                         return GetTrackBarTickPainter (g);
5952                 }
5953                 #endregion
5954                 #endregion
5955
5956                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) 
5957                 {
5958                         Brush           br_thumb;
5959                         int             value_pos;
5960                         bool            mouse_value;
5961                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
5962                         Rectangle       area;
5963                         Rectangle       thumb_pos = tb.ThumbPos;
5964                         Rectangle       thumb_area = tb.ThumbArea;
5965                         
5966                         if (tb.thumb_pressed) {
5967                                 value_pos = tb.thumb_mouseclick;
5968                                 mouse_value = true;
5969                         } else {
5970                                 value_pos = tb.Value - tb.Minimum;
5971                                 mouse_value = false;
5972                         }
5973
5974                         area = tb.ClientRectangle;
5975
5976                         if (!tb.Enabled) {
5977                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
5978                         } else if (tb.thumb_pressed == true) {
5979                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
5980                         } else {
5981                                 br_thumb = SystemBrushes.Control;
5982                         }
5983
5984                         
5985                         /* Control Background */
5986                         if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
5987                                 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5988                         } else {
5989                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
5990                         }
5991                         
5992                         if (tb.Focused) {
5993                                 CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor);
5994                         }
5995
5996                         if (tb.Orientation == Orientation.Vertical) {
5997                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
5998                                         br_thumb, ticks, value_pos, mouse_value);
5999                         
6000                         } else {
6001                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6002                                         br_thumb, ticks, value_pos, mouse_value);
6003                         }
6004
6005                         tb.ThumbPos = thumb_pos;
6006                         tb.ThumbArea = thumb_area;
6007                 }
6008
6009                 public override Size TrackBarDefaultSize {
6010                         get {
6011                                 return new Size (104, 42);
6012                         }
6013                 }
6014
6015                 public override bool TrackBarHasHotThumbStyle {
6016                         get {
6017                                 return false;
6018                         }
6019                 }
6020                 #endregion      // TrackBar
6021
6022                 #region UpDownBase
6023                 public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state)
6024                 {
6025                         ControlPaint.DrawScrollButton (g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal);
6026                 }
6027
6028                 public override bool UpDownBaseHasHotButtonStyle {
6029                         get {
6030                                 return false;
6031                         }
6032                 }
6033                 #endregion
6034
6035                 #region VScrollBar
6036                 public override Size VScrollBarDefaultSize {
6037                         get {
6038                                 return new Size (this.ScrollBarButtonSize, 80);
6039                         }
6040                 }
6041                 #endregion      // VScrollBar
6042
6043                 #region TreeView
6044                 public override Size TreeViewDefaultSize {
6045                         get {
6046                                 return new Size (121, 97);
6047                         }
6048                 }
6049
6050                 public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle)
6051                 {
6052                         int height = treeView.ActualItemHeight - 2;
6053                         dc.FillRectangle (ResPool.GetSolidBrush (treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height);
6054                         
6055                         dc.DrawRectangle (SystemPens.ControlDarkDark, x, middle - 4, 8, 8);
6056
6057                         if (node.IsExpanded) {
6058                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); 
6059                         } else {
6060                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
6061                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2);
6062                         }
6063                 }
6064                 #endregion
6065
6066                 #region Managed window
6067                 public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
6068                 {
6069                         if (wm.IsToolWindow && !wm.IsMinimized)
6070                                 return SystemInformation.ToolWindowCaptionHeight;
6071                         if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6072                                 return 0;
6073                         return SystemInformation.CaptionHeight;
6074                 }
6075
6076                 public override int ManagedWindowBorderWidth (InternalWindowManager wm)
6077                 {
6078                         if ((wm.IsToolWindow && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow) ||
6079                                 wm.IsMinimized)
6080                                 return 3;
6081                         else
6082                                 return 4;
6083                 }
6084
6085                 public override int ManagedWindowIconWidth (InternalWindowManager wm)
6086                 {
6087                         return ManagedWindowTitleBarHeight (wm) - 5;
6088                 }
6089
6090                 public override void ManagedWindowSetButtonLocations (InternalWindowManager wm)
6091                 {
6092                         TitleButtons buttons = wm.TitleButtons;
6093                         Form form = wm.form;
6094                         
6095                         buttons.HelpButton.Visible = form.HelpButton;
6096                         
6097                         foreach (TitleButton button in buttons) {
6098                                 button.Visible = false;
6099                         }
6100                         
6101                         switch (form.FormBorderStyle) {
6102                         case FormBorderStyle.None:
6103                                 if (form.WindowState != FormWindowState.Normal)
6104                                         goto case FormBorderStyle.Sizable;
6105                                 break;
6106                         case FormBorderStyle.FixedToolWindow:
6107                         case FormBorderStyle.SizableToolWindow:
6108                                 buttons.CloseButton.Visible = true;
6109                                 if (form.WindowState != FormWindowState.Normal)
6110                                         goto case FormBorderStyle.Sizable;
6111                                 break;
6112                         case FormBorderStyle.FixedSingle:
6113                         case FormBorderStyle.Fixed3D:
6114                         case FormBorderStyle.FixedDialog:
6115                         case FormBorderStyle.Sizable:
6116                                 switch (form.WindowState) {
6117                                         case FormWindowState.Normal:
6118                                                 buttons.MinimizeButton.Visible = true;
6119                                                 buttons.MaximizeButton.Visible = true;
6120                                                 buttons.RestoreButton.Visible = false;
6121                                                 break;
6122                                         case FormWindowState.Maximized:
6123                                                 buttons.MinimizeButton.Visible = true;
6124                                                 buttons.MaximizeButton.Visible = false;
6125                                                 buttons.RestoreButton.Visible = true;
6126                                                 break;
6127                                         case FormWindowState.Minimized:
6128                                                 buttons.MinimizeButton.Visible = false;
6129                                                 buttons.MaximizeButton.Visible = true;
6130                                                 buttons.RestoreButton.Visible = true;
6131                                                 break;
6132                                 }
6133                                 buttons.CloseButton.Visible = true;
6134                                 break;
6135                         }
6136
6137                         // Respect MinimizeBox/MaximizeBox
6138                         if (form.MinimizeBox == false && form.MaximizeBox == false) {
6139                                 buttons.MinimizeButton.Visible = false;
6140                                 buttons.MaximizeButton.Visible = false;
6141                         } else if (form.MinimizeBox == false)
6142                                 buttons.MinimizeButton.State = ButtonState.Inactive;
6143                         else if (form.MaximizeBox == false)
6144                                 buttons.MaximizeButton.State = ButtonState.Inactive;
6145
6146                         int bw = ManagedWindowBorderWidth (wm);
6147                         Size btsize = ManagedWindowButtonSize (wm);
6148                         int btw = btsize.Width;
6149                         int bth = btsize.Height;
6150                         int top = bw + 2;
6151                         int left = form.Width - bw - btw - ManagedWindowSpacingAfterLastTitleButton;
6152                         
6153                         if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
6154                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6155                                 left -= 2 + btw;
6156                                 
6157                                 if (buttons.MaximizeButton.Visible) {
6158                                         buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6159                                         left -= 2 + btw;
6160                                 } 
6161                                 if (buttons.RestoreButton.Visible) {
6162                                         buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth);
6163                                         left -= 2 + btw;
6164                                 }
6165
6166                                 buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6167                                 left -= 2 + btw;
6168                         } else if (wm.IsToolWindow) {
6169                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6170                                 left -= 2 + btw;
6171                         }
6172                 }
6173
6174                 protected virtual Rectangle ManagedWindowDrawTitleBarAndBorders (Graphics dc, Rectangle clip, InternalWindowManager wm)
6175                 {
6176                         Form form = wm.Form;
6177                         int tbheight = ManagedWindowTitleBarHeight (wm);
6178                         int bdwidth = ManagedWindowBorderWidth (wm);
6179                         Color titlebar_color = Color.FromArgb (255, 10, 36, 106);
6180                         Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240);
6181                         Color color = ThemeEngine.Current.ColorControlDark;
6182                         Color color2 = Color.FromArgb (255, 192, 192, 192);
6183
6184                         Pen pen = ResPool.GetPen (ColorControl);
6185                         Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
6186                         ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
6187                         // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves
6188                         borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5);
6189                         for (int i = 2; i < bdwidth; i++) {
6190                                 dc.DrawRectangle (pen, borders);
6191                                 borders.Inflate (-1, -1);
6192                         }                               
6193
6194
6195                         bool draw_titlebar_enabled = false;
6196                         if (wm.Form.Parent != null && wm.Form.Parent is Form) {
6197                                 draw_titlebar_enabled = false;
6198                         } else if (wm.IsActive && !wm.IsMaximized) {
6199                                 draw_titlebar_enabled = true;
6200                         }
6201                         if (draw_titlebar_enabled) {
6202                                 color = titlebar_color;
6203                                 color2 = titlebar_color2;
6204                         }
6205
6206                         Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1);
6207
6208                         // HACK: For now always draw the titlebar until we get updates better
6209                         if (tb.Width > 0 && tb.Height > 0) {
6210                                 using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal))
6211                                 {
6212                                         dc.FillRectangle (gradient, tb);
6213                                 }       
6214                         }
6215                         
6216                         if (!wm.IsMinimized)
6217                                 // Draw the line just beneath the title bar
6218                                 dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth,
6219                                                 tbheight + bdwidth - 1, form.Width - bdwidth - 1,
6220                                                 tbheight + bdwidth - 1);
6221                         return tb;
6222                 }
6223
6224                 public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
6225                 {
6226 #if debug
6227                         Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations");
6228                         dc.FillRectangle (Brushes.Black, clip);
6229 #endif
6230                         Rectangle tb = ManagedWindowDrawTitleBarAndBorders (dc, clip, wm);
6231
6232                         Form form = wm.Form;
6233                         if (wm.ShowIcon) {
6234                                 Rectangle icon = ManagedWindowGetTitleBarIconArea (wm);
6235                                 if (icon.IntersectsWith (clip))
6236                                         dc.DrawIcon (form.Icon, icon);
6237                                 const int SpacingBetweenIconAndCaption = 2;
6238                                 tb.Width -= icon.Right + SpacingBetweenIconAndCaption - tb.X ;
6239                                 tb.X = icon.Right + SpacingBetweenIconAndCaption;
6240                         }
6241                         
6242                         foreach (TitleButton button in wm.TitleButtons.AllButtons) {
6243                                 tb.Width -= Math.Max (0, tb.Right - DrawTitleButton (dc, button, clip, form));
6244                         }
6245                         const int SpacingBetweenCaptionAndLeftMostButton = 3;
6246                         tb.Width -= SpacingBetweenCaptionAndLeftMostButton;
6247
6248                         string window_caption = form.Text;
6249                         window_caption = window_caption.Replace (Environment.NewLine, string.Empty);
6250
6251                         if (window_caption != null && window_caption != string.Empty) {
6252                                 StringFormat format = new StringFormat ();
6253                                 format.FormatFlags = StringFormatFlags.NoWrap;
6254                                 format.Trimming = StringTrimming.EllipsisCharacter;
6255                                 format.LineAlignment = StringAlignment.Center;
6256
6257                                 if (tb.IntersectsWith (clip))
6258                                         dc.DrawString (window_caption, WindowBorderFont,
6259                                                 ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
6260                                                 tb, format);
6261                         }
6262                 }
6263
6264                 public override Size ManagedWindowButtonSize (InternalWindowManager wm)
6265                 {
6266                         int height = ManagedWindowTitleBarHeight (wm);
6267                         if (!wm.IsMaximized && !wm.IsMinimized) {
6268                                 if (wm.IsToolWindow)
6269                                         return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
6270                                                         height - 5);
6271                                 if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6272                                         return Size.Empty;
6273                         } else
6274                                 height = SystemInformation.CaptionHeight;
6275
6276                         return new Size (SystemInformation.CaptionButtonSize.Width - 2,
6277                                         height - 5);
6278                 }
6279
6280                 private int DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6281                 {
6282                         if (!button.Visible) {
6283                                 return int.MaxValue;
6284                         }
6285                         
6286                         if (button.Rectangle.IntersectsWith (clip)) {
6287                                 ManagedWindowDrawTitleButton (dc, button, clip, form);
6288                         }
6289                         return button.Rectangle.Left;
6290                 }
6291
6292                 protected virtual void ManagedWindowDrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6293                 {
6294                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6295
6296                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6297                                         button.Caption, button.State);
6298                 }
6299
6300                 public override Rectangle ManagedWindowGetTitleBarIconArea (InternalWindowManager wm)
6301                 {
6302                         int bw = ManagedWindowBorderWidth (wm);
6303                         return new Rectangle (bw + 3, bw + 2, wm.IconWidth, wm.IconWidth);
6304                 }
6305
6306                 public override Size ManagedWindowGetMenuButtonSize (InternalWindowManager wm)
6307                 {
6308                         Size result = SystemInformation.MenuButtonSize;
6309                         result.Width -= 2;
6310                         result.Height -= 4;
6311                         return result;
6312                 }
6313
6314                 public override bool ManagedWindowTitleButtonHasHotElementStyle (TitleButton button, Form form)
6315                 {
6316                         return false;
6317                 }
6318
6319                 public override void ManagedWindowDrawMenuButton (Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm)
6320                 {
6321                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6322                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6323                                         button.Caption, button.State);
6324                 }
6325
6326                 public override void ManagedWindowOnSizeInitializedOrChanged (Form form)
6327                 {
6328                 }
6329                 #endregion
6330
6331                 #region ControlPaint
6332                 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
6333                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6334                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6335                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6336                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6337                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6338                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6339                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6340                 }
6341
6342                 public override void CPDrawBorder (Graphics graphics, RectangleF bounds, Color leftColor, int leftWidth,
6343                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6344                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6345                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6346                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6347                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6348                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6349                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6350                 }
6351
6352                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
6353                         CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
6354                 }
6355
6356                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)
6357                 {
6358                         Pen             penTopLeft;
6359                         Pen             penTopLeftInner;
6360                         Pen             penBottomRight;
6361                         Pen             penBottomRightInner;
6362                         Rectangle       rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6363                         bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
6364                         
6365                         if ((style & Border3DStyle.Adjust) != 0) {
6366                                 rect.Y -= 2;
6367                                 rect.X -= 2;
6368                                 rect.Width += 4;
6369                                 rect.Height += 4;
6370                         }
6371                         
6372                         penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color);
6373                         
6374                         CPColor cpcolor = CPColor.Empty;
6375                         
6376                         if (!is_ColorControl)
6377                                 cpcolor = ResPool.GetCPColor (control_color);
6378                         
6379                         switch (style) {
6380                         case Border3DStyle.Raised:
6381                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6382                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6383                                 penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6384                                 break;
6385                         case Border3DStyle.Sunken:
6386                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6387                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6388                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6389                                 break;
6390                         case Border3DStyle.Etched:
6391                                 penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6392                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6393                                 break;
6394                         case Border3DStyle.RaisedOuter:
6395                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6396                                 break;
6397                         case Border3DStyle.SunkenOuter:
6398                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6399                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6400                                 break;
6401                         case Border3DStyle.RaisedInner:
6402                                 penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6403                                 penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6404                                 break;
6405                         case Border3DStyle.SunkenInner:
6406                                 penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6407                                 break;
6408                         case Border3DStyle.Flat:
6409                                 penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6410                                 break;
6411                         case Border3DStyle.Bump:
6412                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6413                                 break;
6414                         default:
6415                                 break;
6416                         }
6417                         
6418                         bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter));
6419                         
6420                         if ((sides & Border3DSide.Middle) != 0) {
6421                                 Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color);
6422                                 graphics.FillRectangle (brush, rect);
6423                         }
6424                         
6425                         if ((sides & Border3DSide.Left) != 0) {
6426                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top);
6427                                 if ((rect.Width > 2) && inner)
6428                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top);
6429                         }
6430                         
6431                         if ((sides & Border3DSide.Top) != 0) {
6432                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top);
6433                                 if ((rect.Height > 2) && inner)
6434                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1);
6435                         }
6436                         
6437                         if ((sides & Border3DSide.Right) != 0) {
6438                                 graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
6439                                 if ((rect.Width > 3) && inner)
6440                                         graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2);
6441                         }
6442                         
6443                         if ((sides & Border3DSide.Bottom) != 0) {
6444                                 graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6445                                 if ((rect.Height > 3) && inner)
6446                                         graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
6447                         }
6448                 }
6449
6450                 public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
6451                 {
6452                         CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight);
6453                 }
6454
6455                 private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)
6456                 {
6457                         // sadly enough, the rectangle gets always filled with a hatchbrush
6458                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6459                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6460                                                                                  ColorControl.G, ColorControl.B),
6461                                                                  ColorControl),
6462                                           rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2);
6463                         
6464                         if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) {
6465                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6466                                 
6467                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6468                         } else
6469                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6470                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6471                         } else
6472                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6473                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6474                                 
6475                                 Pen pen = DarkPen;
6476                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6477                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6478                                 
6479                                 pen = NormalPen;
6480                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6481                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6482                                 
6483                                 pen = LightPen;
6484                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6485                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6486                         } else
6487                         if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) {
6488                                 Pen pen = DarkPen;
6489                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6490                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6491                                 
6492                                 pen = NormalPen;
6493                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6494                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6495                                 
6496                                 pen = LightPen;
6497                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6498                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6499                         } else
6500                         if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) {
6501                                 Pen pen = LightPen;
6502                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6503                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6504                                 
6505                                 pen = NormalPen;
6506                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2);
6507                                 dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3);
6508                                 
6509                                 pen = DarkPen;
6510                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1);
6511                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2);
6512                         }
6513                 }
6514
6515
6516                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
6517                         Rectangle       captionRect;
6518                         int                     lineWidth;
6519
6520                         CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight);
6521
6522                         if (rectangle.Width<rectangle.Height) {
6523                                 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
6524                         } else {
6525                                 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
6526                         }
6527
6528                         if ((state & ButtonState.Pushed)!=0) {
6529                                 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
6530                         }
6531
6532                         /* Make sure we've got at least a line width of 1 */
6533                         lineWidth=Math.Max(1, captionRect.Width/7);
6534
6535                         switch(button) {
6536                         case CaptionButton.Close: {
6537                                 Pen     pen;
6538
6539                                 if ((state & ButtonState.Inactive)!=0) {
6540                                         pen = ResPool.GetSizedPen (ColorControlLight, lineWidth);
6541                                         DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
6542
6543                                         pen = ResPool.GetSizedPen (ColorControlDark, lineWidth);
6544                                         DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
6545                                         return;
6546                                 } else {
6547                                         pen = ResPool.GetSizedPen (ColorControlText, lineWidth);
6548                                         DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
6549                                         return;
6550                                 }
6551                         }
6552
6553                         case CaptionButton.Help:
6554                         case CaptionButton.Maximize:
6555                         case CaptionButton.Minimize:
6556                         case CaptionButton.Restore: {
6557                                 if ((state & ButtonState.Inactive)!=0) {
6558                                         DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
6559
6560                                         DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
6561                                         return;
6562                                 } else {
6563                                         DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
6564                                         return;
6565                                 }
6566                         }
6567                         }
6568                 }
6569
6570                 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
6571                 {
6572                         Pen check_pen = Pens.Black;
6573                         
6574                         Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6575                         
6576                         if ((state & ButtonState.All) == ButtonState.All) {
6577                                 cb_rect.Width -= 2;
6578                                 cb_rect.Height -= 2;
6579                                 
6580                                 dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6581                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6582                                 
6583                                 check_pen = SystemPens.ControlDark;
6584                         } else
6585                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6586                                 cb_rect.Width -= 2;
6587                                 cb_rect.Height -= 2;
6588                                 
6589                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6590                                         dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6591                                 else
6592                                         dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6593                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6594                         } else {
6595                                 cb_rect.Width -= 1;
6596                                 cb_rect.Height -= 1;
6597                                 
6598                                 int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height;
6599                                 
6600                                 int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2);
6601                                 int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2);
6602                                 
6603                                 Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
6604                                 
6605                                 if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) {
6606                                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6607                                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6608                                                                                                  ColorControl.G, ColorControl.B),
6609                                                                                  ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6610                                 } else
6611                                         dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6612                                 
6613                                 Pen pen = SystemPens.ControlDark;
6614                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1);
6615                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y);
6616                                 
6617                                 pen = SystemPens.ControlDarkDark;
6618                                 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2);
6619                                 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1);
6620                                 
6621                                 pen = SystemPens.ControlLightLight;
6622                                 dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom);
6623                                 dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom);
6624                                 
6625                                 // oh boy, matching ms is like fighting against windmills
6626                                 using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
6627                                                                                    Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6628                                                                                                    ColorControl.G, ColorControl.B), ColorControl))) {
6629                                         dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6630                                         dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1);
6631                                 }
6632                                 
6633                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6634                                         check_pen = SystemPens.ControlDark;
6635                         }
6636                         
6637                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6638                                 int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2;
6639                                 
6640                                 if (check_size < 7) {
6641                                         int lineWidth = Math.Max (3, check_size / 3);
6642                                         int Scale = Math.Max (1, check_size / 9);
6643                                         
6644                                         Rectangle rect = new Rectangle (cb_rect.X + (cb_rect.Width / 2) - (int)Math.Ceiling ((float)check_size / 2) - 1, cb_rect.Y + (cb_rect.Height / 2) - (check_size / 2) - 1, 
6645                                                                         check_size, check_size);
6646                                         
6647                                         for (int i = 0; i < lineWidth; i++) {
6648                                                 dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
6649                                                 dc.DrawLine (check_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);
6650                                         }
6651                                 } else {
6652                                         int lineWidth = Math.Max (3, check_size / 3) + 1;
6653                                         
6654                                         int x_half = cb_rect.Width / 2;
6655                                         int y_half = cb_rect.Height / 2;
6656                                         
6657                                         Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2), 
6658                                                                         check_size, check_size);
6659                                         
6660                                         int gradient_left = check_size / 3;
6661                                         int gradient_right = check_size - gradient_left - 1;
6662                                         
6663                                         
6664                                         for (int i = 0; i < lineWidth; i++) {
6665                                                 dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
6666                                                 dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i  - 1 - gradient_right);
6667                                         }
6668                                 }
6669                         }
6670                 }
6671
6672                 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
6673                         Point[]                 arrow = new Point[3];
6674                         Point                           P1;
6675                         Point                           P2;
6676                         Point                           P3;
6677                         int                             centerX;
6678                         int                             centerY;
6679                         int                             shiftX;
6680                         int                             shiftY;
6681                         Rectangle               rect;
6682
6683                         if ((state & ButtonState.Checked)!=0) {
6684                                 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);                              
6685                         }
6686
6687                         if ((state & ButtonState.Flat)!=0) {
6688                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
6689                         } else {
6690                                 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
6691                                         // this needs to render like a pushed button - jba
6692                                         // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6693                                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6694                                         graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle);
6695                                 } else {
6696                                         CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6697                                 }
6698                         }
6699
6700                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
6701                         centerX=rect.Left+rect.Width/2;
6702                         centerY=rect.Top+rect.Height/2;
6703                         shiftX=Math.Max(1, rect.Width/8);
6704                         shiftY=Math.Max(1, rect.Height/8);
6705
6706                         if ((state & ButtonState.Pushed)!=0) {
6707                                 shiftX++;
6708                                 shiftY++;
6709                         }
6710
6711                         rect.Y-=shiftY;
6712                         centerY-=shiftY;
6713                         P1=new Point(rect.Left, centerY);
6714                         P2=new Point(rect.Right, centerY);
6715                         P3=new Point(centerX, rect.Bottom);
6716
6717                         arrow[0]=P1;
6718                         arrow[1]=P2;
6719                         arrow[2]=P3;
6720                         
6721                         /* Draw the arrow */
6722                         if ((state & ButtonState.Inactive)!=0) {
6723                                 /* Move away from the shadow */
6724                                 arrow[0].X += 1;        arrow[0].Y += 1;
6725                                 arrow[1].X += 1;        arrow[1].Y += 1;
6726                                 arrow[2].X += 1;        arrow[2].Y += 1;
6727                                 
6728                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
6729
6730                                 arrow[0]=P1;
6731                                 arrow[1]=P2;
6732                                 arrow[2]=P3;
6733
6734                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
6735                         } else {
6736                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
6737                         }
6738                 }
6739
6740
6741                 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds)
6742                 {
6743                         Pen                     pen     = Pens.Black;
6744                         Rectangle       rect    = new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);      // Dunno why, but MS does it that way, too
6745                         int                     X;
6746                         int                     Y;
6747                         
6748                         graphics.FillRectangle (SystemBrushes.ControlLightLight, rect);
6749                         graphics.DrawRectangle (pen, rect);
6750                         
6751                         X = rect.X + rect.Width / 2;
6752                         Y = rect.Y + rect.Height / 2;
6753                         
6754                         /* Draw the cross */
6755                         graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2);
6756                         graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y);
6757                         
6758                         /* Draw 'arrows' for vertical lines */
6759                         graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3);
6760                         graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3);
6761                         
6762                         /* Draw 'arrows' for horizontal lines */
6763                         graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1);
6764                         graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1);
6765                 }
6766
6767                 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
6768                         // make a rectange to trace around border of the button
6769                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6770                         
6771                         Color outerColor = foreColor;
6772                         // adjust focus color according to the flatstyle
6773                         if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
6774                                 outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;                              
6775                         }
6776                         
6777                         // draw the outer rectangle
6778                         graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);                  
6779                         
6780                         // draw the inner rectangle                                             
6781                         if (button.FlatStyle == FlatStyle.Popup) {
6782                                 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
6783                         } else {
6784                                 // draw a flat inner rectangle
6785                                 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
6786                                 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));                               
6787                         }
6788                 }
6789                 
6790                 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
6791                 {       
6792                         // make a rectange to trace around border of the button
6793                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6794                         
6795 #if NotUntilCairoIsFixed
6796                         Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6797                         DashStyle oldStyle; // used for caching old penstyle
6798                         Pen pen = ResPool.GetPen (colorBackInverted);
6799
6800                         oldStyle = pen.DashStyle; 
6801                         pen.DashStyle = DashStyle.Dot;
6802
6803                         graphics.DrawRectangle (pen, trace_rectangle);
6804                         pen.DashStyle = oldStyle;
6805 #else
6806                         CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
6807 #endif
6808                 }
6809                                 
6810
6811                 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) 
6812                 {                       
6813                         Rectangle rect = rectangle;
6814                         Pen pen;
6815                         HatchBrush brush;
6816                                 
6817                         if (backColor.GetBrightness () >= 0.5) {
6818                                 foreColor = Color.Transparent;
6819                                 backColor = Color.Black;
6820                                 
6821                         } else {
6822                                 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6823                                 foreColor = Color.Black;
6824                         }
6825                                                 
6826                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
6827                         pen = new Pen (brush, 1);
6828                                                 
6829                         rect.Width--;
6830                         rect.Height--;                  
6831                         
6832                         graphics.DrawRectangle (pen, rect);
6833                         pen.Dispose ();
6834                 }
6835                 
6836                 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled)
6837                 {
6838                         Brush   sb;
6839                         Pen pen;
6840                         
6841                         if (primary == true) {
6842                                 pen = Pens.Black;
6843                                 if (enabled == true) {
6844                                         sb = Brushes.White;
6845                                 } else {
6846                                         sb = SystemBrushes.Control;
6847                                 }
6848                         } else {
6849                                 pen = Pens.White;
6850                                 if (enabled == true) {
6851                                         sb = Brushes.Black;
6852                                 } else {
6853                                         sb = SystemBrushes.Control;
6854                                 }
6855                         }
6856                         graphics.FillRectangle (sb, rectangle);
6857                         graphics.DrawRectangle (pen, rectangle);                        
6858                 }
6859
6860
6861                 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
6862                         Color   foreColor;
6863                         int     h;
6864                         int     b;
6865                         int     s;
6866
6867                         ControlPaint.Color2HBS(backColor, out h, out b, out s);
6868                         
6869                         if (b>127) {
6870                                 foreColor=Color.Black;
6871                         } else {
6872                                 foreColor=Color.White;
6873                         }
6874
6875                         // still not perfect. it seems that ms calculates the position of the first dot or line
6876
6877                         using (Pen pen = new Pen (foreColor)) {
6878                                 pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
6879                                 
6880                                 for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
6881                                         graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
6882                         }
6883                 }
6884
6885                 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
6886                         /*
6887                                 Microsoft seems to ignore the background and simply make
6888                                 the image grayscale. At least when having > 256 colors on
6889                                 the display.
6890                         */
6891                         
6892                         if (imagedisabled_attributes == null) {                         
6893                                 imagedisabled_attributes = new ImageAttributes ();
6894                                 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
6895                                           // This table would create a perfect grayscale image, based on luminance
6896                                           //                            new float[]{0.3f,0.3f,0.3f,0,0},
6897                                           //                            new float[]{0.59f,0.59f,0.59f,0,0},
6898                                           //                            new float[]{0.11f,0.11f,0.11f,0,0},
6899                                           //                            new float[]{0,0,0,1,0,0},
6900                                           //                            new float[]{0,0,0,0,1,0},
6901                                           //                            new float[]{0,0,0,0,0,1}
6902                 
6903                                           // This table generates a image that is grayscaled and then
6904                                           // brightened up. Seems to match MS close enough.
6905                                           new float[]{0.2f,0.2f,0.2f,0,0},
6906                                           new float[]{0.41f,0.41f,0.41f,0,0},
6907                                           new float[]{0.11f,0.11f,0.11f,0,0},
6908                                           new float[]{0.15f,0.15f,0.15f,1,0,0},
6909                                           new float[]{0.15f,0.15f,0.15f,0,1,0},
6910                                           new float[]{0.15f,0.15f,0.15f,0,0,1}
6911                                   });
6912                                   
6913                                  imagedisabled_attributes.SetColorMatrix (colorMatrix);
6914                         }
6915                         
6916                         graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
6917                         
6918                 }
6919
6920
6921                 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
6922                         Pen     penBorder;
6923                         Pen     penInside;
6924
6925                         if (primary) {
6926                                 penBorder = ResPool.GetSizedPen (Color.White, 2);
6927                                 penInside = ResPool.GetPen (Color.Black);
6928                         } else {
6929                                 penBorder = ResPool.GetSizedPen (Color.Black, 2);
6930                                 penInside = ResPool.GetPen (Color.White);
6931                         }
6932                         penBorder.Alignment=PenAlignment.Inset;
6933                         penInside.Alignment=PenAlignment.Inset;
6934
6935                         graphics.DrawRectangle(penBorder, rectangle);
6936                         graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
6937                 }
6938
6939
6940                 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) {
6941                         Rectangle       rect;
6942                         int                     lineWidth;
6943
6944                         if (backColor != Color.Empty)
6945                                 graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle);
6946                                 
6947                         Brush brush = ResPool.GetSolidBrush (color);
6948
6949                         switch(glyph) {
6950                         case MenuGlyph.Arrow: {
6951                                 float height = rectangle.Height * 0.7f;
6952                                 float width  = height / 2.0f;
6953                                 
6954                                 PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f));
6955
6956                                 PointF [] vertices = new PointF [3];
6957                                 vertices [0].X = ddCenter.X;
6958                                 vertices [0].Y = ddCenter.Y - (height / 2.0f);
6959                                 vertices [1].X = ddCenter.X;
6960                                 vertices [1].Y = ddCenter.Y + (height / 2.0f);
6961                                 vertices [2].X = ddCenter.X + width + 0.1f;
6962                                 vertices [2].Y = ddCenter.Y;
6963                                 
6964                                 graphics.FillPolygon (brush, vertices);
6965
6966                                 return;
6967                         }
6968
6969                         case MenuGlyph.Bullet: {
6970                                 
6971                                 lineWidth=Math.Max(2, rectangle.Width/3);
6972                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
6973                                 
6974                                 graphics.FillEllipse(brush, rect);
6975                                 
6976                                 return;
6977                         }
6978
6979                         case MenuGlyph.Checkmark: {
6980                                 
6981                                 Pen pen = ResPool.GetPen (color);
6982                                 lineWidth = Math.Max (2, rectangle.Width / 6);
6983                                 rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2);
6984
6985                                 int Scale = Math.Max (1, rectangle.Width / 12);
6986                                 int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2));
6987
6988                                 for (int i=0; i<lineWidth; i++) {
6989                                         graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i);
6990                                         graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i);
6991                                 }
6992                                 return;
6993                         }
6994                         }
6995
6996                 }
6997
6998                 [MonoTODO]
6999                 public override void CPDrawMixedCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state)
7000                 {
7001                         CPDrawCheckBox (graphics, rectangle, state);
7002                 }
7003
7004                 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
7005                 {
7006                         CPColor cpcolor = ResPool.GetCPColor (ColorControl);
7007                         
7008                         Color dot_color = Color.Black;
7009                         
7010                         Color top_left_outer = Color.Black;
7011                         Color top_left_inner = Color.Black;
7012                         Color bottom_right_outer = Color.Black;
7013                         Color bottom_right_inner = Color.Black;
7014                         
7015                         int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height  * 0.9f) : (int)(rectangle.Width * 0.9f);
7016                         int radius = ellipse_diameter / 2;
7017                         
7018                         Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter);
7019                         
7020                         Brush brush = null;
7021                         
7022                         if ((state & ButtonState.All) == ButtonState.All) {
7023                                 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
7024                                                                                                      ColorControl.G, ColorControl.B), ColorControl);
7025                                 dot_color = cpcolor.Dark;
7026                         } else
7027                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
7028                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7029                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7030                                 else
7031                                         brush = SystemBrushes.ControlLightLight;
7032                         } else {
7033                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7034                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7035                                 else
7036                                         brush = SystemBrushes.ControlLightLight;
7037                                 
7038                                 top_left_outer = cpcolor.Dark;
7039                                 top_left_inner = cpcolor.DarkDark;
7040                                 bottom_right_outer = cpcolor.Light;
7041                                 bottom_right_inner = Color.Transparent;
7042                                 
7043                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
7044                                         dot_color = cpcolor.Dark;
7045                         }
7046                         
7047                         dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1);
7048                         
7049                         int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f));
7050                         
7051                         dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f);
7052                         dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f);
7053                         dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f);
7054                         
7055                         if (bottom_right_inner != Color.Transparent)
7056                                 dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7057                         else
7058                                 using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl), line_width)) {
7059                                         dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7060                                 }
7061                         
7062                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
7063                                 int inflate = line_width * 4;
7064                                 Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate);
7065                                 if (rectangle.Height >  13) {
7066                                         tmp.X += 1;
7067                                         tmp.Y += 1;
7068                                         tmp.Height -= 1;
7069                                         dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp);
7070                                 } else {
7071                                         Pen pen = ResPool.GetPen (dot_color);
7072                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2));
7073                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1);
7074                                         
7075                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom);
7076                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom);
7077                                 }
7078                         }
7079                 }
7080
7081                 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
7082
7083                 }
7084
7085
7086                 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
7087
7088                 }
7089
7090
7091                 /* Scroll button: regular button + direction arrow */
7092                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
7093                 {
7094                         DrawScrollButtonPrimitive (dc, area, state);
7095                         
7096                         bool fill_rect = true;
7097                         int offset = 0;
7098                         
7099                         if ((state & ButtonState.Pushed) != 0)
7100                                 offset = 1;
7101                         
7102                         // skip the border
7103                         Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
7104                         
7105                         Point [] arrow = new Point [3];
7106                         for (int i = 0; i < 3; i++)
7107                                 arrow [i] = new Point ();
7108                         
7109                         Pen pen = SystemPens.ControlText;
7110                         
7111                         if ((state & ButtonState.Inactive) != 0) {
7112                                 pen = SystemPens.ControlDark;
7113                         }
7114                         
7115                         switch (type) {
7116                                 default:
7117                                 case ScrollButton.Down:
7118                                         int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7119                                         int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7120                                         if (x_middle == 1)
7121                                                 x_middle = 2;
7122                                         
7123                                         int triangle_height;
7124                                         
7125                                         if (rect.Height < 8) {
7126                                                 triangle_height = 2;
7127                                                 fill_rect = false;
7128                                         } else if (rect.Height == 11) {
7129                                                 triangle_height = 3;
7130                                         } else {
7131                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7132                                         }
7133                                         
7134                                         arrow [0].X = rect.X + x_middle;
7135                                         arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
7136                                         
7137                                         arrow [1].X = arrow [0].X + triangle_height - 1;
7138                                         arrow [1].Y = arrow [0].Y - triangle_height + 1;
7139                                         arrow [2].X = arrow [0].X - triangle_height + 1;
7140                                         arrow [2].Y = arrow [1].Y;
7141                                         
7142                                         dc.DrawPolygon (pen, arrow);
7143                                         
7144                                         if ((state & ButtonState.Inactive) != 0) {
7145                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
7146                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
7147                                         }
7148                                         
7149                                         if (fill_rect) {
7150                                                 for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
7151                                                         dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
7152                                                         arrow [1].X -= 1;
7153                                                         arrow [2].X += 1;
7154                                                 }
7155                                         }
7156                                         break;
7157                                         
7158                                 case ScrollButton.Up:
7159                                         x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7160                                         y_middle = (int)Math.Round (rect.Height / 2.0f);
7161                                         if (x_middle == 1)
7162                                                 x_middle = 2;
7163                                         
7164                                         if (y_middle == 1)
7165                                                 y_middle = 2;
7166                                         
7167                                         if (rect.Height < 8) {
7168                                                 triangle_height = 2;
7169                                                 fill_rect = false;
7170                                         } else if (rect.Height == 11) {
7171                                                 triangle_height = 3;
7172                                         } else {
7173                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7174                                         }
7175                                         
7176                                         arrow [0].X = rect.X + x_middle;
7177                                         arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
7178                                         
7179                                         arrow [1].X = arrow [0].X + triangle_height - 1;
7180                                         arrow [1].Y = arrow [0].Y + triangle_height - 1;
7181                                         arrow [2].X = arrow [0].X - triangle_height + 1;
7182                                         arrow [2].Y = arrow [1].Y;
7183                                         
7184                                         dc.DrawPolygon (pen, arrow);
7185                                         
7186                                         if ((state & ButtonState.Inactive) != 0) {
7187                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
7188                                         }
7189                                         
7190                                         if (fill_rect) {
7191                                                 for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
7192                                                         dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
7193                                                         arrow [1].X -= 1;
7194                                                         arrow [2].X += 1;
7195                                                 }
7196                                         }
7197                                         break;
7198                                         
7199                                 case ScrollButton.Left:
7200                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7201                                         if (y_middle == 1)
7202                                                 y_middle = 2;
7203                                         
7204                                         int triangle_width;
7205                                         
7206                                         if (rect.Width < 8) {
7207                                                 triangle_width = 2;
7208                                                 fill_rect = false;
7209                                         } else if (rect.Width == 11) {
7210                                                 triangle_width = 3;
7211                                         } else {
7212                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7213                                         }
7214                                         
7215                                         arrow [0].X = rect.Left + triangle_width - 1;
7216                                         arrow [0].Y = rect.Y + y_middle;
7217                                         
7218                                         if (arrow [0].X - 1 == rect.X)
7219                                                 arrow [0].X += 1;
7220                                         
7221                                         arrow [1].X = arrow [0].X + triangle_width - 1;
7222                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7223                                         arrow [2].X = arrow [1].X;
7224                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7225                                         
7226                                         dc.DrawPolygon (pen, arrow);
7227                                         
7228                                         if ((state & ButtonState.Inactive) != 0) {
7229                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7230                                         }
7231                                         
7232                                         if (fill_rect) {
7233                                                 for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
7234                                                         dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
7235                                                         arrow [1].Y += 1;
7236                                                         arrow [2].Y -= 1;
7237                                                 }
7238                                         }
7239                                         break;
7240                                         
7241                                 case ScrollButton.Right:
7242                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7243                                         if (y_middle == 1)
7244                                                 y_middle = 2;
7245                                         
7246                                         if (rect.Width < 8) {
7247                                                 triangle_width = 2;
7248                                                 fill_rect = false;
7249                                         } else if (rect.Width == 11) {
7250                                                 triangle_width = 3;
7251                                         } else {
7252                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7253                                         }
7254                                         
7255                                         arrow [0].X = rect.Right - triangle_width - 1;
7256                                         arrow [0].Y = rect.Y + y_middle;
7257                                         
7258                                         if (arrow [0].X - 1 == rect.X)
7259                                                 arrow [0].X += 1;
7260                                         
7261                                         arrow [1].X = arrow [0].X - triangle_width + 1;
7262                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7263                                         arrow [2].X = arrow [1].X;
7264                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7265                                         
7266                                         dc.DrawPolygon (pen, arrow);
7267                                         
7268                                         if ((state & ButtonState.Inactive) != 0) {
7269                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7270                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
7271                                         }
7272                                         
7273                                         if (fill_rect) {
7274                                                 for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
7275                                                         dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
7276                                                         arrow [1].Y += 1;
7277                                                         arrow [2].Y -= 1;
7278                                                 }
7279                                         }
7280                                         break;
7281                         }
7282                 }
7283
7284                 public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
7285                         Color backColor) {
7286
7287                 }
7288
7289
7290                 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds)
7291                 {
7292                         Pen pen_dark = ResPool.GetPen(ControlPaint.Dark(backColor));
7293                         Pen pen_light_light = ResPool.GetPen(ControlPaint.LightLight(backColor));
7294                         
7295                         for (int i = 2; i < bounds.Width - 2; i += 4) {
7296                                 dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1);
7297                                 dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i);
7298                                 dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1);
7299                         }
7300                 }
7301
7302                 private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)
7303                 {
7304                         CPColor cpcolor = ResPool.GetCPColor (color);
7305
7306                         layoutRectangle.Offset (1, 1);
7307                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString);
7308
7309                         layoutRectangle.Offset (-1, -1);
7310                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString);
7311                 }
7312
7313                 public  override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)
7314                 {
7315                         CPColor cpcolor = ResPool.GetCPColor (color);
7316                         
7317                         dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight), 
7318                                        new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height),
7319                                        format);
7320                         dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
7321                 }
7322
7323 #if NET_2_0
7324                 public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
7325                 {
7326                         CPColor cpcolor = ResPool.GetCPColor (color);
7327
7328                         layoutRectangle.Offset (1, 1);
7329                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format);
7330
7331                         layoutRectangle.Offset (-1, -1);
7332                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format);
7333                 }
7334
7335                 public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
7336                 {
7337                         graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds);
7338                 }
7339 #endif
7340
7341                 private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY,
7342                         int width, Color color, ButtonBorderStyle style, Border3DSide side) 
7343                 {
7344                         DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY, 
7345                                 width, color, style, side);
7346                 }
7347
7348                 private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY,
7349                         int width, Color color, ButtonBorderStyle style, Border3DSide side) {
7350
7351                         Pen pen = null;
7352
7353                         switch (style) {
7354                         case ButtonBorderStyle.Solid:
7355                         case ButtonBorderStyle.Inset:
7356                         case ButtonBorderStyle.Outset:
7357                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid);
7358                                         break;
7359                         case ButtonBorderStyle.Dashed:
7360                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash);
7361                                         break;
7362                         case ButtonBorderStyle.Dotted:
7363                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot);
7364                                         break;
7365                         default:
7366                         case ButtonBorderStyle.None:
7367                                         return;
7368                         }
7369
7370                         switch(style) {
7371                         case ButtonBorderStyle.Outset: {
7372                                 Color           colorGrade;
7373                                 int             hue, brightness, saturation;
7374                                 int             brightnessSteps;
7375                                 int             brightnessDownSteps;
7376
7377                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7378
7379                                 brightnessDownSteps=brightness/width;
7380                                 if (brightness>127) {
7381                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7382                                 } else {
7383                                         brightnessSteps=(127-brightness)/width;
7384                                 }
7385
7386                                 for (int i=0; i<width; i++) {
7387                                         switch(side) {
7388                                         case Border3DSide.Left: {
7389                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7390                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7391                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7392                                                 break;
7393                                         }
7394
7395                                         case Border3DSide.Right: {
7396                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7397                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7398                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7399                                                 break;
7400                                         }
7401
7402                                         case Border3DSide.Top: {
7403                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7404                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7405                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7406                                                 break;
7407                                         }
7408
7409                                         case Border3DSide.Bottom: {
7410                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7411                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7412                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7413                                                 break;
7414                                         }
7415                                         }
7416                                 }
7417                                 break;
7418                         }
7419
7420                         case ButtonBorderStyle.Inset: {
7421                                 Color           colorGrade;
7422                                 int             hue, brightness, saturation;
7423                                 int             brightnessSteps;
7424                                 int             brightnessDownSteps;
7425
7426                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7427
7428                                 brightnessDownSteps=brightness/width;
7429                                 if (brightness>127) {
7430                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7431                                 } else {
7432                                         brightnessSteps=(127-brightness)/width;
7433                                 }
7434
7435                                 for (int i=0; i<width; i++) {
7436                                         switch(side) {
7437                                         case Border3DSide.Left: {
7438                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7439                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7440                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7441                                                 break;
7442                                         }
7443
7444                                         case Border3DSide.Right: {
7445                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7446                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7447                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7448                                                 break;
7449                                         }
7450
7451                                         case Border3DSide.Top: {
7452                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7453                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7454                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7455                                                 break;
7456                                         }
7457
7458                                         case Border3DSide.Bottom: {
7459                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7460                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7461                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7462                                                 break;
7463                                         }
7464                                         }
7465                                 }
7466                                 break;
7467                         }
7468
7469                                 /*
7470                                         I decided to have the for-loop duplicated for speed reasons;
7471                                         that way we only have to switch once (as opposed to have the
7472                                         for-loop around the switch)
7473                                 */
7474                         default: {
7475                                 switch(side) {
7476                                 case Border3DSide.Left: {
7477                                         for (int i=0; i<width; i++) {
7478                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7479                                         }
7480                                         break;
7481                                 }
7482
7483                                 case Border3DSide.Right: {
7484                                         for (int i=0; i<width; i++) {
7485                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7486                                         }
7487                                         break;
7488                                 }
7489
7490                                 case Border3DSide.Top: {
7491                                         for (int i=0; i<width; i++) {
7492                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7493                                         }
7494                                         break;
7495                                 }
7496
7497                                 case Border3DSide.Bottom: {
7498                                         for (int i=0; i<width; i++) {
7499                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7500                                         }
7501                                         break;
7502                                 }
7503                                 }
7504                                 break;
7505                         }
7506                         }
7507                 }
7508
7509                 /*
7510                         This function actually draws the various caption elements.
7511                         This way we can scale them nicely, no matter what size, and they
7512                         still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
7513                 */
7514
7515                 private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
7516                         switch(button) {
7517                         case CaptionButton.Close: {
7518                                 if (lineWidth<2) {
7519                                         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);
7520                                         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);
7521                                 }
7522
7523                                 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7524                                 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7525                                 return;
7526                         }
7527
7528                         case CaptionButton.Help: {
7529                                 StringFormat    sf = new StringFormat();                                
7530                                 Font                            font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
7531
7532                                 sf.Alignment=StringAlignment.Center;
7533                                 sf.LineAlignment=StringAlignment.Center;
7534
7535
7536                                 graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
7537
7538                                 sf.Dispose();                           
7539                                 font.Dispose();
7540
7541                                 return;
7542                         }
7543
7544                         case CaptionButton.Maximize: {
7545                                 /* Top 'caption bar' line */
7546                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7547                                         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);
7548                                 }
7549
7550                                 /* Left side line */
7551                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7552                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7553                                 }
7554
7555                                 /* Right side line */
7556                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7557                                         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);
7558                                 }
7559
7560                                 /* Bottom line */
7561                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7562                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7563                                 }
7564                                 return;
7565                         }
7566
7567                         case CaptionButton.Minimize: {
7568                                 /* Bottom line */
7569                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7570                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
7571                                 }
7572                                 return;
7573                         }
7574
7575                         case CaptionButton.Restore: {
7576                                 /** First 'window' **/
7577                                 /* Top 'caption bar' line */
7578                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7579                                         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);
7580                                 }
7581
7582                                 /* Left side line */
7583                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7584                                         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);
7585                                 }
7586
7587                                 /* Right side line */
7588                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7589                                         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);
7590                                 }
7591
7592                                 /* Bottom line */
7593                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7594                                         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);
7595                                 }
7596
7597                                 /** Second 'window' **/
7598                                 /* Top 'caption bar' line */
7599                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7600                                         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);
7601                                 }
7602
7603                                 /* Left side line */
7604                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7605                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7606                                 }
7607
7608                                 /* Right side line */
7609                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7610                                         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);
7611                                 }
7612
7613                                 /* Bottom line */
7614                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7615                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7616                                 }
7617
7618                                 return;
7619                         }
7620
7621                         }
7622                 }
7623
7624                 /* Generic scroll button */
7625                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
7626                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
7627                                 dc.FillRectangle (SystemBrushes.Control, area.X + 1,
7628                                         area.Y + 1, area.Width - 2 , area.Height - 2);
7629
7630                                 dc.DrawRectangle (SystemPens.ControlDark, area.X,
7631                                         area.Y, area.Width, area.Height);
7632
7633                                 return;
7634                         }                       
7635         
7636                         Brush sb_control = SystemBrushes.Control;
7637                         Brush sb_lightlight = SystemBrushes.ControlLightLight;
7638                         Brush sb_dark = SystemBrushes.ControlDark;
7639                         Brush sb_darkdark = SystemBrushes.ControlDarkDark;
7640                         
7641                         dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1);
7642                         dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height);
7643
7644                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1);
7645                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1,
7646                                 area.Height - 4);
7647                         
7648                         dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2,
7649                                 area.Width - 2, 1);
7650
7651                         dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1,
7652                                 area.Width , 1);
7653
7654                         dc.FillRectangle (sb_dark, area.X + area.Width - 2,
7655                                 area.Y + 1, 1, area.Height -3);
7656
7657                         dc.FillRectangle (sb_darkdark, area.X + area.Width -1,
7658                                 area.Y, 1, area.Height - 1);
7659
7660                         dc.FillRectangle (sb_control, area.X + 2,
7661                                 area.Y + 2, area.Width - 4, area.Height - 4);
7662                         
7663                 }
7664                 
7665                 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
7666                         switch (border_style){
7667                         case BorderStyle.Fixed3D:
7668                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
7669                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
7670                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width , 
7671                                         area.Y + area.Height - 1);
7672                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, 
7673                                         area.Y + area.Height);
7674
7675                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
7676                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
7677                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
7678                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
7679                                 break;
7680                         case BorderStyle.FixedSingle:
7681                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
7682                                 break;
7683                         case BorderStyle.None:
7684                         default:
7685                                 break;
7686                         }
7687                         
7688                 }
7689                 #endregion      // ControlPaint
7690
7691
7692         } //class
7693 }