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