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