2008-11-02 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.UsingGroups) {
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 (Application.VisualStylesEnabled && 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 #if NET_2_0
2756                                                 int image_index;
2757                                                 if (control.SmallImageList == null)
2758                                                         image_index = -1;
2759                                                 else 
2760                                                         image_index = col.ImageKey == String.Empty ? col.ImageIndex : control.SmallImageList.Images.IndexOfKey (col.ImageKey);
2761
2762                                                 if (image_index > -1 && image_index < control.SmallImageList.Images.Count) {
2763                                                         int image_width = control.SmallImageList.ImageSize.Width + 5;
2764                                                         int text_width = (int)dc.MeasureString (col.Text, control.Font).Width;
2765                                                         int x_origin = rect.X;
2766
2767                                                         switch (col.TextAlign) {
2768                                                                 case HorizontalAlignment.Left:
2769                                                                         break;
2770                                                                 case HorizontalAlignment.Right:
2771                                                                         x_origin = rect.Right - (text_width + image_width);
2772                                                                         break;
2773                                                                 case HorizontalAlignment.Center:
2774                                                                         x_origin = (rect.Width - (text_width + image_width)) / 2 + rect.X;
2775                                                                         break;
2776                                                         }
2777
2778                                                         if (x_origin < rect.X)
2779                                                                 x_origin = rect.X;
2780
2781                                                         control.SmallImageList.Draw (dc, new Point (x_origin, rect.Y), image_index);
2782                                                         rect.X += image_width;
2783                                                         rect.Width -= image_width;
2784                                                 }
2785 #endif
2786
2787                                                 dc.DrawString (col.Text, control.Font, SystemBrushes.ControlText, rect, col.Format);
2788                                         }
2789                                         int right = control.GetReorderedColumn (control.Columns.Count - 1).Rect.Right - control.h_marker;
2790                                         if (right < control.Right) {
2791                                                 Rectangle rect = control.Columns [0].Rect;
2792                                                 rect.X = right;
2793                                                 rect.Width = control.Right - right;
2794                                                 ListViewDrawUnusedHeaderBackground (control, dc, rect, clip);
2795                                         }
2796                                 }
2797                         }
2798                 }
2799
2800                 protected virtual void ListViewDrawColumnHeaderBackground (ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea)
2801                 {
2802                         ButtonState state;
2803                         if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2804                                 state = columnHeader.Pressed ? ButtonState.Pushed : ButtonState.Normal;
2805                         else
2806                                 state = ButtonState.Flat;
2807                         CPDrawButton (g, area, state);
2808                 }
2809                 
2810                 protected virtual void ListViewDrawUnusedHeaderBackground (ListView listView, Graphics g, Rectangle area, Rectangle clippingArea)
2811                 {
2812                         ButtonState state;
2813                         if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2814                                 state = ButtonState.Normal;
2815                         else
2816                                 state = ButtonState.Flat;
2817                         CPDrawButton (g, area, state);
2818                 }
2819
2820                 public override void DrawListViewHeaderDragDetails (Graphics dc, ListView view, ColumnHeader col, int target_x)
2821                 {
2822                         Rectangle rect = col.Rect;
2823                         rect.X -= view.h_marker;
2824                         Color color = Color.FromArgb (0x7f, ColorControlDark.R, ColorControlDark.G, ColorControlDark.B);
2825                         dc.FillRectangle (ResPool.GetSolidBrush (color), rect);
2826                         rect.X += 3;
2827                         rect.Width -= 8;
2828                         if (rect.Width <= 0)
2829                                 return;
2830                         color = Color.FromArgb (0x7f, ColorControlText.R, ColorControlText.G, ColorControlText.B);
2831                         dc.DrawString (col.Text, view.Font, ResPool.GetSolidBrush (color), rect, col.Format);
2832                         dc.DrawLine (ResPool.GetSizedPen (ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height);
2833                 }
2834
2835 #if NET_2_0
2836                 protected virtual bool DrawListViewColumnHeaderOwnerDraw (Graphics dc, ListView control, ColumnHeader column, Rectangle bounds)
2837                 {
2838                         ListViewItemStates state = ListViewItemStates.ShowKeyboardCues;
2839                         if (column.Pressed)
2840                                 state |= ListViewItemStates.Selected;
2841
2842                         DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs (dc,
2843                                         bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont);
2844                         control.OnDrawColumnHeader (args);
2845
2846                         return !args.DrawDefault;
2847                 }
2848
2849                 protected virtual bool DrawListViewItemOwnerDraw (Graphics dc, ListViewItem item, int index)
2850                 {
2851                         ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues;
2852                         if (item.Selected)
2853                                 item_state |= ListViewItemStates.Selected;
2854                         if (item.Focused)
2855                                 item_state |= ListViewItemStates.Focused;
2856                                                 
2857                         DrawListViewItemEventArgs args = new DrawListViewItemEventArgs (dc,
2858                                         item, item.Bounds, index, item_state);
2859                         item.ListView.OnDrawItem (args);
2860
2861                         if (args.DrawDefault)
2862                                 return false;
2863
2864                         if (item.ListView.View == View.Details) {
2865                                 int count = Math.Min (item.ListView.Columns.Count, item.SubItems.Count);
2866                                 
2867                                 // Do system drawing for subitems if no owner draw is done
2868                                 for (int j = 0; j < count; j++) {
2869                                         if (!DrawListViewSubItemOwnerDraw (dc, item, item_state, j)) {
2870                                                 if (j == 0) // The first sub item contains the main item semantics
2871                                                         DrawListViewItem (dc, item.ListView, item);
2872                                                 else
2873                                                         DrawListViewSubItem (dc, item.ListView, item, j);
2874                                         }
2875                                 }
2876                         }
2877                         
2878                         return true;
2879                 }
2880 #endif
2881
2882                 protected virtual void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
2883                 {                               
2884                         Rectangle rect_checkrect = item.CheckRectReal;
2885                         Rectangle icon_rect = item.GetBounds (ItemBoundsPortion.Icon);
2886                         Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire);
2887                         Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);                 
2888
2889 #if NET_2_0
2890                         // Tile view doesn't support CheckBoxes
2891                         if (control.CheckBoxes && control.View != View.Tile) {
2892 #else
2893                         if (control.CheckBoxes) {
2894 #endif
2895                                 if (control.StateImageList == null) {
2896                                         // Make sure we've got at least a line width of 1
2897                                         int check_wd = Math.Max (3, rect_checkrect.Width / 6);
2898                                         int scale = Math.Max (1, rect_checkrect.Width / 12);
2899
2900                                         // set the checkbox background
2901                                         dc.FillRectangle (SystemBrushes.Window,
2902                                                           rect_checkrect);
2903                                         // define a rectangle inside the border area
2904                                         Rectangle rect = new Rectangle (rect_checkrect.X + 2,
2905                                                                         rect_checkrect.Y + 2,
2906                                                                         rect_checkrect.Width - 4,
2907                                                                         rect_checkrect.Height - 4);
2908                                         Pen pen = ResPool.GetSizedPen (this.ColorWindowText, 2);
2909                                         dc.DrawRectangle (pen, rect);
2910
2911                                         // Need to draw a check-mark
2912                                         if (item.Checked) {
2913                                                 Pen check_pen = ResPool.GetSizedPen (this.ColorWindowText, 1);
2914                                                 // adjustments to get the check-mark at the right place
2915                                                 rect.X ++; rect.Y ++;
2916                                                 // following logic is taken from DrawFrameControl method
2917                                                 int x_offset = rect.Width / 5;
2918                                                 int y_offset = rect.Height / 3;
2919                                                 for (int i = 0; i < check_wd; i++) {
2920                                                         dc.DrawLine (check_pen, rect.Left + x_offset,
2921                                                                      rect.Top + y_offset + i,
2922                                                                      rect.Left + x_offset + 2 * scale,
2923                                                                      rect.Top + y_offset + 2 * scale + i);
2924                                                         dc.DrawLine (check_pen,
2925                                                                      rect.Left + x_offset + 2 * scale,
2926                                                                      rect.Top + y_offset + 2 * scale + i,
2927                                                                      rect.Left + x_offset + 6 * scale,
2928                                                                      rect.Top + y_offset - 2 * scale + i);
2929                                                 }
2930                                         }
2931                                 }
2932                                 else {
2933                                         int simage_idx;
2934                                         if (item.Checked)
2935 #if NET_2_0
2936                                                 simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1;
2937 #else
2938                                                 simage_idx = control.StateImageList.Images.Count > 1 ? 1 : 0;
2939 #endif
2940                                         else
2941                                                 simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1;
2942
2943                                         if (simage_idx > -1)
2944                                                 control.StateImageList.Draw (dc, rect_checkrect.Location, simage_idx);
2945                                 }
2946                         }
2947
2948                         ImageList image_list = control.View == View.LargeIcon 
2949 #if NET_2_0
2950                                 || control.View == View.Tile
2951 #endif
2952                                 ? control.LargeImageList : control.SmallImageList;
2953                         if (image_list != null) {
2954                                 int idx;
2955
2956 #if NET_2_0
2957                                 if (item.ImageKey != String.Empty)
2958                                         idx = image_list.Images.IndexOfKey (item.ImageKey);
2959                                 else
2960 #endif
2961                                         idx = item.ImageIndex;
2962
2963                                 if (idx > -1 && idx < image_list.Images.Count)
2964                                         image_list.Draw (dc, icon_rect.Location, idx);
2965                         }
2966
2967                         // draw the item text                   
2968                         // format for the item text
2969                         StringFormat format = new StringFormat ();
2970                         if (control.View == View.SmallIcon || control.View == View.LargeIcon)
2971                                 format.LineAlignment = StringAlignment.Near;
2972                         else
2973                                 format.LineAlignment = StringAlignment.Center;
2974                         if (control.View == View.LargeIcon)
2975                                 format.Alignment = StringAlignment.Center;
2976                         else
2977                                 format.Alignment = StringAlignment.Near;
2978                         
2979 #if NET_2_0
2980                         if (control.LabelWrap && control.View != View.Details && control.View != View.Tile)
2981 #else
2982                         if (control.LabelWrap && control.View != View.Details)
2983 #endif
2984                                 format.FormatFlags = StringFormatFlags.LineLimit;
2985                         else
2986                                 format.FormatFlags = StringFormatFlags.NoWrap;
2987
2988                         if ((control.View == View.LargeIcon && !item.Focused)
2989                                         || control.View == View.Details 
2990 #if NET_2_0
2991                                         || control.View == View.Tile
2992 #endif
2993                            )
2994                                 format.Trimming = StringTrimming.EllipsisCharacter;
2995
2996                         Rectangle highlight_rect = text_rect;
2997                         if (control.View == View.Details) { // Adjustments for Details view
2998                                 Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
2999
3000                                 if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
3001                                         highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
3002                         }
3003
3004                         if (item.Selected && control.Focused)
3005                                 dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
3006                         else if (item.Selected && !control.HideSelection)
3007                                 dc.FillRectangle (SystemBrushes.Control, highlight_rect);
3008                         else
3009                                 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
3010                         
3011                         Brush textBrush =
3012                                 !control.Enabled ? SystemBrushes.ControlLight :
3013                                 (item.Selected && control.Focused) ? SystemBrushes.HighlightText :
3014                                 this.ResPool.GetSolidBrush (item.ForeColor);
3015
3016 #if NET_2_0
3017                         // Tile view renders its Text in a different fashion
3018                         if (control.View == View.Tile) {
3019                                 // Item.Text is drawn using its first subitem's bounds
3020                                 dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
3021
3022                                 int count = Math.Min (control.Columns.Count, item.SubItems.Count);
3023                                 for (int i = 1; i < count; i++) {
3024                                         ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
3025                                         if (sub_item.Text == null || sub_item.Text.Length == 0)
3026                                                 continue;
3027
3028                                         Brush itemBrush = item.Selected && control.Focused ? 
3029                                                 SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
3030                                         dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
3031                                 }
3032                         } else
3033 #endif
3034                         
3035                         if (item.Text != null && item.Text.Length > 0) {
3036                                 Font font = item.Font;
3037 #if NET_2_0
3038                                 if (control.HotTracking && item.Hot)
3039                                         font = item.HotFont;
3040 #endif
3041
3042                                 if (item.Selected && control.Focused)
3043                                         dc.DrawString (item.Text, font, textBrush, highlight_rect, format);
3044                                 else
3045                                         dc.DrawString (item.Text, font, textBrush, text_rect, format);
3046                         }
3047
3048                         if (item.Focused && control.Focused) {                          
3049                                 Rectangle focus_rect = highlight_rect;
3050                                 if (control.FullRowSelect && control.View == View.Details) {
3051                                         int width = 0;
3052                                         foreach (ColumnHeader col in control.Columns)
3053                                                 width += col.Width;
3054                                         focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height);
3055                                 }
3056                                 if (item.Selected)
3057                                         CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight);
3058                                 else
3059                                         CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor);
3060                         }
3061
3062                         format.Dispose ();
3063                 }
3064
3065                 protected virtual void DrawListViewSubItems (Graphics dc, ListView control, ListViewItem item)
3066                 {
3067                         int columns_count = control.Columns.Count;
3068                         int count = Math.Min (item.SubItems.Count, columns_count);
3069                         // 0th item already done (in this case)
3070                         for (int i = 1; i < count; i++)
3071                                 DrawListViewSubItem (dc, control, item, i);
3072
3073                         // Fill in selection for remaining columns if Column.Count > SubItems.Count
3074                         Rectangle sub_item_rect = item.GetBounds (ItemBoundsPortion.Label);
3075                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3076                                 for (int index = count; index < columns_count; index++) {
3077                                         ColumnHeader col = control.Columns [index];
3078                                         sub_item_rect.X = col.Rect.X - control.h_marker;
3079                                         sub_item_rect.Width = col.Wd;
3080                                         dc.FillRectangle (control.Focused ? SystemBrushes.Highlight : SystemBrushes.Control, 
3081                                                         sub_item_rect);
3082                                 }
3083                         }
3084                 }
3085
3086                 protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index)
3087                 {
3088                         ListViewItem.ListViewSubItem subItem = item.SubItems [index];
3089                         ColumnHeader col = control.Columns [index];
3090                         StringFormat format = new StringFormat ();
3091                         format.Alignment = col.Format.Alignment;
3092                         format.LineAlignment = StringAlignment.Center;
3093                         format.FormatFlags = StringFormatFlags.NoWrap;
3094                         format.Trimming = StringTrimming.EllipsisCharacter;
3095
3096                         Rectangle sub_item_rect = subItem.Bounds;
3097                         Rectangle sub_item_text_rect = sub_item_rect;
3098                         sub_item_text_rect.X += 3;
3099                         sub_item_text_rect.Width -= ListViewItemPaddingWidth;
3100                                                 
3101                         SolidBrush sub_item_back_br = null;
3102                         SolidBrush sub_item_fore_br = null;
3103                         Font sub_item_font = null;
3104                                                 
3105                         if (item.UseItemStyleForSubItems) {
3106                                 sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
3107                                 sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
3108 #if NET_2_0
3109                                 // Hot tracking for subitems only applies when UseStyle is true
3110                                 if (control.HotTracking && item.Hot)
3111                                         sub_item_font = item.HotFont;
3112                                 else
3113 #endif
3114                                         sub_item_font = item.Font;
3115                         } else {
3116                                 sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
3117                                 sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
3118                                 sub_item_font = subItem.Font;
3119                         }
3120                                                 
3121                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3122                                 Brush bg, text;
3123                                 if (control.Focused) {
3124                                         bg = SystemBrushes.Highlight;
3125                                         text = SystemBrushes.HighlightText;
3126                                 } else {
3127                                         bg = SystemBrushes.Control;
3128                                         text = sub_item_fore_br;
3129                                                         
3130                                 }
3131                                                         
3132                                 dc.FillRectangle (bg, sub_item_rect);
3133                                 if (subItem.Text != null && subItem.Text.Length > 0)
3134                                         dc.DrawString (subItem.Text, sub_item_font,
3135                                                         text, sub_item_text_rect, format);
3136                         } else {
3137                                 dc.FillRectangle (sub_item_back_br, sub_item_rect);
3138                                 if (subItem.Text != null && subItem.Text.Length > 0)
3139                                         dc.DrawString (subItem.Text, sub_item_font,
3140                                                         sub_item_fore_br,
3141                                                         sub_item_text_rect, format);
3142                         }
3143
3144                         format.Dispose ();
3145                 }
3146
3147 #if NET_2_0
3148                 protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index)
3149                 {
3150                         ListView control = item.ListView;
3151                         ListViewItem.ListViewSubItem subitem = item.SubItems [index];
3152
3153                         DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item, 
3154                                         subitem, item.Index, index, control.Columns [index], state);
3155                         control.OnDrawSubItem (args);
3156                         
3157                         return !args.DrawDefault;
3158                 }
3159
3160                 protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group)
3161                 {
3162                         Rectangle text_bounds = group.HeaderBounds;
3163                         Rectangle header_bounds = group.HeaderBounds;
3164                         text_bounds.Offset (8, 0);
3165                         text_bounds.Inflate (-8, 0);
3166                         Size text_size = control.text_size;
3167
3168                         Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
3169                         Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0), 
3170                                         SystemColors.Desktop, Color.White);
3171                         Pen pen = new Pen (brush);
3172
3173                         StringFormat sformat = new StringFormat ();
3174                         switch (group.HeaderAlignment) {
3175                                 case HorizontalAlignment.Left:
3176                                         sformat.Alignment = StringAlignment.Near;
3177                                         break;
3178                                 case HorizontalAlignment.Center:
3179                                         sformat.Alignment = StringAlignment.Center;
3180                                         break;
3181                                 case HorizontalAlignment.Right:
3182                                         sformat.Alignment = StringAlignment.Far;
3183                                         break;
3184                         }
3185
3186                         sformat.LineAlignment = StringAlignment.Near;
3187                         dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat);
3188                         dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_size.Height, header_bounds.Left + ListViewGroupLineWidth, 
3189                                         header_bounds.Top + text_size.Height);
3190
3191                         sformat.Dispose ();
3192                         font.Dispose ();
3193                         pen.Dispose ();
3194                         brush.Dispose ();
3195                 }
3196 #endif
3197
3198                 public override bool ListViewHasHotHeaderStyle {
3199                         get {
3200                                 return false;
3201                         }
3202                 }
3203
3204                 // Sizing
3205                 public override int ListViewGetHeaderHeight (ListView listView, Font font)
3206                 {
3207                         return ListViewGetHeaderHeight (font);
3208                 }
3209
3210                 static int ListViewGetHeaderHeight (Font font)
3211                 {
3212                         return font.Height + 5;
3213                 }
3214
3215                 public static int ListViewGetHeaderHeight ()
3216                 {
3217                         return ListViewGetHeaderHeight (ThemeEngine.Current.DefaultFont);
3218                 }
3219
3220                 public override Size ListViewCheckBoxSize {
3221                         get { return new Size (16, 16); }
3222                 }
3223
3224                 public override int ListViewColumnHeaderHeight {
3225                         get { return 16; }
3226                 }
3227
3228                 public override int ListViewDefaultColumnWidth {
3229                         get { return 60; }
3230                 }
3231
3232                 public override int ListViewVerticalSpacing {
3233                         get { return 22; }
3234                 }
3235
3236                 public override int ListViewEmptyColumnWidth {
3237                         get { return 10; }
3238                 }
3239
3240                 public override int ListViewHorizontalSpacing {
3241                         get { return 4; }
3242                 }
3243
3244                 public override int ListViewItemPaddingWidth {
3245                         get { return 6; }
3246                 }
3247
3248                 public override Size ListViewDefaultSize {
3249                         get { return new Size (121, 97); }
3250                 }
3251
3252                 public override int ListViewGroupHeight { 
3253                         get { return 20; }
3254                 }
3255
3256                 public int ListViewGroupLineWidth {
3257                         get { return 200; }
3258                 }
3259
3260                 public override int ListViewTileWidthFactor {
3261                         get { return 22; }
3262                 }
3263
3264                 public override int ListViewTileHeightFactor {
3265                         get { return 3; }
3266                 }
3267                 #endregion      // ListView
3268                 
3269                 #region Menus
3270                 
3271                 public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
3272                 {
3273                         item.X = x;
3274                         item.Y = y;
3275
3276                         if (item.Visible == false) {
3277                                 item.Width = 0;
3278                                 item.Height = 0;
3279                                 return;
3280                         }
3281
3282                         if (item.Separator == true) {
3283                                 item.Height = SEPARATOR_HEIGHT;
3284                                 item.Width = SEPARATOR_MIN_WIDTH;
3285                                 return;
3286                         }
3287                         
3288                         if (item.MeasureEventDefined) {
3289                                 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
3290                                 item.PerformMeasureItem (mi);
3291                                 item.Height = mi.ItemHeight;
3292                                 item.Width = mi.ItemWidth;
3293                                 return;
3294                         } else {                
3295                                 SizeF size;
3296                                 size =  dc.MeasureString (item.Text, MenuFont, int.MaxValue, string_format_menu_text);
3297                                 item.Width = (int) size.Width;
3298                                 item.Height = (int) size.Height;
3299         
3300                                 if (!menuBar) {
3301                                         if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
3302                                                 item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
3303                                                 size =  dc.MeasureString (" " + item.GetShortCutText (), MenuFont);
3304                                                 item.Width += MENU_TAB_SPACE + (int) size.Width;
3305                                         }
3306         
3307                                         item.Width += 4 + (MenuCheckSize.Width * 2);
3308                                 } else {
3309                                         item.Width += MENU_BAR_ITEMS_SPACE;
3310                                         x += item.Width;
3311                                 }
3312         
3313                                 if (item.Height < MenuHeight)
3314                                         item.Height = MenuHeight;
3315                         }
3316                 }
3317                 
3318                 // Updates the menu rect and returns the height
3319                 public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
3320                 {
3321                         int x = 0;
3322                         int y = 0;
3323                         menu.Height = 0;
3324
3325                         foreach (MenuItem item in menu.MenuItems) {
3326
3327                                 CalcItemSize (dc, item, y, x, true);
3328
3329                                 if (x + item.Width > width) {
3330                                         item.X = 0;
3331                                         y += item.Height;
3332                                         item.Y = y;
3333                                         x = 0;
3334                                 }
3335
3336                                 x += item.Width;
3337                                 item.MenuBar = true;                            
3338
3339                                 if (y + item.Height > menu.Height)
3340                                         menu.Height = item.Height + y;
3341                         }
3342
3343                         menu.Width = width;                                             
3344                         return menu.Height;
3345                 }
3346
3347                 public override void CalcPopupMenuSize (Graphics dc, Menu menu)
3348                 {
3349                         int x = 3;
3350                         int start = 0;
3351                         int i, n, y, max;
3352
3353                         menu.Height = 0;
3354
3355                         while (start < menu.MenuItems.Count) {
3356                                 y = 3;
3357                                 max = 0;
3358                                 for (i = start; i < menu.MenuItems.Count; i++) {
3359                                         MenuItem item = menu.MenuItems [i];
3360
3361                                         if ((i != start) && (item.Break || item.BarBreak))
3362                                                 break;
3363
3364                                         CalcItemSize (dc, item, y, x, false);
3365                                         y += item.Height;
3366
3367                                         if (item.Width > max)
3368                                                 max = item.Width;
3369                                 }
3370
3371                                 // Replace the -1 by the menu width (separators)
3372                                 for (n = start; n < i; n++, start++)
3373                                         menu.MenuItems [n].Width = max;
3374
3375                                 if (y > menu.Height)
3376                                         menu.Height = y;
3377
3378                                 x+= max;
3379                         }
3380
3381                         menu.Width = x;
3382                         
3383                         //space for border
3384                         menu.Width += 2;
3385                         menu.Height += 2;
3386
3387                         menu.Width += SM_CXBORDER;
3388                 menu.Height += SM_CYBORDER;
3389                 }
3390                 
3391                 // Draws a menu bar in a window
3392                 public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
3393                 {
3394                         if (menu.Height == 0)
3395                                 CalcMenuBarSize (dc, menu, rect.Width);
3396
3397                         bool keynav = (menu as MainMenu).tracker.hotkey_active;
3398                         HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
3399                         string_format_menu_menubar_text.HotkeyPrefix = hp;
3400                         string_format_menu_text.HotkeyPrefix = hp;
3401
3402                         rect.Height = menu.Height;
3403                         dc.FillRectangle (SystemBrushes.Menu, rect);
3404                         
3405                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3406                                 MenuItem item = menu.MenuItems [i];
3407                                 Rectangle item_rect = item.bounds;
3408                                 item_rect.X += rect.X;
3409                                 item_rect.Y += rect.Y;
3410                                 item.MenuHeight = menu.Height;
3411                                 item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status)); 
3412                         }       
3413                 }               
3414                 
3415                 protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color)
3416                 {
3417                         Color bg_color;
3418                         if (color.R == 0 && color.G == 0 && color.B == 0)
3419                                 bg_color = Color.White;
3420                         else
3421                                 bg_color = Color.Black;
3422                         
3423                         Bitmap  bmp = new Bitmap (size.Width, size.Height);
3424                         Graphics gr = Graphics.FromImage (bmp);
3425                         Rectangle rect = new Rectangle (Point.Empty, size);
3426                         gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
3427                         CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty);
3428                         bmp.MakeTransparent (bg_color);
3429                         gr.Dispose ();
3430                         
3431                         return bmp;
3432                 }
3433
3434                 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
3435                 {
3436                         StringFormat string_format;
3437                         Rectangle rect_text = e.Bounds;
3438                         
3439                         if (item.Visible == false)
3440                                 return;
3441
3442                         if (item.MenuBar)
3443                                 string_format = string_format_menu_menubar_text;
3444                         else
3445                                 string_format = string_format_menu_text;
3446
3447                         if (item.Separator == true) {
3448                                 int liney = e.Bounds.Y + (e.Bounds.Height / 2);
3449                                 
3450                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3451                                         e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney);
3452
3453                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3454                                         e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1);
3455
3456                                 return;
3457                         }
3458
3459                         if (!item.MenuBar)
3460                                 rect_text.X += MenuCheckSize.Width;
3461
3462                         if (item.BarBreak) { /* Draw vertical break bar*/
3463                                 Rectangle rect = e.Bounds;
3464                                 rect.Y++;
3465                                 rect.Width = 3;
3466                                 rect.Height = item.MenuHeight - 6;
3467
3468                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3469                                         rect.X, rect.Y , rect.X, rect.Y + rect.Height);
3470
3471                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3472                                         rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
3473                         }                       
3474                         
3475                         Color color_text;
3476                         Color color_back;
3477                         Brush brush_text = null;
3478                         Brush brush_back = null;
3479                         
3480                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) {
3481                                 color_text = ColorHighlightText;
3482                                 color_back = ColorHighlight;
3483                                 brush_text = SystemBrushes.HighlightText;
3484                                 brush_back = SystemBrushes.Highlight;
3485                         } else {
3486                                 color_text = ColorMenuText;
3487                                 color_back = ColorMenu;
3488                                 brush_text = ResPool.GetSolidBrush (ColorMenuText);
3489                                 brush_back = SystemBrushes.Menu;
3490                         }
3491
3492                         /* Draw background */
3493                         if (!item.MenuBar)
3494                                 e.Graphics.FillRectangle (brush_back, e.Bounds);
3495                         
3496                         if (item.Enabled) {
3497                                 e.Graphics.DrawString (item.Text, e.Font,
3498                                         brush_text,
3499                                         rect_text, string_format);
3500                                 
3501                                 if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
3502                                         string str = item.GetShortCutText ();
3503                                         Rectangle rect = rect_text;
3504                                         rect.X = item.XTab;
3505                                         rect.Width -= item.XTab;
3506
3507                                         e.Graphics.DrawString (str, e.Font, brush_text,
3508                                                 rect, string_format_menu_shortcut);
3509                                 }
3510                                 
3511                                 if (item.MenuBar) {
3512                                         Border3DStyle border_style = Border3DStyle.Adjust;
3513                                         if ((item.Status & DrawItemState.HotLight) != 0)
3514                                                 border_style = Border3DStyle.RaisedInner;
3515                                         else if ((item.Status & DrawItemState.Selected) != 0)
3516                                                 border_style = Border3DStyle.SunkenOuter;
3517                                         
3518                                         if (border_style != Border3DStyle.Adjust)
3519                                                 CPDrawBorder3D(e.Graphics, e.Bounds, border_style,  Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu);
3520                                 }
3521                         } else {
3522                                 if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3523                                         e.Graphics.DrawString (item.Text, e.Font, Brushes.White, 
3524                                                                new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height),
3525                                                                string_format);
3526                                 }
3527                                 
3528                                 e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format);
3529                         }
3530
3531                         /* Draw arrow */
3532                         if (item.MenuBar == false && (item.IsPopup || item.MdiList)) {
3533
3534                                 int cx = MenuCheckSize.Width;
3535                                 int cy = MenuCheckSize.Height;
3536                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text);
3537                                 
3538                                 if (item.Enabled) {
3539                                         e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
3540                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
3541                                 } else {
3542                                         ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
3543                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
3544                                 }
3545  
3546                                 bmp.Dispose ();
3547                         }
3548
3549                         /* Draw checked or radio */
3550                         if (item.MenuBar == false && item.Checked) {
3551
3552                                 Rectangle area = e.Bounds;
3553                                 int cx = MenuCheckSize.Width;
3554                                 int cy = MenuCheckSize.Height;
3555                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text);
3556
3557                                 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
3558
3559                                 bmp.Dispose ();
3560                         }                       
3561                 }               
3562                         
3563                 public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
3564                 {
3565                         // Fill rectangle area
3566                         dc.FillRectangle (SystemBrushes.Menu, cliparea);
3567                         
3568                         // Draw menu borders
3569                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
3570                         
3571                         // Draw menu items
3572                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3573                                 if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
3574                                         MenuItem item = menu.MenuItems [i];
3575                                         item.MenuHeight = menu.Height;
3576                                         item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status));
3577                                 }
3578                         }
3579                 }
3580                 
3581                 #endregion // Menus
3582
3583                 #region MonthCalendar
3584
3585                 // draw the month calendar
3586                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) 
3587                 {
3588                         Rectangle client_rectangle = mc.ClientRectangle;
3589                         Size month_size = mc.SingleMonthSize;
3590                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3591                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
3592                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3593                         
3594                         // draw the singlecalendars
3595                         int x_offset = 1;
3596                         int y_offset = 1;
3597                         // adjust for the position of the specific month
3598                         for (int i=0; i < mc.CalendarDimensions.Height; i++) 
3599                         {
3600                                 if (i > 0) 
3601                                 {
3602                                         y_offset += month_size.Height + calendar_spacing.Height;
3603                                 }
3604                                 // now adjust for x position    
3605                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) 
3606                                 {
3607                                         if (j > 0) 
3608                                         {
3609                                                 x_offset += month_size.Width + calendar_spacing.Width;
3610                                         } 
3611                                         else 
3612                                         {
3613                                                 x_offset = 1;
3614                                         }
3615
3616                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
3617                                         if (month_rect.IntersectsWith (clip_rectangle)) {
3618                                                 DrawSingleMonth (
3619                                                         dc,
3620                                                         clip_rectangle,
3621                                                         month_rect,
3622                                                         mc,
3623                                                         i,
3624                                                         j);
3625                                         }
3626                                 }
3627                         }
3628                         
3629                         Rectangle bottom_rect = new Rectangle (
3630                                                 client_rectangle.X,
3631                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
3632                                                 client_rectangle.Width,
3633                                                 date_cell_size.Height + 2);
3634                         // draw the today date if it's set
3635                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) 
3636                         {
3637                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect);
3638                                 if (mc.ShowToday) {
3639                                         int today_offset = 5;
3640                                         if (mc.ShowTodayCircle) 
3641                                         {
3642                                                 Rectangle today_circle_rect = new Rectangle (
3643                                                         client_rectangle.X + 5,
3644                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
3645                                                         date_cell_size.Width,
3646                                                         date_cell_size.Height);
3647                                                         DrawTodayCircle (dc, today_circle_rect);
3648                                                 today_offset += date_cell_size.Width + 5;
3649                                         }
3650                                         // draw today's date
3651                                         StringFormat text_format = new StringFormat();
3652                                         text_format.LineAlignment = StringAlignment.Center;
3653                                         text_format.Alignment = StringAlignment.Near;
3654                                         Rectangle today_rect = new Rectangle (
3655                                                         today_offset + client_rectangle.X,
3656                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
3657                                                         Math.Max(client_rectangle.Width - today_offset, 0),
3658                                                         date_cell_size.Height);
3659                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format);
3660                                         text_format.Dispose ();
3661                                 }                               
3662                         }
3663                         
3664                         Brush border_brush;
3665                         
3666                         if (mc.owner == null)
3667                                 border_brush = GetControlBackBrush (mc.BackColor);
3668                         else
3669                                 border_brush = SystemBrushes.ControlDarkDark;
3670                                 
3671                         // finally paint the borders of the calendars as required
3672                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
3673                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
3674                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height);
3675                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
3676                                         dc.FillRectangle (border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height);
3677                                 } else { 
3678                                         Rectangle rect = new Rectangle (
3679                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
3680                                                 client_rectangle.Y,
3681                                                 calendar_spacing.Width,
3682                                                 client_rectangle.Height);
3683                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3684                                                 dc.FillRectangle (border_brush, rect);
3685                                         }
3686                                 }
3687                         }
3688                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
3689                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
3690                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1);
3691                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
3692                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1);
3693                                 } else { 
3694                                         Rectangle rect = new Rectangle (
3695                                                 client_rectangle.X,
3696                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
3697                                                 client_rectangle.Width,
3698                                                 calendar_spacing.Height);
3699                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3700                                                 dc.FillRectangle (border_brush, rect);
3701                                         }
3702                                 }
3703                         }
3704                         
3705                         // draw the drop down border if need
3706                         if (mc.owner != null) {
3707                                 Rectangle bounds = mc.ClientRectangle;
3708                                 if (clip_rectangle.Contains (mc.Location)) {
3709                                         // find out if top or left line to draw
3710                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3711                                         
3712                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
3713                                         }
3714                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3715                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
3716                                         }
3717                                 }
3718                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
3719                                         // find out if bottom or right line to draw
3720                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3721                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
3722                                         }
3723                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3724                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
3725                                         }
3726                                 }
3727                         }
3728                 }
3729
3730                 // darws a single part of the month calendar (with one month)
3731                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) 
3732                 {
3733                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3734                         Size title_size = (Size)((object)mc.title_size);
3735                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3736                         DateTime current_month = (DateTime)((object)mc.current_month);
3737                         DateTime sunday = new DateTime(2006, 10, 1);
3738                         
3739                         // draw the title back ground
3740                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
3741                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
3742                         if (title_rect.IntersectsWith (clip_rectangle)) {
3743                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
3744                                 // draw the title                               
3745                                 string title_text = this_month.ToString ("MMMM yyyy");
3746                                 dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format);
3747
3748                                 if (mc.ShowYearUpDown) {
3749                                         Rectangle year_rect;
3750                                         Rectangle upRect, downRect;
3751                                         ButtonState upState, downState;
3752                                         
3753                                         mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect);
3754                                         dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect);
3755                                         dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format);
3756                                         
3757                                         upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal;
3758                                         downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal;
3759
3760                                         ControlPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState);
3761                                         ControlPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState);
3762                                 }
3763
3764                                 // draw previous and next buttons if it's time
3765                                 if (row == 0 && col == 0) 
3766                                 {
3767                                         // draw previous button
3768                                         DrawMonthCalendarButton (
3769                                                 dc,
3770                                                 rectangle,
3771                                                 mc,
3772                                                 title_size,
3773                                                 mc.button_x_offset,
3774                                                 (System.Drawing.Size)((object)mc.button_size),
3775                                                 true);
3776                                 }
3777                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) 
3778                                 {
3779                                         // draw next button
3780                                         DrawMonthCalendarButton (
3781                                                 dc,
3782                                                 rectangle,
3783                                                 mc,
3784                                                 title_size,
3785                                                 mc.button_x_offset,
3786                                                 (System.Drawing.Size)((object)mc.button_size),
3787                                                 false);
3788                                 }
3789                         }
3790                         
3791                         // set the week offset and draw week nums if needed
3792                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
3793                         Rectangle day_name_rect = new Rectangle(
3794                                 rectangle.X,
3795                                 rectangle.Y + title_size.Height,
3796                                 (7 + col_offset) * date_cell_size.Width,
3797                                 date_cell_size.Height);
3798                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
3799                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect);
3800                                 // draw the day names 
3801                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
3802                                 for (int i=0; i < 7; i++) 
3803                                 {
3804                                         int position = i - (int) first_day_of_week;
3805                                         if (position < 0) 
3806                                         {
3807                                                 position = 7 + position;
3808                                         }
3809                                         // draw it
3810                                         Rectangle day_rect = new Rectangle(
3811                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
3812                                                 day_name_rect.Y,
3813                                                 date_cell_size.Width,
3814                                                 date_cell_size.Height);
3815                                         dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format);
3816                                 }
3817                                 
3818                                 // draw the vertical divider
3819                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
3820                                 dc.DrawLine (
3821                                         ResPool.GetPen (mc.ForeColor),
3822                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
3823                                         rectangle.Y + vert_divider_y,
3824                                         rectangle.Right - mc.divider_line_offset,
3825                                         rectangle.Y + vert_divider_y);
3826                         }
3827
3828
3829                         // draw the actual date items in the grid (including the week numbers)
3830                         Rectangle date_rect = new Rectangle (
3831                                 rectangle.X,
3832                                 rectangle.Y + title_size.Height + date_cell_size.Height,
3833                                 date_cell_size.Width,
3834                                 date_cell_size.Height);
3835                         int month_row_count = 0;
3836                         bool draw_week_num_divider = false;
3837                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
3838                         for (int i=0; i < 6; i++) 
3839                         {
3840                                 // establish if this row is in our clip_area
3841                                 Rectangle row_rect = new Rectangle (
3842                                         rectangle.X,
3843                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
3844                                         date_cell_size.Width * 7,
3845                                         date_cell_size.Height);
3846                                 if (mc.ShowWeekNumbers) {
3847                                         row_rect.Width += date_cell_size.Width;
3848                                 }
3849                 
3850                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
3851                                 if (draw_row) {
3852                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect);
3853                                 }
3854                                 // establish if this is a valid week to draw
3855                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
3856                                         month_row_count = i;
3857                                 }
3858                                 
3859                                 // draw the week number if required
3860                                 if (mc.ShowWeekNumbers && month_row_count == i) {
3861                                         if (!draw_week_num_divider) {
3862                                                 draw_week_num_divider = draw_row;
3863                                         }
3864                                         // get the week for this row
3865                                         int week = mc.GetWeekOfYear (current_date);     
3866
3867                                         if (draw_row) {
3868                                                 dc.DrawString (
3869                                                         week.ToString(),
3870                                                         mc.Font,
3871                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
3872                                                         date_rect,
3873                                                         mc.centered_format);
3874                                         }
3875                                         date_rect.Offset(date_cell_size.Width, 0);
3876                                 }
3877                                                                 
3878                                 // only draw the days if we have to
3879                                 if(month_row_count == i) {
3880                                         for (int j=0; j < 7; j++) 
3881                                         {
3882                                                 if (draw_row) {
3883                                                         DrawMonthCalendarDate (
3884                                                                 dc,
3885                                                                 date_rect,
3886                                                                 mc,
3887                                                                 current_date,
3888                                                                 this_month,
3889                                                                 row,
3890                                                                 col);
3891                                                 }
3892
3893                                                 // move the day on
3894                                                 current_date = current_date.AddDays(1);
3895                                                 date_rect.Offset(date_cell_size.Width, 0);
3896                                         }
3897
3898                                         // shift the rectangle down one row
3899                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
3900                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
3901                                 }
3902                         }
3903
3904                         // month_row_count is zero based, so add one
3905                         month_row_count++;
3906
3907                         // draw week numbers if required
3908                         if (draw_week_num_divider) {
3909                                 col_offset = 1;
3910                                 dc.DrawLine (
3911                                         ResPool.GetPen (mc.ForeColor),
3912                                         rectangle.X + date_cell_size.Width - 1,
3913                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
3914                                         rectangle.X + date_cell_size.Width - 1,
3915                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
3916                         }
3917                 }
3918
3919                 // draws the pervious or next button
3920                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) 
3921                 {
3922                         const int arrow_width = 4;
3923                         const int arrow_height = 7;
3924
3925                         bool is_clicked = false;
3926                         Rectangle button_rect;
3927                         PointF arrow_center;
3928                         PointF [] arrow_path = new PointF [3];
3929                         
3930                         // prepare the button
3931                         if (is_previous) 
3932                         {
3933                                 is_clicked = mc.is_previous_clicked;
3934
3935                                 button_rect = new Rectangle (
3936                                         rectangle.X + 1 + x_offset,
3937                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3938                                         Math.Max(button_size.Width - 1, 0),
3939                                         Math.Max(button_size.Height - 1, 0));
3940
3941                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3942                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3943                                 if (is_clicked) {
3944                                         arrow_center.X += 1;
3945                                         arrow_center.Y += 1;
3946                                 }
3947
3948                                 arrow_path [0].X = arrow_center.X;
3949                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3950                                 arrow_path [1].X = arrow_center.X;
3951                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3952                                 arrow_path [2].X = arrow_center.X - arrow_width;
3953                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3954                         }
3955                         else
3956                         {
3957                                 is_clicked = mc.is_next_clicked;
3958
3959                                 button_rect = new Rectangle (
3960                                         rectangle.Right - 1 - x_offset - button_size.Width,
3961                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3962                                         Math.Max(button_size.Width - 1, 0),
3963                                         Math.Max(button_size.Height - 1, 0));
3964
3965                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3966                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3967                                 if (is_clicked) {
3968                                         arrow_center.X += 1;
3969                                         arrow_center.Y += 1;
3970                                 }
3971
3972                                 arrow_path [0].X = arrow_center.X - arrow_width;
3973                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3974                                 arrow_path [1].X = arrow_center.X - arrow_width;
3975                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3976                                 arrow_path [2].X = arrow_center.X;
3977                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3978                         }
3979
3980                         // fill the background
3981                         dc.FillRectangle (SystemBrushes.Control, button_rect);
3982                         // draw the border
3983                         if (is_clicked) {
3984                                 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
3985                         }
3986                         else {
3987                                 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
3988                         }
3989                         // draw the arrow
3990                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);                 
3991                         //dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding);
3992                 }
3993                 
3994
3995                 // draws one day in the calendar grid
3996                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
3997                         Color date_color = mc.ForeColor;
3998                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
3999
4000                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
4001                         if (date.Year != month.Year || date.Month != month.Month) {
4002                                 DateTime check_date = month.AddMonths (-1);
4003                                 // check if it's the month before 
4004                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
4005                                         date_color = mc.TrailingForeColor;
4006                                 } else {
4007                                         // check if it's the month after
4008                                         check_date = month.AddMonths (1);
4009                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
4010                                                 date_color = mc.TrailingForeColor;
4011                                         } else {
4012                                                 return;
4013                                         }
4014                                 }
4015                         } else {
4016                                 date_color = mc.ForeColor;
4017                         }
4018
4019                         const int inflate = -1;
4020
4021                         if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) {
4022                                 // see if the date is in the start of selection
4023                                 date_color = mc.BackColor;
4024                                 // draw the left hand of the back ground
4025                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
4026                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360);
4027                         } else if (date == mc.SelectionStart.Date) {
4028                                 // see if the date is in the start of selection
4029                                 date_color = mc.BackColor;
4030                                 // draw the left hand of the back ground
4031                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
4032                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
4033                                 // fill the other side as a straight rect
4034                                 if (date < mc.SelectionEnd.Date) 
4035                                 {
4036                                         // use rectangle instead of rectangle to go all the way to edge of rect
4037                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
4038                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
4039                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4040                                 }
4041                         } else if (date == mc.SelectionEnd.Date) {
4042                                 // see if it is the end of selection
4043                                 date_color = mc.BackColor;
4044                                 // draw the left hand of the back ground
4045                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4046                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
4047                                 // fill the other side as a straight rect
4048                                 if (date > mc.SelectionStart.Date) {
4049                                         selection_rect.X = rectangle.X;
4050                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
4051                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4052                                 }
4053                         } else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) {
4054                                 // now see if it's in the middle
4055                                 date_color = mc.BackColor;
4056                                 // draw the left hand of the back ground
4057                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate);
4058                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4059                         }
4060
4061                         // establish if it's a bolded font
4062                         Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font;
4063
4064                         // just draw the date now
4065                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format);
4066
4067                         // today circle if needed
4068                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
4069                                 DrawTodayCircle (dc, interior);
4070                         }
4071
4072                         // draw the selection grid
4073                         if (mc.is_date_clicked && mc.clicked_date == date) {
4074                                 Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot);
4075                                 dc.DrawRectangle (pen, interior);
4076                         }
4077                 }
4078
4079                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
4080                         Color circle_color = Color.FromArgb (248, 0, 0);
4081                         // draw the left hand of the circle 
4082                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
4083                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
4084                         Point [] curve_points = new Point [3];
4085                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
4086                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
4087                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
4088
4089                         Pen pen = ResPool.GetSizedPen(circle_color, 2);
4090                         dc.DrawArc (pen, lhs_circle_rect, 90, 180);
4091                         dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
4092                         dc.DrawCurve (pen, curve_points);
4093                         dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
4094                 }
4095
4096                 #endregion      // MonthCalendar
4097
4098                 #region Panel
4099                 public override Size PanelDefaultSize {
4100                         get {
4101                                 return new Size (200, 100);
4102                         }
4103                 }
4104                 #endregion      // Panel
4105
4106                 #region PictureBox
4107                 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
4108                         Rectangle client = pb.ClientRectangle;
4109
4110                         // FIXME - instead of drawing the whole picturebox every time
4111                         // intersect the clip rectangle with the drawn picture and only draw what's needed,
4112                         // Also, we only need a background fill where no image goes
4113                         if (pb.Image != null) {
4114                                 switch (pb.SizeMode) {
4115                                 case PictureBoxSizeMode.StretchImage:
4116                                         dc.DrawImage (pb.Image, 0, 0, client.Width, client.Height);
4117                                         break;
4118
4119                                 case PictureBoxSizeMode.CenterImage:
4120                                         dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
4121                                         break;
4122 #if NET_2_0
4123                                 case PictureBoxSizeMode.Zoom:
4124                                         Size image_size;
4125                                         
4126                                         if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height))
4127                                                 image_size = new Size (client.Width, (pb.Image.Height * client.Width) / pb.Image.Width);
4128                                         else
4129                                                 image_size = new Size ((pb.Image.Width * client.Height) / pb.Image.Height, client.Height);
4130
4131                                         dc.DrawImage (pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height);
4132                                         break;
4133 #endif
4134                                 default:
4135                                         // Normal, AutoSize
4136                                         dc.DrawImage(pb.Image, 0, 0, pb.Image.Width, pb.Image.Height);
4137                                         break;
4138                                 }
4139
4140                                 return;
4141                         }
4142                 }
4143
4144                 public override Size PictureBoxDefaultSize {
4145                         get {
4146                                 return new Size (100, 50);
4147                         }
4148                 }
4149                 #endregion      // PictureBox
4150
4151                 #region PrintPreviewControl
4152                 public override int PrintPreviewControlPadding {
4153                         get { return 8; }
4154                 }
4155
4156                 public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview)
4157                 {
4158                         int page_width, page_height;
4159                         int padding = PrintPreviewControlPadding;
4160                         PreviewPageInfo[] pis = preview.page_infos;
4161
4162                         if (preview.AutoZoom) {
4163                                 int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding;
4164                                 int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding;
4165
4166                                 float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height;
4167
4168                                 /* try to lay things out using the width to determine the size */
4169                                 page_width = width_available / preview.Columns;
4170                                 page_height = (int)(page_width / image_ratio);
4171
4172                                 /* does the height fit? */
4173                                 if (page_height * (preview.Rows + 1) > height_available) {
4174                                         /* no, lay things out via the height */
4175                                         page_height = height_available / (preview.Rows + 1);
4176                                         page_width = (int)(page_height * image_ratio);
4177                                 }
4178                         }
4179                         else {
4180                                 page_width = (int)(pis[0].Image.Width * preview.Zoom);
4181                                 page_height = (int)(pis[0].Image.Height * preview.Zoom);
4182                         }
4183
4184                         return new Size (page_width, page_height);
4185                 }
4186
4187                 public override void PrintPreviewControlPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size)
4188                 {
4189                         int padding = 8;
4190                         PreviewPageInfo[] pis = preview.page_infos;
4191                         if (pis == null)
4192                                 return;
4193
4194                         int page_x, page_y;
4195
4196                         int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding;
4197                         int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding;
4198
4199                         Rectangle viewport = preview.ViewPort;
4200
4201                         pe.Graphics.Clip = new Region (viewport);
4202
4203                         /* center things if we can */
4204                         int off_x = viewport.Width / 2 - width / 2;
4205                         if (off_x < 0) off_x = 0;
4206                         int off_y = viewport.Height / 2 - height / 2;
4207                         if (off_y < 0) off_y = 0;
4208
4209                         page_y = off_y + padding - preview.vbar_value;
4210
4211                         if (preview.StartPage > 0) {
4212                                 int p = preview.StartPage - 1;
4213                                 for (int py = 0; py < preview.Rows + 1; py ++) {
4214                                         page_x = off_x + padding - preview.hbar_value;
4215                                         for (int px = 0; px < preview.Columns; px ++) {
4216                                                 if (p >= pis.Length)
4217                                                         continue;
4218                                                 Image image = preview.image_cache[p];
4219                                                 if (image == null)
4220                                                         image = pis[p].Image;
4221                                                 Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size);
4222
4223                                                 pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
4224
4225                                                 page_x += padding + page_size.Width;
4226                                                 p++;
4227                                         }
4228                                         page_y += padding + page_size.Height;
4229                                 }
4230                         }
4231                 }
4232                 #endregion      // PrintPreviewControl
4233
4234                 #region ProgressBar
4235                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) 
4236                 {
4237                         Rectangle client_area = ctrl.client_area;
4238                         
4239                         /* Draw border */
4240                         CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl);
4241                         
4242                         /* Draw Blocks */
4243                         int draw_mode = 0;
4244                         int max_blocks = int.MaxValue;
4245                         int start_pixel = client_area.X;
4246 #if NET_2_0
4247                         draw_mode = (int) ctrl.Style;
4248 #endif
4249                         switch (draw_mode) {
4250 #if NET_2_0
4251                         case 1: { // Continuous
4252                                 int pixels_to_draw;
4253                                 pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1))));
4254                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
4255                                 break;
4256                         }
4257                         case 2: // Marquee
4258                                 if (XplatUI.ThemesEnabled) {
4259                                         int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds;
4260                                         double percent_done = (double) ms_diff % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
4261                                         max_blocks = 5;
4262                                         start_pixel = client_area.X + (int) (client_area.Width * percent_done);
4263                                 }
4264                                 
4265                                 goto case 0;
4266 #endif
4267                         case 0:
4268                         default:  // Blocks
4269                                 Rectangle block_rect;
4270                                 int space_betweenblocks = ProgressBarChunkSpacing;
4271                                 int block_width;
4272                                 int increment;
4273                                 int barpos_pixels;
4274                                 int block_count = 0;
4275                                 
4276                                 block_width = ProgressBarGetChunkSize (client_area.Height);
4277                                 barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)));
4278                                 increment = block_width + space_betweenblocks;
4279                                 
4280                                 block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
4281                                 while (true) {
4282                                         if (max_blocks != int.MaxValue) {
4283                                                 if (block_count >= max_blocks)
4284                                                         break;
4285                                                 if (block_rect.X > client_area.Width)
4286                                                         block_rect.X -= client_area.Width;
4287                                         } else {
4288                                                 if ((block_rect.X - client_area.X) >= barpos_pixels)
4289                                                         break;
4290                                         }
4291                                         
4292                                         if (clip_rect.IntersectsWith (block_rect) == true) {                            
4293                                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), block_rect);
4294                                         }                               
4295                                         
4296                                         block_rect.X  += increment;
4297                                         block_count++;
4298                                 }
4299                                 break;
4300                         
4301                         }
4302                 }
4303                 
4304                 public const int ProgressBarChunkSpacing = 2;
4305
4306                 public static int ProgressBarGetChunkSize ()
4307                 {
4308                         return ProgressBarGetChunkSize (ProgressBarDefaultHeight);
4309                 }
4310                 
4311                 static int ProgressBarGetChunkSize (int progressBarClientAreaHeight)
4312                 {
4313                         return (progressBarClientAreaHeight * 2) / 3;
4314                 }
4315
4316                 const int ProgressBarDefaultHeight = 23;
4317
4318                 public override Size ProgressBarDefaultSize {
4319                         get {
4320                                 return new Size (100, ProgressBarDefaultHeight);
4321                         }
4322                 }
4323
4324                 #endregion      // ProgressBar
4325
4326                 #region RadioButton
4327                 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
4328                         StringFormat    text_format;
4329                         Rectangle       client_rectangle;
4330                         Rectangle       text_rectangle;
4331                         Rectangle       radiobutton_rectangle;
4332                         int             radiobutton_size = 13;
4333                         int     radiobutton_space = 4;
4334
4335                         client_rectangle = radio_button.ClientRectangle;
4336                         text_rectangle = client_rectangle;
4337                         radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
4338
4339                         text_format = new StringFormat();
4340                         text_format.Alignment = StringAlignment.Near;
4341                         text_format.LineAlignment = StringAlignment.Center;
4342                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
4343
4344                         /* Calculate the position of text and checkbox rectangle */
4345                         if (radio_button.appearance!=Appearance.Button) {
4346                                 switch(radio_button.radiobutton_alignment) {
4347                                 case ContentAlignment.BottomCenter: {
4348                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4349                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4350                                         text_rectangle.X=client_rectangle.X;
4351                                         text_rectangle.Width=client_rectangle.Width;
4352                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4353                                         break;
4354                                 }
4355
4356                                 case ContentAlignment.BottomLeft: {
4357                                         radiobutton_rectangle.X=client_rectangle.Left;
4358                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4359                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4360                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;                                 
4361                                         break;
4362                                 }
4363
4364                                 case ContentAlignment.BottomRight: {
4365                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4366                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4367                                         text_rectangle.X=client_rectangle.X;
4368                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4369                                         break;
4370                                 }
4371
4372                                 case ContentAlignment.MiddleCenter: {
4373                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4374                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4375                                         text_rectangle.X=client_rectangle.X;
4376                                         text_rectangle.Width=client_rectangle.Width;
4377                                         break;
4378                                 }
4379
4380                                 default:
4381                                 case ContentAlignment.MiddleLeft: {
4382                                         radiobutton_rectangle.X=client_rectangle.Left;
4383                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4384                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4385                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4386                                         break;
4387                                 }
4388
4389                                 case ContentAlignment.MiddleRight: {
4390                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4391                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4392                                         text_rectangle.X=client_rectangle.X;
4393                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4394                                         break;
4395                                 }
4396
4397                                 case ContentAlignment.TopCenter: {
4398                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4399                                         radiobutton_rectangle.Y=client_rectangle.Top;
4400                                         text_rectangle.X=client_rectangle.X;
4401                                         text_rectangle.Y=radiobutton_size+radiobutton_space;
4402                                         text_rectangle.Width=client_rectangle.Width;
4403                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4404                                         break;
4405                                 }
4406
4407                                 case ContentAlignment.TopLeft: {
4408                                         radiobutton_rectangle.X=client_rectangle.Left;
4409                                         radiobutton_rectangle.Y=client_rectangle.Top;
4410                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4411                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4412                                         break;
4413                                 }
4414
4415                                 case ContentAlignment.TopRight: {
4416                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4417                                         radiobutton_rectangle.Y=client_rectangle.Top;
4418                                         text_rectangle.X=client_rectangle.X;
4419                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4420                                         break;
4421                                 }
4422                                 }
4423                         } else {
4424                                 text_rectangle.X=client_rectangle.X;
4425                                 text_rectangle.Width=client_rectangle.Width;
4426                         }
4427                         
4428                         /* Set the horizontal alignment of our text */
4429                         switch(radio_button.text_alignment) {
4430                                 case ContentAlignment.BottomLeft:
4431                                 case ContentAlignment.MiddleLeft:
4432                                 case ContentAlignment.TopLeft: {
4433                                         text_format.Alignment=StringAlignment.Near;
4434                                         break;
4435                                 }
4436
4437                                 case ContentAlignment.BottomCenter:
4438                                 case ContentAlignment.MiddleCenter:
4439                                 case ContentAlignment.TopCenter: {
4440                                         text_format.Alignment=StringAlignment.Center;
4441                                         break;
4442                                 }
4443
4444                                 case ContentAlignment.BottomRight:
4445                                 case ContentAlignment.MiddleRight:
4446                                 case ContentAlignment.TopRight: {
4447                                         text_format.Alignment=StringAlignment.Far;
4448                                         break;
4449                                 }
4450                         }
4451
4452                         /* Set the vertical alignment of our text */
4453                         switch(radio_button.text_alignment) {
4454                                 case ContentAlignment.TopLeft: 
4455                                 case ContentAlignment.TopCenter: 
4456                                 case ContentAlignment.TopRight: {
4457                                         text_format.LineAlignment=StringAlignment.Near;
4458                                         break;
4459                                 }
4460
4461                                 case ContentAlignment.BottomLeft:
4462                                 case ContentAlignment.BottomCenter:
4463                                 case ContentAlignment.BottomRight: {
4464                                         text_format.LineAlignment=StringAlignment.Far;
4465                                         break;
4466                                 }
4467
4468                                 case ContentAlignment.MiddleLeft:
4469                                 case ContentAlignment.MiddleCenter:
4470                                 case ContentAlignment.MiddleRight: {
4471                                         text_format.LineAlignment=StringAlignment.Center;
4472                                         break;
4473                                 }
4474                         }
4475
4476                         ButtonState state = ButtonState.Normal;
4477                         if (radio_button.FlatStyle == FlatStyle.Flat) {
4478                                 state |= ButtonState.Flat;
4479                         }
4480                         
4481                         if (radio_button.Checked) {
4482                                 state |= ButtonState.Checked;
4483                         }
4484                         
4485                         if (!radio_button.Enabled) {
4486                                 state |= ButtonState.Inactive;
4487                         }
4488
4489                         // Start drawing
4490                         RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
4491                         
4492                         if ((radio_button.image != null) || (radio_button.image_list != null))
4493                                 ButtonBase_DrawImage(radio_button, dc);
4494                         
4495                         RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
4496
4497                         if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) {
4498                                 SizeF text_size = dc.MeasureString (radio_button.Text, radio_button.Font);
4499                                 
4500                                 Rectangle focus_rect = Rectangle.Empty;
4501                                 focus_rect.X = text_rectangle.X;
4502                                 focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
4503                                 focus_rect.Size = text_size.ToSize ();
4504
4505                                 RadioButton_DrawFocus (radio_button, dc, focus_rect);
4506                         }
4507                         
4508                         text_format.Dispose ();
4509                 }
4510
4511                 protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
4512                 {
4513                         dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle);
4514                         
4515                         if (radio_button.appearance==Appearance.Button) {
4516                                 ButtonBase_DrawButton (radio_button, dc);
4517                                 
4518                                 if ((radio_button.Focused) && radio_button.Enabled)
4519                                         ButtonBase_DrawFocus(radio_button, dc);
4520                         } else {
4521                                 // establish if we are rendering a flat style of some sort
4522                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
4523                                         DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
4524                                 } else {
4525                                         CPDrawRadioButton(dc, radiobutton_rectangle, state);
4526                                 }
4527                         }
4528                 }
4529                 
4530                 protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
4531                 {
4532                         DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc, 
4533                                                           text_format, radio_button.Appearance, radio_button.Checked);
4534                 }
4535                 
4536                 protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
4537                 {
4538                         DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
4539                 }
4540                 
4541                 
4542                 // renders a radio button with the Flat and Popup FlatStyle
4543                 protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
4544                 {
4545                         int     lineWidth;
4546                         
4547                         if (radio_button.Enabled) {
4548                                 
4549                                 // draw the outer flatstyle arcs
4550                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
4551                                         graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359);
4552                                         
4553                                         // fill in the area depending on whether or not the mouse is hovering
4554                                         if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) {
4555                                                 graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4556                                         } else {
4557                                                 graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4558                                         }
4559                                 } else {
4560                                         // must be a popup radio button
4561                                         // fill the control
4562                                         graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359);
4563
4564                                         if (radio_button.is_entered || radio_button.Capture) {
4565                                                 // draw the popup 3d button knob
4566                                                 graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
4567
4568                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180);
4569                                                 graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180);
4570                                                 
4571                                         } else {
4572                                                 // just draw lighter flatstyle outer circle
4573                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);                                           
4574                                         }                                                                               
4575                                 }
4576                         } else {
4577                                 // disabled
4578                                 // fill control background color regardless of actual backcolor
4579                                 graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4580                                 // draw the ark as control dark
4581                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4582                         }
4583
4584                         // draw the check
4585                         if (radio_button.Checked) {
4586                                 lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
4587                                 
4588                                 Pen dot_pen = SystemPens.ControlDarkDark;
4589                                 Brush dot_brush = SystemBrushes.ControlDarkDark;
4590
4591                                 if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) {
4592                                         dot_pen = SystemPens.ControlDark;
4593                                         dot_brush = SystemBrushes.ControlDark;
4594                                 } 
4595                                 
4596                                 if (rectangle.Height >  13) {
4597                                         graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
4598                                 } else {
4599                                         int x_half_pos = (rectangle.Width / 2) + rectangle.X;
4600                                         int y_half_pos = (rectangle.Height / 2) + rectangle.Y;
4601                                         
4602                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
4603                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
4604                                         
4605                                         graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
4606                                         graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
4607                                 }
4608                         }
4609                 }
4610
4611                 public override Size RadioButtonDefaultSize {
4612                         get {
4613                                 return new Size (104,24);
4614                         }
4615                 }
4616
4617 #if NET_2_0
4618                 public override void DrawRadioButton (Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
4619                 {
4620                         // Draw Button Background
4621                         if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) {
4622                                 glyphArea.Height -= 2;
4623                                 glyphArea.Width -= 2;
4624                         }
4625                         
4626                         DrawRadioButtonGlyph (g, rb, glyphArea);
4627
4628                         // If we have an image, draw it
4629                         if (imageBounds.Size != Size.Empty)
4630                                 DrawRadioButtonImage (g, rb, imageBounds);
4631
4632                         if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty)
4633                                 DrawRadioButtonFocus (g, rb, textBounds);
4634
4635                         // If we have text, draw it
4636                         if (textBounds != Rectangle.Empty)
4637                                 DrawRadioButtonText (g, rb, textBounds);
4638                 }
4639
4640                 public virtual void DrawRadioButtonGlyph (Graphics g, RadioButton rb, Rectangle glyphArea)
4641                 {
4642                         if (rb.Pressed)
4643                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked);
4644                         else if (rb.InternalSelected)
4645                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4646                         else if (rb.Entered)
4647                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked);
4648                         else if (!rb.Enabled)
4649                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked);
4650                         else
4651                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4652                 }
4653
4654                 public virtual void DrawRadioButtonFocus (Graphics g, RadioButton rb, Rectangle focusArea)
4655                 {
4656                         ControlPaint.DrawFocusRectangle (g, focusArea);
4657                 }
4658
4659                 public virtual void DrawRadioButtonImage (Graphics g, RadioButton rb, Rectangle imageBounds)
4660                 {
4661                         if (rb.Enabled)
4662                                 g.DrawImage (rb.Image, imageBounds);
4663                         else
4664                                 CPDrawImageDisabled (g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
4665                 }
4666
4667                 public virtual void DrawRadioButtonText (Graphics g, RadioButton rb, Rectangle textBounds)
4668                 {
4669                         if (rb.Enabled)
4670                                 TextRenderer.DrawTextInternal (g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4671                         else
4672                                 DrawStringDisabled20 (g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4673                 }
4674
4675                 public override Size CalculateRadioButtonAutoSize (RadioButton rb)
4676                 {
4677                         Size ret_size = Size.Empty;
4678                         Size text_size = TextRenderer.MeasureTextInternal (rb.Text, rb.Font, rb.UseCompatibleTextRendering);
4679                         Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size;
4680
4681                         // Pad the text size
4682                         if (rb.Text.Length != 0) {
4683                                 text_size.Height += 4;
4684                                 text_size.Width += 4;
4685                         }
4686
4687                         switch (rb.TextImageRelation) {
4688                                 case TextImageRelation.Overlay:
4689                                         ret_size.Height = Math.Max (rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
4690                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4691                                         break;
4692                                 case TextImageRelation.ImageAboveText:
4693                                 case TextImageRelation.TextAboveImage:
4694                                         ret_size.Height = text_size.Height + image_size.Height;
4695                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4696                                         break;
4697                                 case TextImageRelation.ImageBeforeText:
4698                                 case TextImageRelation.TextBeforeImage:
4699                                         ret_size.Height = Math.Max (text_size.Height, image_size.Height);
4700                                         ret_size.Width = text_size.Width + image_size.Width;
4701                                         break;
4702                         }
4703
4704                         // Pad the result
4705                         ret_size.Height += (rb.Padding.Vertical);
4706                         ret_size.Width += (rb.Padding.Horizontal) + 15;
4707
4708                         // There seems to be a minimum height
4709                         if (ret_size.Height == rb.Padding.Vertical)
4710                                 ret_size.Height += 14;
4711
4712                         return ret_size;
4713                 }
4714
4715                 public override void CalculateRadioButtonTextAndImageLayout (ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
4716                 {
4717                         CalculateCheckBoxTextAndImageLayout (b, offset, out glyphArea, out textRectangle, out imageRectangle);
4718                 }
4719 #endif
4720                 #endregion      // RadioButton
4721
4722                 #region ScrollBar
4723                 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
4724                 {
4725                         int             scrollbutton_width = bar.scrollbutton_width;
4726                         int             scrollbutton_height = bar.scrollbutton_height;
4727                         Rectangle       first_arrow_area;
4728                         Rectangle       second_arrow_area;                      
4729                         Rectangle       thumb_pos;
4730                         
4731                         thumb_pos = bar.ThumbPos;
4732
4733                         if (bar.vert) {
4734                                 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
4735                                 bar.FirstArrowArea = first_arrow_area;
4736
4737                                 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
4738                                 bar.SecondArrowArea = second_arrow_area;
4739
4740                                 thumb_pos.Width = bar.Width;
4741                                 bar.ThumbPos = thumb_pos;
4742
4743                                 Brush VerticalBrush;
4744                                 /* Background, upper track */
4745                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4746                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4747                                 else
4748                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4749                                 Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom);
4750                                 if (clip.IntersectsWith (UpperTrack))
4751                                         dc.FillRectangle (VerticalBrush, UpperTrack);
4752
4753                                 /* Background, lower track */
4754                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4755                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4756                                 else
4757                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4758                                 Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom);
4759                                 if (clip.IntersectsWith (LowerTrack))
4760                                         dc.FillRectangle (VerticalBrush, LowerTrack);
4761
4762                                 /* Buttons */
4763                                 if (clip.IntersectsWith (first_arrow_area))
4764                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
4765                                 if (clip.IntersectsWith (second_arrow_area))
4766                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
4767                         } else {
4768                                 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
4769                                 bar.FirstArrowArea = first_arrow_area;
4770
4771                                 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
4772                                 bar.SecondArrowArea = second_arrow_area;
4773
4774                                 thumb_pos.Height = bar.Height;
4775                                 bar.ThumbPos = thumb_pos;
4776
4777                                 Brush HorizontalBrush;
4778                                 //Background, left track
4779                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4780                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4781                                 else
4782                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4783                                 Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height);
4784                                 if (clip.IntersectsWith (LeftTrack))
4785                                         dc.FillRectangle (HorizontalBrush, LeftTrack);
4786
4787                                 //Background, right track
4788                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4789                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4790                                 else
4791                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4792                                 Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height);
4793                                 if (clip.IntersectsWith (RightTrack))
4794                                         dc.FillRectangle (HorizontalBrush, RightTrack);
4795
4796                                 /* Buttons */
4797                                 if (clip.IntersectsWith (first_arrow_area))
4798                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
4799                                 if (clip.IntersectsWith (second_arrow_area))
4800                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
4801                         }
4802
4803                         /* Thumb */
4804                         ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);                          
4805                 }
4806
4807                 protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
4808                 {
4809                         if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
4810                                 DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
4811                 }
4812
4813                 public override int ScrollBarButtonSize {
4814                         get { return 16; }
4815                 }
4816
4817                 public override bool ScrollBarHasHotElementStyles {
4818                         get {
4819                                 return false;
4820                         }
4821                 }
4822
4823                 public override bool ScrollBarHasPressedThumbStyle {
4824                         get { 
4825                                 return false;
4826                         }
4827                 }
4828
4829                 public override bool ScrollBarHasHoverArrowButtonStyle {
4830                         get {
4831                                 return false;
4832                         }
4833                 }
4834                 #endregion      // ScrollBar
4835
4836                 #region StatusBar
4837                 public  override void DrawStatusBar (Graphics real_dc, Rectangle clip, StatusBar sb) {
4838                         Rectangle area = sb.ClientRectangle;
4839                         int horz_border = 2;
4840                         int vert_border = 2;
4841
4842                         Image backbuffer = new Bitmap (sb.ClientSize.Width, sb.ClientSize.Height, real_dc);
4843                         Graphics dc = Graphics.FromImage (backbuffer);
4844                         
4845                         DrawStatusBarBackground (dc, clip, sb);
4846                         
4847                         if (!sb.ShowPanels && sb.Text != String.Empty) {
4848                                 string text = sb.Text;
4849                                 StringFormat string_format = new StringFormat ();
4850                                 string_format.Trimming = StringTrimming.Character;
4851                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
4852                                 
4853                                 if (text.Length > 127)
4854                                         text = text.Substring (0, 127);
4855
4856                                 if (text [0] == '\t') {
4857                                         string_format.Alignment = StringAlignment.Center;
4858                                         text = text.Substring (1);
4859                                         if (text [0] == '\t') {
4860                                                 string_format.Alignment = StringAlignment.Far;
4861                                                 text = text.Substring (1);
4862                                         }
4863                                 }
4864                 
4865                                 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
4866                                                 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
4867                                 string_format.Dispose ();
4868                         } else if (sb.ShowPanels) {
4869                                 Brush br_forecolor = GetControlForeBrush (sb.ForeColor);
4870                                 int prev_x = area.X + horz_border;
4871                                 int y = area.Y + vert_border;
4872                                 for (int i = 0; i < sb.Panels.Count; i++) {
4873                                         Rectangle pr = new Rectangle (prev_x, y,
4874                                                 sb.Panels [i].Width, area.Height);
4875                                         prev_x += pr.Width + StatusBarHorzGapWidth;
4876                                         if (pr.IntersectsWith (clip))
4877                                                 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
4878                                 }
4879                         }
4880
4881                         if (sb.SizingGrip)
4882                                 DrawStatusBarSizingGrip (dc, clip, sb, area);
4883                         
4884                         real_dc.DrawImage (backbuffer, 0, 0);
4885                         dc.Dispose ();
4886                         backbuffer.Dispose ();
4887
4888                 }
4889
4890                 protected virtual void DrawStatusBarBackground (Graphics dc, Rectangle clip, StatusBar sb)
4891                 {
4892                         bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
4893
4894                         Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
4895                         dc.FillRectangle (brush, clip);
4896                 }
4897
4898                 protected virtual void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area)
4899                 {
4900                         area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16);
4901                         CPDrawSizeGrip (dc, ColorControl, area);
4902                 }
4903
4904                 protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
4905                         Brush br_forecolor, StatusBarPanel panel) {
4906                         int border_size = 3; // this is actually const, even if the border style is none
4907                         int icon_width = 16;
4908                         
4909                         area.Height -= border_size;
4910
4911                         DrawStatusBarPanelBackground (dc, area, panel);
4912
4913                         if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
4914                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
4915                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
4916                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor);
4917                                 panel.Parent.OnDrawItemInternal (e);
4918                                 return;
4919                         }
4920
4921                         string text = panel.Text;
4922                         StringFormat string_format = new StringFormat ();
4923                         string_format.Trimming = StringTrimming.Character;
4924                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4925
4926                         
4927                         if (text != null && text.Length > 0 && text [0] == '\t') {
4928                                 string_format.Alignment = StringAlignment.Center;
4929                                 text = text.Substring (1);
4930                                 if (text [0] == '\t') {
4931                                         string_format.Alignment = StringAlignment.Far;
4932                                         text = text.Substring (1);
4933                                 }
4934                         }
4935
4936                         Rectangle string_rect = Rectangle.Empty;
4937                         int x;
4938                         int len;
4939                         int icon_x = 0;
4940                         int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1;
4941
4942                         switch (panel.Alignment) {
4943                         case HorizontalAlignment.Right:
4944                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4945                                 x = area.Right - len - 4;
4946                                 string_rect = new Rectangle (x, y, 
4947                                                 area.Right - x - border_size,
4948                                                 area.Bottom - y - border_size);
4949                                 if (panel.Icon != null) {
4950                                         icon_x = x - icon_width - 2;
4951                                 }
4952                                 break;
4953                         case HorizontalAlignment.Center:
4954                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4955                                 x = area.Left + ((panel.Width - len) / 2);
4956                                 
4957                                 string_rect = new Rectangle (x, y, 
4958                                                 area.Right - x - border_size,
4959                                                 area.Bottom - y - border_size);
4960
4961                                 if (panel.Icon != null) {
4962                                         icon_x = x - icon_width - 2;
4963                                 }
4964                                 break;
4965
4966                                 
4967                         default:
4968                                 int left = area.Left + border_size;;
4969                                 if (panel.Icon != null) {
4970                                         icon_x = area.Left + 2;
4971                                         left = icon_x + icon_width + 2;
4972                                 }
4973
4974                                 x = left;
4975                                 string_rect = new Rectangle (x, y, 
4976                                                 area.Right - x - border_size,
4977                                                 area.Bottom - y - border_size);
4978                                 break;
4979                         }
4980
4981                         RectangleF clip_bounds = dc.ClipBounds;
4982                         dc.SetClip (area);
4983                         dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format);                      
4984                         dc.SetClip (clip_bounds);
4985
4986                         if (panel.Icon != null) {
4987                                 dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width));
4988                         }
4989                 }
4990
4991                 protected virtual void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel)
4992                 {
4993                         if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
4994                                 Border3DStyle border_style = Border3DStyle.SunkenOuter;
4995                                 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
4996                                         border_style = Border3DStyle.RaisedInner;
4997                                         
4998                                 CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor);
4999                         }
5000                 }
5001
5002                 public override int StatusBarSizeGripWidth {
5003                         get { return 15; }
5004                 }
5005
5006                 public override int StatusBarHorzGapWidth {
5007                         get { return 3; }
5008                 }
5009
5010                 public override Size StatusBarDefaultSize {
5011                         get {
5012                                 return new Size (100, 22);
5013                         }
5014                 }
5015                 #endregion      // StatusBar
5016
5017                 #region TabControl
5018
5019                 #region TabControl settings
5020
5021                 public override Size TabControlDefaultItemSize {
5022                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultItemSize; }
5023                 }
5024
5025                 public override Point TabControlDefaultPadding {
5026                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultPadding; }
5027                 }
5028
5029                 public override int TabControlMinimumTabWidth {
5030                         get { return ThemeElements.CurrentTheme.TabControlPainter.MinimumTabWidth; }
5031                 }
5032
5033                 public override Rectangle TabControlSelectedDelta {
5034                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedTabDelta; }
5035                 }
5036
5037                 public override int TabControlSelectedSpacing {
5038                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedSpacing; }
5039                 }
5040                 
5041                 public override int TabPanelOffsetX {
5042                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.X; }
5043                 }
5044                 
5045                 public override int TabPanelOffsetY {
5046                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.Y; }
5047                 }
5048
5049                 public override int TabControlColSpacing {
5050                         get { return ThemeElements.CurrentTheme.TabControlPainter.ColSpacing; }
5051                 }
5052
5053                 public override Point TabControlImagePadding {
5054                         get { return ThemeElements.CurrentTheme.TabControlPainter.ImagePadding; }
5055                 }
5056
5057                 public override int TabControlScrollerWidth {
5058                         get {return ThemeElements.CurrentTheme.TabControlPainter.ScrollerWidth; }
5059                 }
5060
5061
5062                 public override Size TabControlGetSpacing (TabControl tab) 
5063                 {
5064                         try {
5065                                 return ThemeElements.CurrentTheme.TabControlPainter.RowSpacing (tab);
5066                         } catch {
5067                                 throw new Exception ("Invalid Appearance value: " + tab.Appearance);
5068                         }
5069                 }
5070                 #endregion
5071
5072                 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
5073                 {
5074                         ThemeElements.CurrentTheme.TabControlPainter.Draw (dc, area, tab);
5075                 }
5076
5077                 public override Rectangle TabControlGetDisplayRectangle (TabControl tab)
5078                 {
5079                         return ThemeElements.CurrentTheme.TabControlPainter.GetDisplayRectangle (tab);
5080                 }
5081
5082                 public override Rectangle TabControlGetPanelRect (TabControl tab)
5083                 {
5084                         return ThemeElements.CurrentTheme.TabControlPainter.GetTabPanelRect (tab);
5085                 }
5086
5087                 #endregion
5088
5089                 #region TextBox
5090                 public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea)
5091                 {
5092                         if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) {
5093                                 g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea);
5094                         } else {
5095                                 g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea);
5096                         }
5097                 }
5098
5099                 public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m)
5100                 {
5101                         return false;
5102                 }
5103
5104                 public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase)
5105                 {
5106                         return true;
5107                 }
5108                 #endregion
5109
5110                 #region ToolBar
5111                 public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) 
5112                 {
5113                         StringFormat format = new StringFormat ();
5114                         format.Trimming = StringTrimming.EllipsisCharacter;
5115                         format.LineAlignment = StringAlignment.Center;
5116                         if (control.ShowKeyboardCuesInternal)
5117                                 format.HotkeyPrefix = HotkeyPrefix.Show;
5118                         else
5119                                 format.HotkeyPrefix = HotkeyPrefix.Hide;
5120
5121                         if (control.TextAlign == ToolBarTextAlign.Underneath)
5122                                 format.Alignment = StringAlignment.Center;
5123                         else
5124                                 format.Alignment = StringAlignment.Near;
5125 #if !NET_2_0
5126                         if (control is PropertyGrid.PropertyToolBar) {
5127                                 dc.FillRectangle (ResPool.GetSolidBrush(control.BackColor), clip_rectangle);
5128                                 
5129                                 if (clip_rectangle.X == 0) {
5130                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.X, control.Bottom);
5131                                 }
5132
5133                                 if (clip_rectangle.Y < 2) {
5134                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
5135                                 }
5136
5137                                 if (clip_rectangle.Bottom == control.Bottom) {
5138                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, clip_rectangle.Bottom - 1, clip_rectangle.Right, clip_rectangle.Bottom - 1);
5139                                 }
5140
5141                                 if (clip_rectangle.Right == control.Right) {
5142                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.Right - 1, 1, clip_rectangle.Right - 1, control.Bottom - 1);
5143                                 }
5144                         } else {
5145 #endif
5146                                 if (control.Appearance != ToolBarAppearance.Flat || control.Parent == null) {
5147                                         dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5148                                 }
5149
5150                                 if (control.Divider && clip_rectangle.Y < 2) {
5151                                         if (clip_rectangle.Y < 1) {
5152                                                 dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
5153                                         }
5154                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
5155                                 }
5156 #if !NET_2_0
5157                         }
5158 #endif
5159
5160                         foreach (ToolBarItem item in control.items)
5161                                 if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
5162                                         DrawToolBarButton (dc, control, item, format);
5163
5164                         format.Dispose ();
5165                 }
5166
5167                 protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5168                 {
5169                         bool is_flat = (control.Appearance == ToolBarAppearance.Flat);
5170                         
5171                         DrawToolBarButtonBorder (dc, item, is_flat);
5172
5173                         switch (item.Button.Style) {
5174                         case ToolBarButtonStyle.DropDownButton:
5175                                 if (control.DropDownArrows)
5176                                         DrawToolBarDropDownArrow (dc, item, is_flat);
5177                                 DrawToolBarButtonContents (dc, control, item, format);
5178                                 break;
5179
5180                         case ToolBarButtonStyle.Separator:
5181                                 if (is_flat)
5182                                         DrawToolBarSeparator (dc, item);
5183                                 break;
5184
5185                         case ToolBarButtonStyle.ToggleButton:
5186                                 DrawToolBarToggleButtonBackground (dc, item);
5187                                 DrawToolBarButtonContents (dc, control, item, format);
5188                                 break;
5189
5190                         default:
5191                                 DrawToolBarButtonContents (dc, control, item, format);
5192                                 break;
5193                         }
5194                 }
5195
5196                 const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom;
5197
5198                 protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat)
5199                 {
5200                         if (item.Button.Style == ToolBarButtonStyle.Separator)
5201                                 return;
5202
5203                         Border3DStyle style;
5204
5205                         if (is_flat) {
5206                                 if (item.Button.Pushed || item.Pressed)
5207                                         style = Border3DStyle.SunkenOuter;
5208                                 else if (item.Hilight)
5209                                         style = Border3DStyle.RaisedInner;
5210                                 else
5211                                         return;
5212
5213                         } else {
5214                                 if (item.Button.Pushed || item.Pressed)
5215                                         style = Border3DStyle.Sunken;
5216                                 else 
5217                                         style = Border3DStyle.Raised;
5218                         }
5219                         
5220                         Rectangle rect = item.Rectangle;
5221                         if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat)
5222                                 rect.Width -= ToolBarDropDownWidth;
5223
5224                         CPDrawBorder3D (dc, rect, style, all_sides);
5225                 }
5226
5227                 protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item)
5228                 {
5229                         Rectangle area = item.Rectangle;
5230                         int offset = (int) SystemPens.Control.Width + 1;
5231                         dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom);
5232                         dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom);
5233                 }
5234
5235                 protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item)
5236                 {
5237                         Brush brush;
5238                         Rectangle area = item.Rectangle;
5239                         area.X += ToolBarImageGripWidth;
5240                         area.Y += ToolBarImageGripWidth;
5241                         area.Width -= 2 * ToolBarImageGripWidth;
5242                         area.Height -= 2 * ToolBarImageGripWidth;
5243                         
5244                         if (item.Button.Pushed)
5245                                 brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight);
5246                         else if (item.Button.PartialPush)
5247                                 brush = SystemBrushes.ControlLight;
5248                         else
5249                                 brush = SystemBrushes.Control;
5250                          
5251                         dc.FillRectangle (brush, area);
5252                 }
5253
5254                 protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat)
5255                 {
5256                         Rectangle rect = item.Rectangle;
5257                         rect.X = item.Rectangle.Right - ToolBarDropDownWidth;
5258                         rect.Width = ToolBarDropDownWidth;
5259                         
5260                         if (is_flat) {
5261                                 if (item.DDPressed)
5262                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5263                                 else if (item.Button.Pushed || item.Pressed)
5264                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5265                                 else if (item.Hilight)
5266                                         CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides);
5267                         } else {
5268                                 if (item.DDPressed)
5269                                         CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides);
5270                                 else if (item.Button.Pushed || item.Pressed)
5271                                         CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides);
5272                                 else
5273                                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
5274                         }
5275                         
5276                         PointF [] vertices = new PointF [3];
5277                         PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2));
5278                         
5279                         // Increase vertical and horizontal position by 1 when button is pressed
5280                         if (item.Pressed || item.Button.Pushed || item.DDPressed) {
5281                             ddCenter.X += 1;
5282                             ddCenter.Y += 1;
5283                         }
5284                         
5285                         vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5286                         vertices [0].Y = ddCenter.Y;
5287                         vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5288                         vertices [1].Y = ddCenter.Y;
5289                         vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
5290                         vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight;
5291                         dc.FillPolygon (SystemBrushes.ControlText, vertices);
5292                 }
5293
5294                 protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5295                 {
5296                         if (item.Button.Image != null) {
5297                                 int x = item.ImageRectangle.X + ToolBarImageGripWidth;
5298                                 int y = item.ImageRectangle.Y + ToolBarImageGripWidth;
5299                                 
5300                                 // Increase vertical and horizontal position by 1 when button is pressed
5301                                 if (item.Pressed || item.Button.Pushed) {
5302                                     x += 1;
5303                                     y += 1;
5304                                 }
5305                                 
5306                                 if (item.Button.Enabled)
5307                                         dc.DrawImage (item.Button.Image, x, y);
5308                                 else 
5309                                         CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl);
5310                         }
5311
5312                         Rectangle text_rect = item.TextRectangle;
5313                         if (text_rect.Width <= 0 || text_rect.Height <= 0)
5314                                 return;
5315
5316                         if (item.Pressed || item.Button.Pushed) {
5317                                 text_rect.X += 1;
5318                                 text_rect.Y += 1;
5319                         }
5320                         
5321                         if (item.Button.Enabled)
5322                                 dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
5323                         else
5324                                 CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format);
5325                 }
5326
5327                 // Grip width for the ToolBar
5328                 public override int ToolBarGripWidth {
5329                         get { return 2;}
5330                 }
5331
5332                 // Grip width for the Image on the ToolBarButton
5333                 public override int ToolBarImageGripWidth {
5334                         get { return 2;}
5335                 }
5336
5337                 // width of the separator
5338                 public override int ToolBarSeparatorWidth {
5339                         get { return 4; }
5340                 }
5341
5342                 // width of the dropdown arrow rect
5343                 public override int ToolBarDropDownWidth {
5344                         get { return 13; }
5345                 }
5346
5347                 // width for the dropdown arrow on the ToolBarButton
5348                 public override int ToolBarDropDownArrowWidth {
5349                         get { return 5;}
5350                 }
5351
5352                 // height for the dropdown arrow on the ToolBarButton
5353                 public override int ToolBarDropDownArrowHeight {
5354                         get { return 3;}
5355                 }
5356
5357                 public override Size ToolBarDefaultSize {
5358                         get {
5359                                 return new Size (100, 42);
5360                         }
5361                 }
5362
5363                 public override bool ToolBarHasHotElementStyles (ToolBar toolBar)
5364                 {
5365                         return toolBar.Appearance == ToolBarAppearance.Flat;
5366                 }
5367
5368                 public override bool ToolBarHasHotCheckedElementStyles {
5369                         get {
5370                                 return false;
5371                         }
5372                 }
5373                 #endregion      // ToolBar
5374
5375                 #region ToolTip
5376                 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5377                 {
5378                         ToolTipDrawBackground (dc, clip_rectangle, control);
5379
5380                         Rectangle text_rect = Rectangle.Inflate (control.ClientRectangle, -2, -1);
5381 #if NET_2_0
5382                         Color foreground = control.ForeColor;
5383 #else
5384                         Color foreground = this.ColorInfoText;
5385 #endif
5386                         TextFormatFlags flags = TextFormatFlags.HidePrefix;
5387                         TextRenderer.DrawTextInternal (dc, control.Text, control.Font, text_rect, foreground, flags, false);
5388                 }
5389
5390                 protected virtual void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5391                 {
5392 #if NET_2_0
5393                         Brush back_brush = ResPool.GetSolidBrush (control.BackColor);;
5394 #else
5395                         Brush back_brush = SystemBrushes.Info;
5396 #endif
5397                         dc.FillRectangle (back_brush, control.ClientRectangle);
5398                         dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1);
5399                 }
5400
5401                 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text)
5402                 {
5403                         Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false);
5404
5405                         size.Width += 4;
5406                         size.Height += 3;
5407                         
5408                         return size;
5409                 }
5410                 
5411                 public override bool ToolTipTransparentBackground {
5412                         get {
5413                                 return false;
5414                         }
5415                 }
5416                 #endregion      // ToolTip
5417
5418                 #region BalloonWindow
5419 #if NET_2_0
5420                 NotifyIcon.BalloonWindow balloon_window;
5421                 
5422                 public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
5423                 {
5424                         Control control = Control.FromHandle(handle);
5425                         
5426                         if (control == null)
5427                                 return;
5428
5429                         if (balloon_window != null) {
5430                                 balloon_window.Close ();
5431                                 balloon_window.Dispose ();
5432                         }
5433
5434                         balloon_window = new NotifyIcon.BalloonWindow (handle);
5435                         balloon_window.Title = title;
5436                         balloon_window.Text = text;
5437                         balloon_window.Icon = icon;
5438                         balloon_window.Timeout = timeout;
5439                         balloon_window.Show ();
5440                 }
5441
5442                 private const int balloon_iconsize = 16;
5443                 private const int balloon_bordersize = 8; 
5444                 
5445                 public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) 
5446                 {
5447                         Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText);
5448                         Rectangle rect = control.ClientRectangle;
5449                         int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
5450                         
5451                         // Rectangle borders and background.
5452                         dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
5453                         dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1);
5454
5455                         // Icon
5456                         Image image;
5457                         switch (control.Icon) {
5458                                 case ToolTipIcon.Info: {
5459                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
5460                                         break;
5461                                 }
5462
5463                                 case ToolTipIcon.Warning: {
5464                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
5465                                         break;
5466                                 }
5467
5468                                 case ToolTipIcon.Error: {
5469                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
5470                                         break;
5471                                 }
5472                                 
5473                                 default: {
5474                                         image = null;
5475                                         break;
5476                                 }
5477                         }
5478
5479                         if (control.Icon != ToolTipIcon.None)
5480                                 dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize));
5481                         
5482                         // Title
5483                         Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0), 
5484                                                                                                 rect.Y + balloon_bordersize, 
5485                                                                                                 rect.Width - ((3 * balloon_bordersize) + iconsize), 
5486                                                                                                 rect.Height - (2 * balloon_bordersize));
5487                         
5488                         Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
5489                         dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
5490                         
5491                         // Text
5492                         Rectangle textrect = new Rectangle (rect.X + balloon_bordersize, 
5493                                                                                                 rect.Y + balloon_bordersize, 
5494                                                                                                 rect.Width - (2 * balloon_bordersize), 
5495                                                                                                 rect.Height - (2 * balloon_bordersize));
5496
5497                         StringFormat textformat = control.Format;
5498                         textformat.LineAlignment = StringAlignment.Far;
5499                         dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
5500                 }
5501
5502                 public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
5503                 {
5504                         Rectangle deskrect = Screen.GetWorkingArea (control);
5505                         SizeF maxsize = new SizeF (250, 200);
5506
5507                         SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
5508                         SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
5509                         
5510                         if (titlesize.Height < balloon_iconsize)
5511                                 titlesize.Height = balloon_iconsize;
5512                         
5513                         Rectangle rect = new Rectangle ();
5514                         rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
5515                         rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize);
5516                         rect.X = deskrect.Width - rect.Width - 2;
5517                         rect.Y = deskrect.Height - rect.Height - 2;
5518                         
5519                         return rect;
5520                 }
5521 #endif
5522                 #endregion      // BalloonWindow
5523
5524                 #region TrackBar
5525                 public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb)
5526                 {
5527                         int result = tb.Value;
5528                         int value_pos = tb.Value;
5529                         float pixels_betweenticks;
5530                         Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty;
5531                         Point channel_startpoint = Point.Empty, na_point = Point.Empty;
5532                         
5533                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point);
5534                         
5535                         /* Convert thumb position from mouse position to value*/
5536                         if (tb.Orientation == Orientation.Vertical) {
5537                                 value_pos = (int)Math.Round (((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0);
5538
5539                                 if (value_pos + tb.Minimum > tb.Maximum)
5540                                         value_pos = tb.Maximum - tb.Minimum;
5541                                 else if (value_pos + tb.Minimum < tb.Minimum)
5542                                         value_pos = 0;
5543
5544                                 result = value_pos + tb.Minimum;
5545                         } else {
5546                                 value_pos = (int)Math.Round (((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float) pixels_betweenticks), 0);
5547
5548                                 if (value_pos + tb.Minimum > tb.Maximum)
5549                                         value_pos = tb.Maximum - tb.Minimum;
5550                                 else if (value_pos + tb.Minimum < tb.Minimum)
5551                                         value_pos = 0;
5552
5553                                 result = value_pos + tb.Minimum;
5554                         }
5555                         
5556                         return result;
5557                 }
5558                 
5559                 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)
5560                 {
5561                         thumb_area = Rectangle.Empty;
5562                         thumb_pos = Rectangle.Empty;
5563                         
5564                         if (tb.Orientation == Orientation.Vertical) {
5565                                 toptick_startpoint = new Point ();
5566                                 bottomtick_startpoint = new Point ();
5567                                 channel_startpoint = new Point ();
5568                                 float pixel_len;
5569                                 const int space_from_right = 8;
5570                                 const int space_from_left = 8;
5571                                 const int space_from_bottom = 11;
5572                                 Rectangle area = tb.ClientRectangle;
5573
5574                                 switch (tb.TickStyle) {
5575                                 case TickStyle.BottomRight:
5576                                 case TickStyle.None:
5577                                         channel_startpoint.Y = 8;
5578                                         channel_startpoint.X = 9;
5579                                         bottomtick_startpoint.Y = 13;
5580                                         bottomtick_startpoint.X = 24;
5581                                         break;
5582                                 case TickStyle.TopLeft:
5583                                         channel_startpoint.Y = 8;
5584                                         channel_startpoint.X = 19;
5585                                         toptick_startpoint.Y = 13;
5586                                         toptick_startpoint.X = 8;
5587                                         break;
5588                                 case TickStyle.Both:
5589                                         channel_startpoint.Y = 8;
5590                                         channel_startpoint.X = 18;
5591                                         bottomtick_startpoint.Y = 13;
5592                                         bottomtick_startpoint.X = 32;
5593                                         toptick_startpoint.Y = 13;
5594                                         toptick_startpoint.X = 8;
5595                                         break;
5596                                 default:
5597                                         break;
5598                                 }
5599
5600                                 thumb_area.X = area.X + channel_startpoint.X;
5601                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5602                                 thumb_area.Height = area.Height - space_from_right - space_from_left;
5603                                 thumb_area.Width = TrackBarVerticalTrackWidth;
5604
5605                                 pixel_len = thumb_area.Height - 11;
5606                                 if (tb.Maximum == tb.Minimum) {
5607                                         pixels_betweenticks = 0;
5608                                 } else {
5609                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5610                                 }
5611
5612                                 thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum));
5613                         } else {        
5614                                 toptick_startpoint = new Point ();
5615                                 bottomtick_startpoint = new Point ();
5616                                 channel_startpoint = new Point ();
5617                                 float pixel_len;
5618                                 const int space_from_right = 8;
5619                                 const int space_from_left = 8;
5620                                 Rectangle area = tb.ClientRectangle;
5621                                                         
5622                                 switch (tb.TickStyle) {
5623                                 case TickStyle.BottomRight:
5624                                 case TickStyle.None:
5625                                         channel_startpoint.X = 8;
5626                                         channel_startpoint.Y = 9;
5627                                         bottomtick_startpoint.X = 13;
5628                                         bottomtick_startpoint.Y = 24;                           
5629                                         break;
5630                                 case TickStyle.TopLeft:
5631                                         channel_startpoint.X = 8;
5632                                         channel_startpoint.Y = 19;
5633                                         toptick_startpoint.X = 13;
5634                                         toptick_startpoint.Y = 8;
5635                                         break;
5636                                 case TickStyle.Both:
5637                                         channel_startpoint.X = 8;
5638                                         channel_startpoint.Y = 18;      
5639                                         bottomtick_startpoint.X = 13;
5640                                         bottomtick_startpoint.Y = 32;                           
5641                                         toptick_startpoint.X = 13;
5642                                         toptick_startpoint.Y = 8;                               
5643                                         break;
5644                                 default:
5645                                         break;
5646                                 }
5647                                                         
5648                                 thumb_area.X = area.X + channel_startpoint.X;
5649                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5650                                 thumb_area.Width = area.Width - space_from_right - space_from_left;
5651                                 thumb_area.Height = TrackBarHorizontalTrackHeight;
5652
5653                                 pixel_len = thumb_area.Width - 11;
5654                                 if (tb.Maximum == tb.Minimum) {
5655                                         pixels_betweenticks = 0;
5656                                 } else {
5657                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5658                                 }
5659
5660                                 thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum));
5661                         }
5662
5663                         thumb_pos.Size = TrackBarGetThumbSize (tb);
5664                 }
5665
5666                 protected virtual Size TrackBarGetThumbSize (TrackBar trackBar)
5667                 {
5668                         return TrackBarGetThumbSize ();
5669                 }
5670
5671                 public static Size TrackBarGetThumbSize ()
5672                 {
5673                         /* Draw thumb fixed 10x22 size */
5674                         return new Size (10, 22);
5675                 }
5676
5677                 public const int TrackBarVerticalTrackWidth = 4;
5678
5679                 public const int TrackBarHorizontalTrackHeight = 4;
5680
5681                 #region Ticks
5682                 protected interface ITrackBarTickPainter
5683                 {
5684                         void Paint (float x1, float y1, float x2, float y2);
5685                 }
5686
5687                 class TrackBarTickPainter : ITrackBarTickPainter
5688                 {
5689                         readonly Graphics g;
5690                         readonly Pen pen;
5691                         public TrackBarTickPainter (Graphics g, Pen pen)
5692                         {
5693                                 this.g = g;
5694                                 this.pen = pen;
5695                         }
5696                         public void Paint (float x1, float y1, float x2, float y2)
5697                         {
5698                                 g.DrawLine (pen, x1, y1, x2, y2);
5699                         }
5700                 }
5701                 protected virtual ITrackBarTickPainter GetTrackBarTickPainter (Graphics g)
5702                 {
5703                         return new TrackBarTickPainter (g, ResPool.GetPen (pen_ticks_color));
5704                 }
5705                 #endregion
5706
5707                 #region DrawTrackBar_Vertical
5708                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5709                         ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
5710                         float ticks, int value_pos, bool mouse_value) {                 
5711
5712                         Point toptick_startpoint = new Point ();
5713                         Point bottomtick_startpoint = new Point ();
5714                         Point channel_startpoint = new Point ();
5715                         float pixel_len;
5716                         float pixels_betweenticks;
5717                         Rectangle area = tb.ClientRectangle;
5718                         
5719                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5720
5721                         #region Track
5722                         TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5723                         #endregion
5724
5725                         #region Thumb
5726                         switch (tb.TickStyle)   {
5727                         case TickStyle.BottomRight:
5728                         case TickStyle.None:
5729                                 thumb_pos.X = channel_startpoint.X - 8;
5730                                 TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5731                                 break;
5732                         case TickStyle.TopLeft:
5733                                 thumb_pos.X = channel_startpoint.X - 10;
5734                                 TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5735                                 break;
5736                         default:
5737                                 thumb_pos.X = area.X + 10;
5738                                 TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5739                                 break;
5740                         }
5741                         #endregion
5742
5743                         pixel_len = thumb_area.Height - 11;
5744                         pixels_betweenticks = pixel_len / ticks;
5745                         
5746                         thumb_area.X = thumb_pos.X;
5747                         thumb_area.Y = channel_startpoint.Y;
5748                         thumb_area.Width = thumb_pos.Height;
5749
5750                         #region Ticks
5751                         if (pixels_betweenticks <= 0)
5752                                 return;
5753                         if (tb.TickStyle == TickStyle.None)
5754                                 return;
5755                         Region outside = new Region (area);
5756                         outside.Exclude (thumb_area);                   
5757                         
5758                         if (outside.IsVisible (clip_rectangle)) {
5759                                 ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter (dc);
5760
5761                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5762                                         float x = area.X + bottomtick_startpoint.X;
5763                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks)    {
5764                                                 float y = area.Y + bottomtick_startpoint.Y + inc;
5765                                                 tick_painter.Paint (
5766                                                         x, y,
5767                                                         x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y);
5768                                         }
5769                                 }
5770
5771                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5772                                         float x = area.X + toptick_startpoint.X; 
5773                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
5774                                                 float y = area.Y + toptick_startpoint.Y + inc;
5775                                                 tick_painter.Paint (
5776                                                         x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y,
5777                                                         x, y);
5778                                         }                       
5779                                 }
5780                         }
5781                         
5782                         outside.Dispose ();
5783                         #endregion
5784                 }
5785
5786                 #region Track
5787                 protected virtual void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5788                 {
5789                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5790                                 1, thumb_area.Height);
5791
5792                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y,
5793                                 1, thumb_area.Height);
5794
5795                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y,
5796                                 1, thumb_area.Height);
5797                 }
5798                 #endregion
5799
5800                 #region Thumb
5801                 protected virtual void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5802                 {
5803                         Pen pen = SystemPens.ControlLightLight;
5804                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10);
5805                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
5806                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
5807
5808                         pen = SystemPens.ControlDark;
5809                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9);
5810                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4);
5811
5812                         pen = SystemPens.ControlDarkDark;
5813                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10);
5814                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5);
5815
5816                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
5817                         dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
5818                         dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
5819                         dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
5820                 }
5821
5822                 protected virtual void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5823                 {
5824                         Pen pen = SystemPens.ControlLightLight;
5825                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
5826                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
5827
5828                         pen = SystemPens.ControlDark;
5829                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9);
5830                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5);
5831                         dc.DrawLine (pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1);
5832
5833                         pen = SystemPens.ControlDarkDark;
5834                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10);
5835                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5);
5836                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10);
5837
5838                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
5839                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
5840                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
5841                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
5842                 }
5843
5844                 protected virtual void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5845                 {
5846                         Pen pen = SystemPens.ControlLightLight;
5847                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
5848                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
5849
5850                         pen = SystemPens.ControlDark;
5851                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9);
5852                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8);
5853
5854                         pen = SystemPens.ControlDarkDark;
5855                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10);
5856                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9);
5857
5858                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
5859                 }
5860                 #endregion
5861
5862                 #region Ticks
5863                 protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g)
5864                 {
5865                         return GetTrackBarTickPainter (g);
5866                 }
5867                 #endregion
5868                 #endregion
5869
5870                 #region DrawTrackBar_Horizontal
5871                 /* 
5872                         Horizontal trackbar 
5873                   
5874                         Does not matter the size of the control, Win32 always draws:
5875                                 - Ticks starting from pixel 13, 8
5876                                 - Channel starting at pos 8, 19 and ends at Width - 8
5877                                 - Autosize makes always the control 45 pixels high
5878                                 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
5879                                 
5880                 */
5881                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5882                         ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5883                         float ticks, int value_pos, bool mouse_value) {                 
5884                         Point toptick_startpoint = new Point ();
5885                         Point bottomtick_startpoint = new Point ();
5886                         Point channel_startpoint = new Point ();
5887                         float pixel_len;
5888                         float pixels_betweenticks;
5889                         Rectangle area = tb.ClientRectangle;
5890                         
5891                         GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5892
5893                         #region Track
5894                         TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5895                         #endregion
5896
5897                         #region Thumb
5898                         switch (tb.TickStyle) {
5899                         case TickStyle.BottomRight:
5900                         case TickStyle.None:
5901                                 thumb_pos.Y = channel_startpoint.Y - 8;
5902                                 TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5903                                 break;
5904                         case TickStyle.TopLeft:
5905                                 thumb_pos.Y = channel_startpoint.Y - 10;
5906                                 TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5907                                 break;
5908                         default:
5909                                 thumb_pos.Y = area.Y + 10;
5910                                 TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5911                                 break;
5912                         }
5913                         #endregion
5914
5915                         pixel_len = thumb_area.Width - 11;
5916                         pixels_betweenticks = pixel_len / ticks;
5917
5918                         thumb_area.Y = thumb_pos.Y;
5919                         thumb_area.X = channel_startpoint.X;
5920                         thumb_area.Height = thumb_pos.Height;
5921                         #region Ticks
5922                         if (pixels_betweenticks <= 0)
5923                                 return;
5924                         if (tb.TickStyle == TickStyle.None)
5925                                 return;
5926                         Region outside = new Region (area);
5927                         outside.Exclude (thumb_area);
5928
5929                         if (outside.IsVisible (clip_rectangle)) {
5930                                 ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter (dc);
5931
5932                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5933                                         float y = area.Y + bottomtick_startpoint.Y;
5934                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5935                                                 float x = area.X + bottomtick_startpoint.X + inc;
5936                                                 tick_painter.Paint (
5937                                                         x, y, 
5938                                                         x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2));
5939                                         }
5940                                 }
5941
5942                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5943                                         float y = area.Y + toptick_startpoint.Y;
5944                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5945                                                 float x = area.X + toptick_startpoint.X + inc;
5946                                                 tick_painter.Paint (
5947                                                         x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2), 
5948                                                         x, y);
5949                                         }                       
5950                                 }
5951                         }
5952                         
5953                         outside.Dispose ();
5954                         #endregion
5955                 }
5956
5957                 #region Track
5958                 protected virtual void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5959                 {
5960                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5961                                 thumb_area.Width, 1);
5962
5963                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1,
5964                                 thumb_area.Width, 1);
5965
5966                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3,
5967                                 thumb_area.Width, 1);
5968                 }
5969                 #endregion
5970
5971                 #region Thumb
5972                 protected virtual void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5973                 {
5974                         Pen pen = SystemPens.ControlLightLight;
5975                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
5976                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
5977                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
5978
5979                         pen = SystemPens.ControlDark;
5980                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15);
5981                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4);
5982
5983                         pen = SystemPens.ControlDarkDark;
5984                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16);
5985                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5);
5986
5987                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
5988                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
5989                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
5990                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
5991                 }
5992
5993                 protected virtual void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5994                 {
5995                         Pen pen = SystemPens.ControlLightLight;
5996                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
5997                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
5998
5999                         pen = SystemPens.ControlDark;
6000                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
6001                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
6002                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19);
6003
6004                         pen = SystemPens.ControlDarkDark;
6005                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
6006                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1);
6007                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
6008
6009                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
6010                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
6011                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
6012                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
6013                 }
6014
6015                 protected virtual void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6016                 {
6017                         Pen pen = SystemPens.ControlLightLight;
6018                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
6019                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
6020
6021                         pen = SystemPens.ControlDark;
6022                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
6023                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
6024
6025                         pen = SystemPens.ControlDarkDark;
6026                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20);
6027                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
6028
6029                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
6030                 }
6031                 #endregion
6032
6033                 #region Ticks
6034                 protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g)
6035                 {
6036                         return GetTrackBarTickPainter (g);
6037                 }
6038                 #endregion
6039                 #endregion
6040
6041                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) 
6042                 {
6043                         Brush           br_thumb;
6044                         int             value_pos;
6045                         bool            mouse_value;
6046                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
6047                         Rectangle       area;
6048                         Rectangle       thumb_pos = tb.ThumbPos;
6049                         Rectangle       thumb_area = tb.ThumbArea;
6050                         
6051                         if (tb.thumb_pressed) {
6052                                 value_pos = tb.thumb_mouseclick;
6053                                 mouse_value = true;
6054                         } else {
6055                                 value_pos = tb.Value - tb.Minimum;
6056                                 mouse_value = false;
6057                         }
6058
6059                         area = tb.ClientRectangle;
6060
6061                         if (!tb.Enabled) {
6062                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
6063                         } else if (tb.thumb_pressed == true) {
6064                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
6065                         } else {
6066                                 br_thumb = SystemBrushes.Control;
6067                         }
6068
6069                         
6070                         /* Control Background */
6071                         if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
6072                                 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
6073                         } else {
6074                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
6075                         }
6076                         
6077                         if (tb.Focused) {
6078                                 CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor);
6079                         }
6080
6081                         if (tb.Orientation == Orientation.Vertical) {
6082                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6083                                         br_thumb, ticks, value_pos, mouse_value);
6084                         
6085                         } else {
6086                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6087                                         br_thumb, ticks, value_pos, mouse_value);
6088                         }
6089
6090                         tb.ThumbPos = thumb_pos;
6091                         tb.ThumbArea = thumb_area;
6092                 }
6093
6094                 public override Size TrackBarDefaultSize {
6095                         get {
6096                                 return new Size (104, 42);
6097                         }
6098                 }
6099
6100                 public override bool TrackBarHasHotThumbStyle {
6101                         get {
6102                                 return false;
6103                         }
6104                 }
6105                 #endregion      // TrackBar
6106
6107                 #region UpDownBase
6108                 public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state)
6109                 {
6110                         ControlPaint.DrawScrollButton (g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal);
6111                 }
6112
6113                 public override bool UpDownBaseHasHotButtonStyle {
6114                         get {
6115                                 return false;
6116                         }
6117                 }
6118                 #endregion
6119
6120                 #region VScrollBar
6121                 public override Size VScrollBarDefaultSize {
6122                         get {
6123                                 return new Size (this.ScrollBarButtonSize, 80);
6124                         }
6125                 }
6126                 #endregion      // VScrollBar
6127
6128                 #region TreeView
6129                 public override Size TreeViewDefaultSize {
6130                         get {
6131                                 return new Size (121, 97);
6132                         }
6133                 }
6134
6135                 public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle)
6136                 {
6137                         int height = treeView.ActualItemHeight - 2;
6138                         dc.FillRectangle (ResPool.GetSolidBrush (treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height);
6139                         
6140                         dc.DrawRectangle (SystemPens.ControlDarkDark, x, middle - 4, 8, 8);
6141
6142                         if (node.IsExpanded) {
6143                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); 
6144                         } else {
6145                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
6146                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2);
6147                         }
6148                 }
6149                 #endregion
6150
6151                 #region Managed window
6152                 public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
6153                 {
6154                         if (wm.IsToolWindow && !wm.IsMinimized)
6155                                 return SystemInformation.ToolWindowCaptionHeight;
6156                         if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6157                                 return 0;
6158                         return SystemInformation.CaptionHeight;
6159                 }
6160
6161                 public override int ManagedWindowBorderWidth (InternalWindowManager wm)
6162                 {
6163                         if ((wm.IsToolWindow && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow) ||
6164                                 wm.IsMinimized)
6165                                 return 3;
6166                         else
6167                                 return 4;
6168                 }
6169
6170                 public override int ManagedWindowIconWidth (InternalWindowManager wm)
6171                 {
6172                         return ManagedWindowTitleBarHeight (wm) - 5;
6173                 }
6174
6175                 public override void ManagedWindowSetButtonLocations (InternalWindowManager wm)
6176                 {
6177                         TitleButtons buttons = wm.TitleButtons;
6178                         Form form = wm.form;
6179                         
6180                         buttons.HelpButton.Visible = form.HelpButton;
6181                         
6182                         foreach (TitleButton button in buttons) {
6183                                 button.Visible = false;
6184                         }
6185                         
6186                         switch (form.FormBorderStyle) {
6187                         case FormBorderStyle.None:
6188                                 if (form.WindowState != FormWindowState.Normal)
6189                                         goto case FormBorderStyle.Sizable;
6190                                 break;
6191                         case FormBorderStyle.FixedToolWindow:
6192                         case FormBorderStyle.SizableToolWindow:
6193                                 buttons.CloseButton.Visible = true;
6194                                 if (form.WindowState != FormWindowState.Normal)
6195                                         goto case FormBorderStyle.Sizable;
6196                                 break;
6197                         case FormBorderStyle.FixedSingle:
6198                         case FormBorderStyle.Fixed3D:
6199                         case FormBorderStyle.FixedDialog:
6200                         case FormBorderStyle.Sizable:
6201                                 switch (form.WindowState) {
6202                                         case FormWindowState.Normal:
6203                                                 buttons.MinimizeButton.Visible = true;
6204                                                 buttons.MaximizeButton.Visible = true;
6205                                                 buttons.RestoreButton.Visible = false;
6206                                                 break;
6207                                         case FormWindowState.Maximized:
6208                                                 buttons.MinimizeButton.Visible = true;
6209                                                 buttons.MaximizeButton.Visible = false;
6210                                                 buttons.RestoreButton.Visible = true;
6211                                                 break;
6212                                         case FormWindowState.Minimized:
6213                                                 buttons.MinimizeButton.Visible = false;
6214                                                 buttons.MaximizeButton.Visible = true;
6215                                                 buttons.RestoreButton.Visible = true;
6216                                                 break;
6217                                 }
6218                                 buttons.CloseButton.Visible = true;
6219                                 break;
6220                         }
6221
6222                         // Respect MinimizeBox/MaximizeBox
6223                         if (form.MinimizeBox == false && form.MaximizeBox == false) {
6224                                 buttons.MinimizeButton.Visible = false;
6225                                 buttons.MaximizeButton.Visible = false;
6226                         } else if (form.MinimizeBox == false)
6227                                 buttons.MinimizeButton.State = ButtonState.Inactive;
6228                         else if (form.MaximizeBox == false)
6229                                 buttons.MaximizeButton.State = ButtonState.Inactive;
6230
6231                         int bw = ManagedWindowBorderWidth (wm);
6232                         Size btsize = ManagedWindowButtonSize (wm);
6233                         int btw = btsize.Width;
6234                         int bth = btsize.Height;
6235                         int top = bw + 2;
6236                         int left = form.Width - bw - btw - ManagedWindowSpacingAfterLastTitleButton;
6237                         
6238                         if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
6239                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6240                                 left -= 2 + btw;
6241                                 
6242                                 if (buttons.MaximizeButton.Visible) {
6243                                         buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6244                                         left -= 2 + btw;
6245                                 } 
6246                                 if (buttons.RestoreButton.Visible) {
6247                                         buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth);
6248                                         left -= 2 + btw;
6249                                 }
6250
6251                                 buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6252                                 left -= 2 + btw;
6253                         } else if (wm.IsToolWindow) {
6254                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6255                                 left -= 2 + btw;
6256                         }
6257                 }
6258
6259                 protected virtual Rectangle ManagedWindowDrawTitleBarAndBorders (Graphics dc, Rectangle clip, InternalWindowManager wm)
6260                 {
6261                         Form form = wm.Form;
6262                         int tbheight = ManagedWindowTitleBarHeight (wm);
6263                         int bdwidth = ManagedWindowBorderWidth (wm);
6264                         Color titlebar_color = Color.FromArgb (255, 10, 36, 106);
6265                         Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240);
6266                         Color color = ThemeEngine.Current.ColorControlDark;
6267                         Color color2 = Color.FromArgb (255, 192, 192, 192);
6268
6269                         Pen pen = ResPool.GetPen (ColorControl);
6270                         Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
6271                         ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
6272                         // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves
6273                         borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5);
6274                         for (int i = 2; i < bdwidth; i++) {
6275                                 dc.DrawRectangle (pen, borders);
6276                                 borders.Inflate (-1, -1);
6277                         }                               
6278
6279
6280                         bool draw_titlebar_enabled = false;
6281                         if (wm.Form.Parent != null && wm.Form.Parent is Form) {
6282                                 draw_titlebar_enabled = false;
6283                         } else if (wm.IsActive && !wm.IsMaximized) {
6284                                 draw_titlebar_enabled = true;
6285                         }
6286                         if (draw_titlebar_enabled) {
6287                                 color = titlebar_color;
6288                                 color2 = titlebar_color2;
6289                         }
6290
6291                         Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1);
6292
6293                         // HACK: For now always draw the titlebar until we get updates better
6294                         if (tb.Width > 0 && tb.Height > 0) {
6295                                 using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal))
6296                                 {
6297                                         dc.FillRectangle (gradient, tb);
6298                                 }       
6299                         }
6300                         
6301                         if (!wm.IsMinimized)
6302                                 // Draw the line just beneath the title bar
6303                                 dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth,
6304                                                 tbheight + bdwidth - 1, form.Width - bdwidth - 1,
6305                                                 tbheight + bdwidth - 1);
6306                         return tb;
6307                 }
6308
6309                 public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
6310                 {
6311 #if debug
6312                         Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations");
6313                         dc.FillRectangle (Brushes.Black, clip);
6314 #endif
6315                         Rectangle tb = ManagedWindowDrawTitleBarAndBorders (dc, clip, wm);
6316
6317                         Form form = wm.Form;
6318                         if (wm.ShowIcon) {
6319                                 Rectangle icon = ManagedWindowGetTitleBarIconArea (wm);
6320                                 if (icon.IntersectsWith (clip))
6321                                         dc.DrawIcon (form.Icon, icon);
6322                                 const int SpacingBetweenIconAndCaption = 2;
6323                                 tb.Width -= icon.Right + SpacingBetweenIconAndCaption - tb.X ;
6324                                 tb.X = icon.Right + SpacingBetweenIconAndCaption;
6325                         }
6326                         
6327                         foreach (TitleButton button in wm.TitleButtons.AllButtons) {
6328                                 tb.Width -= Math.Max (0, tb.Right - DrawTitleButton (dc, button, clip, form));
6329                         }
6330                         const int SpacingBetweenCaptionAndLeftMostButton = 3;
6331                         tb.Width -= SpacingBetweenCaptionAndLeftMostButton;
6332
6333                         string window_caption = form.Text;
6334                         window_caption = window_caption.Replace (Environment.NewLine, string.Empty);
6335
6336                         if (window_caption != null && window_caption != string.Empty) {
6337                                 StringFormat format = new StringFormat ();
6338                                 format.FormatFlags = StringFormatFlags.NoWrap;
6339                                 format.Trimming = StringTrimming.EllipsisCharacter;
6340                                 format.LineAlignment = StringAlignment.Center;
6341
6342                                 if (tb.IntersectsWith (clip))
6343                                         dc.DrawString (window_caption, WindowBorderFont,
6344                                                 ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
6345                                                 tb, format);
6346                         }
6347                 }
6348
6349                 public override Size ManagedWindowButtonSize (InternalWindowManager wm)
6350                 {
6351                         int height = ManagedWindowTitleBarHeight (wm);
6352                         if (!wm.IsMaximized && !wm.IsMinimized) {
6353                                 if (wm.IsToolWindow)
6354                                         return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
6355                                                         height - 5);
6356                                 if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6357                                         return Size.Empty;
6358                         } else
6359                                 height = SystemInformation.CaptionHeight;
6360
6361                         return new Size (SystemInformation.CaptionButtonSize.Width - 2,
6362                                         height - 5);
6363                 }
6364
6365                 private int DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6366                 {
6367                         if (!button.Visible) {
6368                                 return int.MaxValue;
6369                         }
6370                         
6371                         if (button.Rectangle.IntersectsWith (clip)) {
6372                                 ManagedWindowDrawTitleButton (dc, button, clip, form);
6373                         }
6374                         return button.Rectangle.Left;
6375                 }
6376
6377                 protected virtual void ManagedWindowDrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6378                 {
6379                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6380
6381                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6382                                         button.Caption, button.State);
6383                 }
6384
6385                 public override Rectangle ManagedWindowGetTitleBarIconArea (InternalWindowManager wm)
6386                 {
6387                         int bw = ManagedWindowBorderWidth (wm);
6388                         return new Rectangle (bw + 3, bw + 2, wm.IconWidth, wm.IconWidth);
6389                 }
6390
6391                 public override Size ManagedWindowGetMenuButtonSize (InternalWindowManager wm)
6392                 {
6393                         Size result = SystemInformation.MenuButtonSize;
6394                         result.Width -= 2;
6395                         result.Height -= 4;
6396                         return result;
6397                 }
6398
6399                 public override bool ManagedWindowTitleButtonHasHotElementStyle (TitleButton button, Form form)
6400                 {
6401                         return false;
6402                 }
6403
6404                 public override void ManagedWindowDrawMenuButton (Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm)
6405                 {
6406                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6407                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6408                                         button.Caption, button.State);
6409                 }
6410
6411                 public override void ManagedWindowOnSizeInitializedOrChanged (Form form)
6412                 {
6413                 }
6414                 #endregion
6415
6416                 #region ControlPaint
6417                 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
6418                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6419                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6420                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6421                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6422                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6423                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6424                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6425                 }
6426
6427                 public override void CPDrawBorder (Graphics graphics, RectangleF bounds, Color leftColor, int leftWidth,
6428                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6429                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6430                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6431                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6432                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6433                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6434                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6435                 }
6436
6437                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
6438                         CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
6439                 }
6440
6441                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)
6442                 {
6443                         Pen             penTopLeft;
6444                         Pen             penTopLeftInner;
6445                         Pen             penBottomRight;
6446                         Pen             penBottomRightInner;
6447                         Rectangle       rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6448                         bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
6449                         
6450                         if ((style & Border3DStyle.Adjust) != 0) {
6451                                 rect.Y -= 2;
6452                                 rect.X -= 2;
6453                                 rect.Width += 4;
6454                                 rect.Height += 4;
6455                         }
6456                         
6457                         penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color);
6458                         
6459                         CPColor cpcolor = CPColor.Empty;
6460                         
6461                         if (!is_ColorControl)
6462                                 cpcolor = ResPool.GetCPColor (control_color);
6463                         
6464                         switch (style) {
6465                         case Border3DStyle.Raised:
6466                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6467                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6468                                 penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6469                                 break;
6470                         case Border3DStyle.Sunken:
6471                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6472                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6473                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6474                                 break;
6475                         case Border3DStyle.Etched:
6476                                 penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6477                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6478                                 break;
6479                         case Border3DStyle.RaisedOuter:
6480                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6481                                 break;
6482                         case Border3DStyle.SunkenOuter:
6483                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6484                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6485                                 break;
6486                         case Border3DStyle.RaisedInner:
6487                                 penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6488                                 penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6489                                 break;
6490                         case Border3DStyle.SunkenInner:
6491                                 penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6492                                 break;
6493                         case Border3DStyle.Flat:
6494                                 penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6495                                 break;
6496                         case Border3DStyle.Bump:
6497                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6498                                 break;
6499                         default:
6500                                 break;
6501                         }
6502                         
6503                         bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter));
6504                         
6505                         if ((sides & Border3DSide.Middle) != 0) {
6506                                 Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color);
6507                                 graphics.FillRectangle (brush, rect);
6508                         }
6509                         
6510                         if ((sides & Border3DSide.Left) != 0) {
6511                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top);
6512                                 if ((rect.Width > 2) && inner)
6513                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top);
6514                         }
6515                         
6516                         if ((sides & Border3DSide.Top) != 0) {
6517                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top);
6518                                 if ((rect.Height > 2) && inner)
6519                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1);
6520                         }
6521                         
6522                         if ((sides & Border3DSide.Right) != 0) {
6523                                 graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
6524                                 if ((rect.Width > 3) && inner)
6525                                         graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2);
6526                         }
6527                         
6528                         if ((sides & Border3DSide.Bottom) != 0) {
6529                                 graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6530                                 if ((rect.Height > 3) && inner)
6531                                         graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
6532                         }
6533                 }
6534
6535                 public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
6536                 {
6537                         CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight);
6538                 }
6539
6540                 private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)
6541                 {
6542                         // sadly enough, the rectangle gets always filled with a hatchbrush
6543                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6544                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6545                                                                                  ColorControl.G, ColorControl.B),
6546                                                                  ColorControl),
6547                                           rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2);
6548                         
6549                         if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) {
6550                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6551                                 
6552                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6553                         } else
6554                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6555                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6556                         } else
6557                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6558                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6559                                 
6560                                 Pen pen = DarkPen;
6561                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6562                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6563                                 
6564                                 pen = NormalPen;
6565                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6566                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6567                                 
6568                                 pen = LightPen;
6569                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6570                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6571                         } else
6572                         if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) {
6573                                 Pen pen = DarkPen;
6574                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6575                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6576                                 
6577                                 pen = NormalPen;
6578                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6579                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6580                                 
6581                                 pen = LightPen;
6582                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6583                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6584                         } else
6585                         if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) {
6586                                 Pen pen = LightPen;
6587                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6588                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6589                                 
6590                                 pen = NormalPen;
6591                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2);
6592                                 dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3);
6593                                 
6594                                 pen = DarkPen;
6595                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1);
6596                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2);
6597                         }
6598                 }
6599
6600
6601                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
6602                         Rectangle       captionRect;
6603                         int                     lineWidth;
6604
6605                         CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight);
6606
6607                         if (rectangle.Width<rectangle.Height) {
6608                                 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
6609                         } else {
6610                                 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
6611                         }
6612
6613                         if ((state & ButtonState.Pushed)!=0) {
6614                                 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
6615                         }
6616
6617                         /* Make sure we've got at least a line width of 1 */
6618                         lineWidth=Math.Max(1, captionRect.Width/7);
6619
6620                         switch(button) {
6621                         case CaptionButton.Close: {
6622                                 Pen     pen;
6623
6624                                 if ((state & ButtonState.Inactive)!=0) {
6625                                         pen = ResPool.GetSizedPen (ColorControlLight, lineWidth);
6626                                         DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
6627
6628                                         pen = ResPool.GetSizedPen (ColorControlDark, lineWidth);
6629                                         DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
6630                                         return;
6631                                 } else {
6632                                         pen = ResPool.GetSizedPen (ColorControlText, lineWidth);
6633                                         DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
6634                                         return;
6635                                 }
6636                         }
6637
6638                         case CaptionButton.Help:
6639                         case CaptionButton.Maximize:
6640                         case CaptionButton.Minimize:
6641                         case CaptionButton.Restore: {
6642                                 if ((state & ButtonState.Inactive)!=0) {
6643                                         DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
6644
6645                                         DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
6646                                         return;
6647                                 } else {
6648                                         DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
6649                                         return;
6650                                 }
6651                         }
6652                         }
6653                 }
6654
6655                 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
6656                 {
6657                         Pen check_pen = Pens.Black;
6658                         
6659                         Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6660                         
6661                         if ((state & ButtonState.All) == ButtonState.All) {
6662                                 cb_rect.Width -= 2;
6663                                 cb_rect.Height -= 2;
6664                                 
6665                                 dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6666                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6667                                 
6668                                 check_pen = SystemPens.ControlDark;
6669                         } else
6670                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6671                                 cb_rect.Width -= 2;
6672                                 cb_rect.Height -= 2;
6673                                 
6674                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6675                                         dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6676                                 else
6677                                         dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6678                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6679                         } else {
6680                                 cb_rect.Width -= 1;
6681                                 cb_rect.Height -= 1;
6682                                 
6683                                 int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height;
6684                                 
6685                                 int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2);
6686                                 int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2);
6687                                 
6688                                 Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
6689                                 
6690                                 if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) {
6691                                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6692                                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6693                                                                                                  ColorControl.G, ColorControl.B),
6694                                                                                  ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6695                                 } else
6696                                         dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6697                                 
6698                                 Pen pen = SystemPens.ControlDark;
6699                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1);
6700                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y);
6701                                 
6702                                 pen = SystemPens.ControlDarkDark;
6703                                 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2);
6704                                 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1);
6705                                 
6706                                 pen = SystemPens.ControlLightLight;
6707                                 dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom);
6708                                 dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom);
6709                                 
6710                                 // oh boy, matching ms is like fighting against windmills
6711                                 using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
6712                                                                                    Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6713                                                                                                    ColorControl.G, ColorControl.B), ColorControl))) {
6714                                         dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6715                                         dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1);
6716                                 }
6717                                 
6718                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6719                                         check_pen = SystemPens.ControlDark;
6720                         }
6721                         
6722                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6723                                 int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2;
6724                                 
6725                                 if (check_size < 7) {
6726                                         int lineWidth = Math.Max (3, check_size / 3);
6727                                         int Scale = Math.Max (1, check_size / 9);
6728                                         
6729                                         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, 
6730                                                                         check_size, check_size);
6731                                         
6732                                         for (int i = 0; i < lineWidth; i++) {
6733                                                 dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
6734                                                 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);
6735                                         }
6736                                 } else {
6737                                         int lineWidth = Math.Max (3, check_size / 3) + 1;
6738                                         
6739                                         int x_half = cb_rect.Width / 2;
6740                                         int y_half = cb_rect.Height / 2;
6741                                         
6742                                         Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2), 
6743                                                                         check_size, check_size);
6744                                         
6745                                         int gradient_left = check_size / 3;
6746                                         int gradient_right = check_size - gradient_left - 1;
6747                                         
6748                                         
6749                                         for (int i = 0; i < lineWidth; i++) {
6750                                                 dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
6751                                                 dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i  - 1 - gradient_right);
6752                                         }
6753                                 }
6754                         }
6755                 }
6756
6757                 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
6758                         Point[]                 arrow = new Point[3];
6759                         Point                           P1;
6760                         Point                           P2;
6761                         Point                           P3;
6762                         int                             centerX;
6763                         int                             centerY;
6764                         int                             shiftX;
6765                         int                             shiftY;
6766                         Rectangle               rect;
6767
6768                         if ((state & ButtonState.Checked)!=0) {
6769                                 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);                              
6770                         }
6771
6772                         if ((state & ButtonState.Flat)!=0) {
6773                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
6774                         } else {
6775                                 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
6776                                         // this needs to render like a pushed button - jba
6777                                         // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6778                                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6779                                         graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle);
6780                                 } else {
6781                                         CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6782                                 }
6783                         }
6784
6785                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
6786                         centerX=rect.Left+rect.Width/2;
6787                         centerY=rect.Top+rect.Height/2;
6788                         shiftX=Math.Max(1, rect.Width/8);
6789                         shiftY=Math.Max(1, rect.Height/8);
6790
6791                         if ((state & ButtonState.Pushed)!=0) {
6792                                 shiftX++;
6793                                 shiftY++;
6794                         }
6795
6796                         rect.Y-=shiftY;
6797                         centerY-=shiftY;
6798                         P1=new Point(rect.Left, centerY);
6799                         P2=new Point(rect.Right, centerY);
6800                         P3=new Point(centerX, rect.Bottom);
6801
6802                         arrow[0]=P1;
6803                         arrow[1]=P2;
6804                         arrow[2]=P3;
6805                         
6806                         /* Draw the arrow */
6807                         if ((state & ButtonState.Inactive)!=0) {
6808                                 /* Move away from the shadow */
6809                                 arrow[0].X += 1;        arrow[0].Y += 1;
6810                                 arrow[1].X += 1;        arrow[1].Y += 1;
6811                                 arrow[2].X += 1;        arrow[2].Y += 1;
6812                                 
6813                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
6814
6815                                 arrow[0]=P1;
6816                                 arrow[1]=P2;
6817                                 arrow[2]=P3;
6818
6819                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
6820                         } else {
6821                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
6822                         }
6823                 }
6824
6825
6826                 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds)
6827                 {
6828                         Pen                     pen     = Pens.Black;
6829                         Rectangle       rect    = new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);      // Dunno why, but MS does it that way, too
6830                         int                     X;
6831                         int                     Y;
6832                         
6833                         graphics.FillRectangle (SystemBrushes.ControlLightLight, rect);
6834                         graphics.DrawRectangle (pen, rect);
6835                         
6836                         X = rect.X + rect.Width / 2;
6837                         Y = rect.Y + rect.Height / 2;
6838                         
6839                         /* Draw the cross */
6840                         graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2);
6841                         graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y);
6842                         
6843                         /* Draw 'arrows' for vertical lines */
6844                         graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3);
6845                         graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3);
6846                         
6847                         /* Draw 'arrows' for horizontal lines */
6848                         graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1);
6849                         graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1);
6850                 }
6851
6852                 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
6853                         // make a rectange to trace around border of the button
6854                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6855                         
6856                         Color outerColor = foreColor;
6857                         // adjust focus color according to the flatstyle
6858                         if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
6859                                 outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;                              
6860                         }
6861                         
6862                         // draw the outer rectangle
6863                         graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);                  
6864                         
6865                         // draw the inner rectangle                                             
6866                         if (button.FlatStyle == FlatStyle.Popup) {
6867                                 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
6868                         } else {
6869                                 // draw a flat inner rectangle
6870                                 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
6871                                 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));                               
6872                         }
6873                 }
6874                 
6875                 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
6876                 {       
6877                         // make a rectange to trace around border of the button
6878                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6879                         
6880 #if NotUntilCairoIsFixed
6881                         Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6882                         DashStyle oldStyle; // used for caching old penstyle
6883                         Pen pen = ResPool.GetPen (colorBackInverted);
6884
6885                         oldStyle = pen.DashStyle; 
6886                         pen.DashStyle = DashStyle.Dot;
6887
6888                         graphics.DrawRectangle (pen, trace_rectangle);
6889                         pen.DashStyle = oldStyle;
6890 #else
6891                         CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
6892 #endif
6893                 }
6894                                 
6895
6896                 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) 
6897                 {                       
6898                         Rectangle rect = rectangle;
6899                         Pen pen;
6900                         HatchBrush brush;
6901                                 
6902                         if (backColor.GetBrightness () >= 0.5) {
6903                                 foreColor = Color.Transparent;
6904                                 backColor = Color.Black;
6905                                 
6906                         } else {
6907                                 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6908                                 foreColor = Color.Black;
6909                         }
6910                                                 
6911                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
6912                         pen = new Pen (brush, 1);
6913                                                 
6914                         rect.Width--;
6915                         rect.Height--;                  
6916                         
6917                         graphics.DrawRectangle (pen, rect);
6918                         pen.Dispose ();
6919                 }
6920                 
6921                 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled)
6922                 {
6923                         Brush   sb;
6924                         Pen pen;
6925                         
6926                         if (primary == true) {
6927                                 pen = Pens.Black;
6928                                 if (enabled == true) {
6929                                         sb = Brushes.White;
6930                                 } else {
6931                                         sb = SystemBrushes.Control;
6932                                 }
6933                         } else {
6934                                 pen = Pens.White;
6935                                 if (enabled == true) {
6936                                         sb = Brushes.Black;
6937                                 } else {
6938                                         sb = SystemBrushes.Control;
6939                                 }
6940                         }
6941                         graphics.FillRectangle (sb, rectangle);
6942                         graphics.DrawRectangle (pen, rectangle);                        
6943                 }
6944
6945
6946                 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
6947                         Color   foreColor;
6948                         int     h;
6949                         int     b;
6950                         int     s;
6951
6952                         ControlPaint.Color2HBS(backColor, out h, out b, out s);
6953                         
6954                         if (b>127) {
6955                                 foreColor=Color.Black;
6956                         } else {
6957                                 foreColor=Color.White;
6958                         }
6959
6960                         // still not perfect. it seems that ms calculates the position of the first dot or line
6961
6962                         using (Pen pen = new Pen (foreColor)) {
6963                                 pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
6964                                 
6965                                 for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
6966                                         graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
6967                         }
6968                 }
6969
6970                 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
6971                         /*
6972                                 Microsoft seems to ignore the background and simply make
6973                                 the image grayscale. At least when having > 256 colors on
6974                                 the display.
6975                         */
6976                         
6977                         if (imagedisabled_attributes == null) {                         
6978                                 imagedisabled_attributes = new ImageAttributes ();
6979                                 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
6980                                           // This table would create a perfect grayscale image, based on luminance
6981                                           //                            new float[]{0.3f,0.3f,0.3f,0,0},
6982                                           //                            new float[]{0.59f,0.59f,0.59f,0,0},
6983                                           //                            new float[]{0.11f,0.11f,0.11f,0,0},
6984                                           //                            new float[]{0,0,0,1,0,0},
6985                                           //                            new float[]{0,0,0,0,1,0},
6986                                           //                            new float[]{0,0,0,0,0,1}
6987                 
6988                                           // This table generates a image that is grayscaled and then
6989                                           // brightened up. Seems to match MS close enough.
6990                                           new float[]{0.2f,0.2f,0.2f,0,0},
6991                                           new float[]{0.41f,0.41f,0.41f,0,0},
6992                                           new float[]{0.11f,0.11f,0.11f,0,0},
6993                                           new float[]{0.15f,0.15f,0.15f,1,0,0},
6994                                           new float[]{0.15f,0.15f,0.15f,0,1,0},
6995                                           new float[]{0.15f,0.15f,0.15f,0,0,1}
6996                                   });
6997                                   
6998                                  imagedisabled_attributes.SetColorMatrix (colorMatrix);
6999                         }
7000                         
7001                         graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
7002                         
7003                 }
7004
7005
7006                 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
7007                         Pen     penBorder;
7008                         Pen     penInside;
7009
7010                         if (primary) {
7011                                 penBorder = ResPool.GetSizedPen (Color.White, 2);
7012                                 penInside = ResPool.GetPen (Color.Black);
7013                         } else {
7014                                 penBorder = ResPool.GetSizedPen (Color.Black, 2);
7015                                 penInside = ResPool.GetPen (Color.White);
7016                         }
7017                         penBorder.Alignment=PenAlignment.Inset;
7018                         penInside.Alignment=PenAlignment.Inset;
7019
7020                         graphics.DrawRectangle(penBorder, rectangle);
7021                         graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
7022                 }
7023
7024
7025                 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) {
7026                         Rectangle       rect;
7027                         int                     lineWidth;
7028
7029                         if (backColor != Color.Empty)
7030                                 graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle);
7031                                 
7032                         Brush brush = ResPool.GetSolidBrush (color);
7033
7034                         switch(glyph) {
7035                         case MenuGlyph.Arrow: {
7036                                 float height = rectangle.Height * 0.7f;
7037                                 float width  = height / 2.0f;
7038                                 
7039                                 PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f));
7040
7041                                 PointF [] vertices = new PointF [3];
7042                                 vertices [0].X = ddCenter.X;
7043                                 vertices [0].Y = ddCenter.Y - (height / 2.0f);
7044                                 vertices [1].X = ddCenter.X;
7045                                 vertices [1].Y = ddCenter.Y + (height / 2.0f);
7046                                 vertices [2].X = ddCenter.X + width + 0.1f;
7047                                 vertices [2].Y = ddCenter.Y;
7048                                 
7049                                 graphics.FillPolygon (brush, vertices);
7050
7051                                 return;
7052                         }
7053
7054                         case MenuGlyph.Bullet: {
7055                                 
7056                                 lineWidth=Math.Max(2, rectangle.Width/3);
7057                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
7058                                 
7059                                 graphics.FillEllipse(brush, rect);
7060                                 
7061                                 return;
7062                         }
7063
7064                         case MenuGlyph.Checkmark: {
7065                                 
7066                                 Pen pen = ResPool.GetPen (color);
7067                                 lineWidth = Math.Max (2, rectangle.Width / 6);
7068                                 rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2);
7069
7070                                 int Scale = Math.Max (1, rectangle.Width / 12);
7071                                 int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2));
7072
7073                                 for (int i=0; i<lineWidth; i++) {
7074                                         graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i);
7075                                         graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i);
7076                                 }
7077                                 return;
7078                         }
7079                         }
7080
7081                 }
7082
7083                 [MonoTODO]
7084                 public override void CPDrawMixedCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state)
7085                 {
7086                         CPDrawCheckBox (graphics, rectangle, state);
7087                 }
7088
7089                 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
7090                 {
7091                         CPColor cpcolor = ResPool.GetCPColor (ColorControl);
7092                         
7093                         Color dot_color = Color.Black;
7094                         
7095                         Color top_left_outer = Color.Black;
7096                         Color top_left_inner = Color.Black;
7097                         Color bottom_right_outer = Color.Black;
7098                         Color bottom_right_inner = Color.Black;
7099                         
7100                         int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height  * 0.9f) : (int)(rectangle.Width * 0.9f);
7101                         int radius = ellipse_diameter / 2;
7102                         
7103                         Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter);
7104                         
7105                         Brush brush = null;
7106                         
7107                         if ((state & ButtonState.All) == ButtonState.All) {
7108                                 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
7109                                                                                                      ColorControl.G, ColorControl.B), ColorControl);
7110                                 dot_color = cpcolor.Dark;
7111                         } else
7112                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
7113                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7114                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7115                                 else
7116                                         brush = SystemBrushes.ControlLightLight;
7117                         } else {
7118                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7119                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7120                                 else
7121                                         brush = SystemBrushes.ControlLightLight;
7122                                 
7123                                 top_left_outer = cpcolor.Dark;
7124                                 top_left_inner = cpcolor.DarkDark;
7125                                 bottom_right_outer = cpcolor.Light;
7126                                 bottom_right_inner = Color.Transparent;
7127                                 
7128                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
7129                                         dot_color = cpcolor.Dark;
7130                         }
7131                         
7132                         dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1);
7133                         
7134                         int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f));
7135                         
7136                         dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f);
7137                         dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f);
7138                         dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f);
7139                         
7140                         if (bottom_right_inner != Color.Transparent)
7141                                 dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7142                         else
7143                                 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)) {
7144                                         dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7145                                 }
7146                         
7147                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
7148                                 int inflate = line_width * 4;
7149                                 Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate);
7150                                 if (rectangle.Height >  13) {
7151                                         tmp.X += 1;
7152                                         tmp.Y += 1;
7153                                         tmp.Height -= 1;
7154                                         dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp);
7155                                 } else {
7156                                         Pen pen = ResPool.GetPen (dot_color);
7157                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2));
7158                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1);
7159                                         
7160                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom);
7161                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom);
7162                                 }
7163                         }
7164                 }
7165
7166                 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
7167
7168                 }
7169
7170
7171                 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
7172
7173                 }
7174
7175
7176                 /* Scroll button: regular button + direction arrow */
7177                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
7178                 {
7179                         DrawScrollButtonPrimitive (dc, area, state);
7180                         
7181                         bool fill_rect = true;
7182                         int offset = 0;
7183                         
7184                         if ((state & ButtonState.Pushed) != 0)
7185                                 offset = 1;
7186                         
7187                         // skip the border
7188                         Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
7189                         
7190                         Point [] arrow = new Point [3];
7191                         for (int i = 0; i < 3; i++)
7192                                 arrow [i] = new Point ();
7193                         
7194                         Pen pen = SystemPens.ControlText;
7195                         
7196                         if ((state & ButtonState.Inactive) != 0) {
7197                                 pen = SystemPens.ControlDark;
7198                         }
7199                         
7200                         switch (type) {
7201                                 default:
7202                                 case ScrollButton.Down:
7203                                         int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7204                                         int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7205                                         if (x_middle == 1)
7206                                                 x_middle = 2;
7207                                         
7208                                         int triangle_height;
7209                                         
7210                                         if (rect.Height < 8) {
7211                                                 triangle_height = 2;
7212                                                 fill_rect = false;
7213                                         } else if (rect.Height == 11) {
7214                                                 triangle_height = 3;
7215                                         } else {
7216                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7217                                         }
7218                                         
7219                                         arrow [0].X = rect.X + x_middle;
7220                                         arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
7221                                         
7222                                         arrow [1].X = arrow [0].X + triangle_height - 1;
7223                                         arrow [1].Y = arrow [0].Y - triangle_height + 1;
7224                                         arrow [2].X = arrow [0].X - triangle_height + 1;
7225                                         arrow [2].Y = arrow [1].Y;
7226                                         
7227                                         dc.DrawPolygon (pen, arrow);
7228                                         
7229                                         if ((state & ButtonState.Inactive) != 0) {
7230                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
7231                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
7232                                         }
7233                                         
7234                                         if (fill_rect) {
7235                                                 for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
7236                                                         dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
7237                                                         arrow [1].X -= 1;
7238                                                         arrow [2].X += 1;
7239                                                 }
7240                                         }
7241                                         break;
7242                                         
7243                                 case ScrollButton.Up:
7244                                         x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7245                                         y_middle = (int)Math.Round (rect.Height / 2.0f);
7246                                         if (x_middle == 1)
7247                                                 x_middle = 2;
7248                                         
7249                                         if (y_middle == 1)
7250                                                 y_middle = 2;
7251                                         
7252                                         if (rect.Height < 8) {
7253                                                 triangle_height = 2;
7254                                                 fill_rect = false;
7255                                         } else if (rect.Height == 11) {
7256                                                 triangle_height = 3;
7257                                         } else {
7258                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7259                                         }
7260                                         
7261                                         arrow [0].X = rect.X + x_middle;
7262                                         arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
7263                                         
7264                                         arrow [1].X = arrow [0].X + triangle_height - 1;
7265                                         arrow [1].Y = arrow [0].Y + triangle_height - 1;
7266                                         arrow [2].X = arrow [0].X - triangle_height + 1;
7267                                         arrow [2].Y = arrow [1].Y;
7268                                         
7269                                         dc.DrawPolygon (pen, arrow);
7270                                         
7271                                         if ((state & ButtonState.Inactive) != 0) {
7272                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
7273                                         }
7274                                         
7275                                         if (fill_rect) {
7276                                                 for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
7277                                                         dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
7278                                                         arrow [1].X -= 1;
7279                                                         arrow [2].X += 1;
7280                                                 }
7281                                         }
7282                                         break;
7283                                         
7284                                 case ScrollButton.Left:
7285                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7286                                         if (y_middle == 1)
7287                                                 y_middle = 2;
7288                                         
7289                                         int triangle_width;
7290                                         
7291                                         if (rect.Width < 8) {
7292                                                 triangle_width = 2;
7293                                                 fill_rect = false;
7294                                         } else if (rect.Width == 11) {
7295                                                 triangle_width = 3;
7296                                         } else {
7297                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7298                                         }
7299                                         
7300                                         arrow [0].X = rect.Left + triangle_width - 1;
7301                                         arrow [0].Y = rect.Y + y_middle;
7302                                         
7303                                         if (arrow [0].X - 1 == rect.X)
7304                                                 arrow [0].X += 1;
7305                                         
7306                                         arrow [1].X = arrow [0].X + triangle_width - 1;
7307                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7308                                         arrow [2].X = arrow [1].X;
7309                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7310                                         
7311                                         dc.DrawPolygon (pen, arrow);
7312                                         
7313                                         if ((state & ButtonState.Inactive) != 0) {
7314                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7315                                         }
7316                                         
7317                                         if (fill_rect) {
7318                                                 for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
7319                                                         dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
7320                                                         arrow [1].Y += 1;
7321                                                         arrow [2].Y -= 1;
7322                                                 }
7323                                         }
7324                                         break;
7325                                         
7326                                 case ScrollButton.Right:
7327                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7328                                         if (y_middle == 1)
7329                                                 y_middle = 2;
7330                                         
7331                                         if (rect.Width < 8) {
7332                                                 triangle_width = 2;
7333                                                 fill_rect = false;
7334                                         } else if (rect.Width == 11) {
7335                                                 triangle_width = 3;
7336                                         } else {
7337                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7338                                         }
7339                                         
7340                                         arrow [0].X = rect.Right - triangle_width - 1;
7341                                         arrow [0].Y = rect.Y + y_middle;
7342                                         
7343                                         if (arrow [0].X - 1 == rect.X)
7344                                                 arrow [0].X += 1;
7345                                         
7346                                         arrow [1].X = arrow [0].X - triangle_width + 1;
7347                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7348                                         arrow [2].X = arrow [1].X;
7349                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7350                                         
7351                                         dc.DrawPolygon (pen, arrow);
7352                                         
7353                                         if ((state & ButtonState.Inactive) != 0) {
7354                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7355                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
7356                                         }
7357                                         
7358                                         if (fill_rect) {
7359                                                 for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
7360                                                         dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
7361                                                         arrow [1].Y += 1;
7362                                                         arrow [2].Y -= 1;
7363                                                 }
7364                                         }
7365                                         break;
7366                         }
7367                 }
7368
7369                 public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
7370                         Color backColor) {
7371
7372                 }
7373
7374
7375                 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds)
7376                 {
7377                         Pen pen_dark = ResPool.GetPen(ControlPaint.Dark(backColor));
7378                         Pen pen_light_light = ResPool.GetPen(ControlPaint.LightLight(backColor));
7379                         
7380                         for (int i = 2; i < bounds.Width - 2; i += 4) {
7381                                 dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1);
7382                                 dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i);
7383                                 dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1);
7384                         }
7385                 }
7386
7387                 private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)
7388                 {
7389                         CPColor cpcolor = ResPool.GetCPColor (color);
7390
7391                         layoutRectangle.Offset (1, 1);
7392                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString);
7393
7394                         layoutRectangle.Offset (-1, -1);
7395                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString);
7396                 }
7397
7398                 public  override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)
7399                 {
7400                         CPColor cpcolor = ResPool.GetCPColor (color);
7401                         
7402                         dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight), 
7403                                        new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height),
7404                                        format);
7405                         dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
7406                 }
7407
7408 #if NET_2_0
7409                 public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
7410                 {
7411                         CPColor cpcolor = ResPool.GetCPColor (color);
7412
7413                         layoutRectangle.Offset (1, 1);
7414                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format);
7415
7416                         layoutRectangle.Offset (-1, -1);
7417                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format);
7418                 }
7419
7420                 public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
7421                 {
7422                         graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds);
7423                 }
7424 #endif
7425
7426                 private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY,
7427                         int width, Color color, ButtonBorderStyle style, Border3DSide side) 
7428                 {
7429                         DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY, 
7430                                 width, color, style, side);
7431                 }
7432
7433                 private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY,
7434                         int width, Color color, ButtonBorderStyle style, Border3DSide side) {
7435
7436                         Pen pen = null;
7437
7438                         switch (style) {
7439                         case ButtonBorderStyle.Solid:
7440                         case ButtonBorderStyle.Inset:
7441                         case ButtonBorderStyle.Outset:
7442                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid);
7443                                         break;
7444                         case ButtonBorderStyle.Dashed:
7445                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash);
7446                                         break;
7447                         case ButtonBorderStyle.Dotted:
7448                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot);
7449                                         break;
7450                         default:
7451                         case ButtonBorderStyle.None:
7452                                         return;
7453                         }
7454
7455                         switch(style) {
7456                         case ButtonBorderStyle.Outset: {
7457                                 Color           colorGrade;
7458                                 int             hue, brightness, saturation;
7459                                 int             brightnessSteps;
7460                                 int             brightnessDownSteps;
7461
7462                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7463
7464                                 brightnessDownSteps=brightness/width;
7465                                 if (brightness>127) {
7466                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7467                                 } else {
7468                                         brightnessSteps=(127-brightness)/width;
7469                                 }
7470
7471                                 for (int i=0; i<width; i++) {
7472                                         switch(side) {
7473                                         case Border3DSide.Left: {
7474                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7475                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7476                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7477                                                 break;
7478                                         }
7479
7480                                         case Border3DSide.Right: {
7481                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7482                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7483                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7484                                                 break;
7485                                         }
7486
7487                                         case Border3DSide.Top: {
7488                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7489                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7490                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7491                                                 break;
7492                                         }
7493
7494                                         case Border3DSide.Bottom: {
7495                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7496                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7497                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7498                                                 break;
7499                                         }
7500                                         }
7501                                 }
7502                                 break;
7503                         }
7504
7505                         case ButtonBorderStyle.Inset: {
7506                                 Color           colorGrade;
7507                                 int             hue, brightness, saturation;
7508                                 int             brightnessSteps;
7509                                 int             brightnessDownSteps;
7510
7511                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7512
7513                                 brightnessDownSteps=brightness/width;
7514                                 if (brightness>127) {
7515                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7516                                 } else {
7517                                         brightnessSteps=(127-brightness)/width;
7518                                 }
7519
7520                                 for (int i=0; i<width; i++) {
7521                                         switch(side) {
7522                                         case Border3DSide.Left: {
7523                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7524                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7525                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7526                                                 break;
7527                                         }
7528
7529                                         case Border3DSide.Right: {
7530                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7531                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7532                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7533                                                 break;
7534                                         }
7535
7536                                         case Border3DSide.Top: {
7537                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7538                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7539                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7540                                                 break;
7541                                         }
7542
7543                                         case Border3DSide.Bottom: {
7544                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7545                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7546                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7547                                                 break;
7548                                         }
7549                                         }
7550                                 }
7551                                 break;
7552                         }
7553
7554                                 /*
7555                                         I decided to have the for-loop duplicated for speed reasons;
7556                                         that way we only have to switch once (as opposed to have the
7557                                         for-loop around the switch)
7558                                 */
7559                         default: {
7560                                 switch(side) {
7561                                 case Border3DSide.Left: {
7562                                         for (int i=0; i<width; i++) {
7563                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7564                                         }
7565                                         break;
7566                                 }
7567
7568                                 case Border3DSide.Right: {
7569                                         for (int i=0; i<width; i++) {
7570                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7571                                         }
7572                                         break;
7573                                 }
7574
7575                                 case Border3DSide.Top: {
7576                                         for (int i=0; i<width; i++) {
7577                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7578                                         }
7579                                         break;
7580                                 }
7581
7582                                 case Border3DSide.Bottom: {
7583                                         for (int i=0; i<width; i++) {
7584                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7585                                         }
7586                                         break;
7587                                 }
7588                                 }
7589                                 break;
7590                         }
7591                         }
7592                 }
7593
7594                 /*
7595                         This function actually draws the various caption elements.
7596                         This way we can scale them nicely, no matter what size, and they
7597                         still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
7598                 */
7599
7600                 private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
7601                         switch(button) {
7602                         case CaptionButton.Close: {
7603                                 if (lineWidth<2) {
7604                                         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);
7605                                         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);
7606                                 }
7607
7608                                 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7609                                 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7610                                 return;
7611                         }
7612
7613                         case CaptionButton.Help: {
7614                                 StringFormat    sf = new StringFormat();                                
7615                                 Font                            font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
7616
7617                                 sf.Alignment=StringAlignment.Center;
7618                                 sf.LineAlignment=StringAlignment.Center;
7619
7620
7621                                 graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
7622
7623                                 sf.Dispose();                           
7624                                 font.Dispose();
7625
7626                                 return;
7627                         }
7628
7629                         case CaptionButton.Maximize: {
7630                                 /* Top 'caption bar' line */
7631                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7632                                         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);
7633                                 }
7634
7635                                 /* Left side line */
7636                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7637                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7638                                 }
7639
7640                                 /* Right side line */
7641                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7642                                         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);
7643                                 }
7644
7645                                 /* Bottom line */
7646                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7647                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7648                                 }
7649                                 return;
7650                         }
7651
7652                         case CaptionButton.Minimize: {
7653                                 /* Bottom line */
7654                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7655                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
7656                                 }
7657                                 return;
7658                         }
7659
7660                         case CaptionButton.Restore: {
7661                                 /** First 'window' **/
7662                                 /* Top 'caption bar' line */
7663                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7664                                         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);
7665                                 }
7666
7667                                 /* Left side line */
7668                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7669                                         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);
7670                                 }
7671
7672                                 /* Right side line */
7673                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7674                                         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);
7675                                 }
7676
7677                                 /* Bottom line */
7678                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7679                                         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);
7680                                 }
7681
7682                                 /** Second 'window' **/
7683                                 /* Top 'caption bar' line */
7684                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7685                                         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);
7686                                 }
7687
7688                                 /* Left side line */
7689                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7690                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7691                                 }
7692
7693                                 /* Right side line */
7694                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7695                                         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);
7696                                 }
7697
7698                                 /* Bottom line */
7699                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7700                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7701                                 }
7702
7703                                 return;
7704                         }
7705
7706                         }
7707                 }
7708
7709                 /* Generic scroll button */
7710                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
7711                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
7712                                 dc.FillRectangle (SystemBrushes.Control, area.X + 1,
7713                                         area.Y + 1, area.Width - 2 , area.Height - 2);
7714
7715                                 dc.DrawRectangle (SystemPens.ControlDark, area.X,
7716                                         area.Y, area.Width, area.Height);
7717
7718                                 return;
7719                         }                       
7720         
7721                         Brush sb_control = SystemBrushes.Control;
7722                         Brush sb_lightlight = SystemBrushes.ControlLightLight;
7723                         Brush sb_dark = SystemBrushes.ControlDark;
7724                         Brush sb_darkdark = SystemBrushes.ControlDarkDark;
7725                         
7726                         dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1);
7727                         dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height);
7728
7729                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1);
7730                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1,
7731                                 area.Height - 4);
7732                         
7733                         dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2,
7734                                 area.Width - 2, 1);
7735
7736                         dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1,
7737                                 area.Width , 1);
7738
7739                         dc.FillRectangle (sb_dark, area.X + area.Width - 2,
7740                                 area.Y + 1, 1, area.Height -3);
7741
7742                         dc.FillRectangle (sb_darkdark, area.X + area.Width -1,
7743                                 area.Y, 1, area.Height - 1);
7744
7745                         dc.FillRectangle (sb_control, area.X + 2,
7746                                 area.Y + 2, area.Width - 4, area.Height - 4);
7747                         
7748                 }
7749                 
7750                 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
7751                         switch (border_style){
7752                         case BorderStyle.Fixed3D:
7753                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
7754                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
7755                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width , 
7756                                         area.Y + area.Height - 1);
7757                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, 
7758                                         area.Y + area.Height);
7759
7760                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
7761                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
7762                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
7763                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
7764                                 break;
7765                         case BorderStyle.FixedSingle:
7766                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
7767                                 break;
7768                         case BorderStyle.None:
7769                         default:
7770                                 break;
7771                         }
7772                         
7773                 }
7774                 #endregion      // ControlPaint
7775
7776
7777         } //class
7778 }