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