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