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