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