2008-06-10 George Giolfan <georgegiolfan@yahoo.com>
[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 modified_area = clip;
1667                         modified_area.Intersect (grid.caption_area);
1668
1669                         g.FillRectangle (ResPool.GetSolidBrush (grid.CaptionBackColor),
1670                                          modified_area);
1671
1672                         Rectangle text_rect = grid.caption_area;
1673                         text_rect.Y += text_rect.Height / 2 - grid.CaptionFont.Height / 2;
1674                         text_rect.Height = grid.CaptionFont.Height;
1675                         
1676                         g.DrawString (grid.CaptionText, grid.CaptionFont,
1677                                       ResPool.GetSolidBrush (grid.CaptionForeColor),
1678                                       text_rect);
1679
1680                         if (modified_area.IntersectsWith (grid.back_button_rect)) {
1681                                 g.DrawImage (grid.back_button_image, grid.back_button_rect);
1682                                 if (grid.back_button_mouseover) {
1683                                         CPDrawBorder3D (g, grid.back_button_rect, grid.back_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1684                                 }
1685                         }
1686                         if (modified_area.IntersectsWith (grid.parent_rows_button_rect)) {
1687                                 g.DrawImage (grid.parent_rows_button_image, grid.parent_rows_button_rect);
1688                                 if (grid.parent_rows_button_mouseover) {
1689                                         CPDrawBorder3D (g, grid.parent_rows_button_rect, grid.parent_rows_button_active ? Border3DStyle.Sunken : Border3DStyle.Raised, all_sides);
1690                                 }
1691                         }
1692                 }
1693
1694                 public override void DataGridPaintColumnHeaders (Graphics g, Rectangle clip, DataGrid grid)
1695                 {
1696                         Rectangle columns_area = grid.column_headers_area;
1697
1698                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) { // Paint corner shared between row and column header
1699                                 Rectangle rect_bloc = grid.column_headers_area;
1700                                 rect_bloc.Width = grid.RowHeaderWidth;
1701                                 if (clip.IntersectsWith (rect_bloc)) {
1702                                         if (grid.VisibleColumnCount > 0)
1703                                                 g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor), rect_bloc);
1704                                         else
1705                                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), rect_bloc);
1706                                 }
1707
1708                                 columns_area.X += grid.RowHeaderWidth;
1709                                 columns_area.Width -= grid.RowHeaderWidth;
1710                         }
1711
1712                         // Set unused area
1713                         Rectangle column_headers_area_complete = columns_area;
1714                         column_headers_area_complete.Width = grid.column_headers_max_width;
1715                         
1716                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
1717                                 column_headers_area_complete.Width -= grid.RowHeaderWidth;
1718                         }               
1719
1720                         // Set column painting
1721                         Rectangle rect_columnhdr = new Rectangle ();
1722                         int col_pixel;
1723                         Region current_clip;
1724                         Region prev_clip = g.Clip;
1725                         rect_columnhdr.Y = columns_area.Y;
1726                         rect_columnhdr.Height = columns_area.Height;
1727
1728                         int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
1729                         for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
1730                                 if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
1731                                         continue;
1732                                 
1733                                 col_pixel = grid.GetColumnStartingPixel (column);
1734                                 rect_columnhdr.X = columns_area.X + col_pixel - grid.HorizPixelOffset;
1735                                 rect_columnhdr.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
1736
1737                                 if (clip.IntersectsWith (rect_columnhdr) == false)
1738                                         continue;
1739
1740                                 current_clip = new Region (rect_columnhdr);
1741                                 current_clip.Intersect (columns_area);
1742                                 current_clip.Intersect (prev_clip);
1743                                 g.Clip = current_clip;
1744
1745                                 grid.CurrentTableStyle.GridColumnStyles[column].PaintHeader (g, rect_columnhdr, column);
1746
1747                                 current_clip.Dispose ();
1748                         }
1749
1750                         g.Clip = prev_clip;
1751                                 
1752                         Rectangle not_usedarea = column_headers_area_complete;                          
1753                         not_usedarea.X = rect_columnhdr.X + rect_columnhdr.Width;
1754                         not_usedarea.Width = grid.ClientRectangle.X + grid.ClientRectangle.Width - rect_columnhdr.X - rect_columnhdr.Height;            
1755                         g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
1756                         
1757                 }
1758
1759                 public override void DataGridPaintParentRows (Graphics g, Rectangle clip, DataGrid grid)
1760                 {
1761                         Rectangle rect_row = new Rectangle ();
1762
1763                         rect_row.X = grid.ParentRowsArea.X;
1764                         rect_row.Width = grid.ParentRowsArea.Width;
1765                         rect_row.Height = (grid.CaptionFont.Height + 3);
1766
1767                         object[] parentRows = grid.data_source_stack.ToArray();
1768                         
1769                         Region current_clip;
1770                         Region prev_clip = g.Clip;
1771                         for (int row = 0; row < parentRows.Length; row++) {
1772                                 rect_row.Y = grid.ParentRowsArea.Y + row * rect_row.Height;
1773
1774                                 if (clip.IntersectsWith (rect_row) == false)
1775                                         continue;
1776
1777                                 current_clip = new Region (rect_row);
1778                                 current_clip.Intersect (prev_clip);
1779                                 g.Clip = current_clip;
1780
1781                                 DataGridPaintParentRow (g, rect_row, (DataGridDataSource)parentRows[parentRows.Length - row - 1], grid);
1782
1783                                 current_clip.Dispose ();
1784                         }
1785                         
1786                         g.Clip = prev_clip;
1787                 }
1788
1789                 public override void DataGridPaintParentRow (Graphics g, Rectangle bounds, DataGridDataSource row, DataGrid grid)
1790                 {
1791                         //Console.WriteLine ("drawing parent row {0}", row);
1792
1793                         // Background
1794                         g.FillRectangle (ResPool.GetSolidBrush (grid.ParentRowsBackColor),
1795                                          bounds);
1796
1797                         Font bold_font = new Font (grid.Font.FontFamily, grid.Font.Size, grid.Font.Style | FontStyle.Bold);
1798                         // set up some standard string formating variables
1799                         StringFormat text_format = new StringFormat();
1800                         text_format.LineAlignment = StringAlignment.Center;
1801                         text_format.Alignment = StringAlignment.Near;
1802
1803                         string table_name = "";
1804                         if (row.view is DataRowView)
1805                                 table_name = ((ITypedList)((DataRowView)row.view).DataView).GetListName (null) + ": ";
1806                         // XXX else?
1807
1808                         Rectangle       text_rect;
1809                         Size            text_size;
1810
1811                         text_size = g.MeasureString (table_name, bold_font).ToSize();
1812                         text_rect = new Rectangle(new Point(bounds.X + 3, bounds.Y + bounds.Height - text_size.Height), text_size);
1813
1814                         //Console.WriteLine ("drawing text at {0}", text_rect);
1815
1816                         g.DrawString (table_name,
1817                                       bold_font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1818
1819                         foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)row.view).GetProperties()) {
1820                                 if (typeof(IBindingList).IsAssignableFrom (pd.PropertyType))
1821                                         continue;
1822
1823                                 text_rect.X += text_rect.Size.Width + 5;
1824
1825                                 string text = String.Format ("{0}: {1}",
1826                                                              pd.Name,
1827                                                              pd.GetValue (row.view));
1828
1829                                 text_rect.Size = g.MeasureString (text, grid.Font).ToSize();
1830                                 text_rect.Y = bounds.Y + bounds.Height - text_rect.Height; // XXX
1831
1832                                 //Console.WriteLine ("drawing text at {0}", text_rect);
1833
1834                                 g.DrawString (text,
1835                                               grid.Font, ResPool.GetSolidBrush (grid.ParentRowsForeColor), text_rect, text_format);
1836                         }
1837
1838                         if (grid.FlatMode == false) {
1839                                 
1840                                 // Paint Borders
1841                                 g.DrawLine (ResPool.GetPen (ColorControlLight),
1842                                         bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
1843         
1844                                 g.DrawLine (ResPool.GetPen (ColorControlLight),
1845                                         bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
1846         
1847                                 g.DrawLine (ResPool.GetPen (ColorControlDark),
1848                                         bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
1849         
1850                                 g.DrawLine (ResPool.GetPen (ColorControlDark),
1851                                         bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
1852                         }
1853                 }
1854
1855                 public override void DataGridPaintRowHeaderArrow (Graphics g, Rectangle bounds, DataGrid grid) 
1856                 {               
1857                         Point[] arrow = new Point[3];
1858                         Point P1, P2, P3;
1859                         int centerX, centerY, shiftX;                   
1860                         Rectangle rect;
1861                         
1862                         rect = new Rectangle (bounds.X + bounds.Width /4, 
1863                                 bounds.Y + bounds.Height/4, bounds.Width / 2, bounds.Height / 2);
1864                         
1865                         centerX = rect.Left + rect.Width / 2;
1866                         centerY = rect.Top + rect.Height / 2;
1867                         shiftX = Math.Max (1, rect.Width / 8);                  
1868                         rect.X -= shiftX;
1869                         centerX -= shiftX;                      
1870                         P1 = new Point (centerX, rect.Top - 1);
1871                         P2 = new Point (centerX, rect.Bottom);
1872                         P3 = new Point (rect.Right, centerY);                   
1873                         arrow[0] = P1;
1874                         arrow[1] = P2;
1875                         arrow[2] = P3;
1876                         
1877                         g.FillPolygon (ResPool.GetSolidBrush 
1878                                 (grid.CurrentTableStyle.CurrentHeaderForeColor), arrow, FillMode.Winding);
1879                 }
1880
1881                 public override void DataGridPaintRowHeader (Graphics g, Rectangle bounds, int row, DataGrid grid)
1882                 {
1883                         bool is_add_row = grid.ShowEditRow && row == grid.DataGridRows.Length - 1;
1884                         bool is_current_row = row == grid.CurrentCell.RowNumber;
1885
1886                         // Background
1887                         g.FillRectangle (ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderBackColor),
1888                                          bounds);
1889
1890                         // Draw arrow
1891                         if (is_current_row) {
1892                                 if (grid.IsChanging) {
1893                                         g.DrawString ("...", grid.Font,
1894                                                       ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
1895                                                       bounds);
1896                                 } else {
1897                                         Rectangle rect = new Rectangle (bounds.X - 2, bounds.Y, 18, 18);
1898                                         DataGridPaintRowHeaderArrow (g, rect, grid);
1899                                 }
1900                         }
1901                         else if (is_add_row) {
1902                                 g.DrawString ("*", grid.Font, ResPool.GetSolidBrush (grid.CurrentTableStyle.CurrentHeaderForeColor),
1903                                               bounds);
1904                         }
1905
1906                         if (grid.FlatMode == false && !is_add_row) {
1907                                 // Paint Borders
1908                                 g.DrawLine (ResPool.GetPen (ColorControlLight),
1909                                             bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);
1910
1911                                 g.DrawLine (ResPool.GetPen (ColorControlLight),
1912                                             bounds.X, bounds.Y + 1, bounds.X, bounds.Y + bounds.Height - 1);
1913
1914                                 g.DrawLine (ResPool.GetPen (ColorControlDark),
1915                                             bounds.X + bounds.Width - 1, bounds.Y + 1 , bounds.X + bounds.Width - 1, bounds.Y + bounds.Height - 1);
1916
1917                                 g.DrawLine (ResPool.GetPen (ColorControlDark),
1918                                             bounds.X, bounds.Y + bounds.Height -1, bounds.X + bounds.Width, bounds.Y  + bounds.Height -1);
1919                         }
1920                 }
1921                 
1922                 public override void DataGridPaintRows (Graphics g, Rectangle cells, Rectangle clip, DataGrid grid)
1923                 {
1924                         Rectangle rect_row = new Rectangle ();
1925                         Rectangle not_usedarea = new Rectangle ();
1926
1927                         int rowcnt = grid.VisibleRowCount;
1928                         
1929                         bool showing_add_row = false;
1930
1931                         if (grid.RowsCount < grid.DataGridRows.Length) {
1932                                 /* the table has an add row */
1933
1934                                 if (grid.FirstVisibleRow + grid.VisibleRowCount >= grid.DataGridRows.Length) {
1935                                         showing_add_row = true;
1936                                 }
1937                         }
1938
1939                         rect_row.Width = cells.Width + grid.RowHeadersArea.Width;
1940                         for (int r = 0; r < rowcnt; r++) {
1941                                 int row = grid.FirstVisibleRow + r;
1942                                 if (row == grid.DataGridRows.Length - 1)
1943                                         rect_row.Height = grid.DataGridRows[row].Height;
1944                                 else
1945                                         rect_row.Height = grid.DataGridRows[row + 1].VerticalOffset - grid.DataGridRows[row].VerticalOffset;
1946                                 rect_row.Y = cells.Y + grid.DataGridRows[row].VerticalOffset - grid.DataGridRows[grid.FirstVisibleRow].VerticalOffset;
1947                                 if (clip.IntersectsWith (rect_row)) {
1948                                         if (grid.CurrentTableStyle.HasRelations
1949                                             && !(showing_add_row && row == grid.DataGridRows.Length - 1))
1950                                                 DataGridPaintRelationRow (g, row, rect_row, false, clip, grid);
1951                                         else
1952                                                 DataGridPaintRow (g, row, rect_row, showing_add_row && row == grid.DataGridRows.Length - 1, clip, grid);
1953                                 }
1954                         }
1955
1956                         not_usedarea.X = 0;
1957                         // the rowcnt == 0 check is needed because
1958                         // otherwise we'd draw over the caption on
1959                         // empty datasources (since rect_row would be
1960                         // Empty)
1961                         if (rowcnt == 0)
1962                                 not_usedarea.Y = cells.Y;
1963                         else
1964                                 not_usedarea.Y = rect_row.Y + rect_row.Height;
1965                         not_usedarea.Height = cells.Y + cells.Height - rect_row.Y - rect_row.Height;
1966                         not_usedarea.Width = cells.Width + grid.RowHeadersArea.Width;
1967
1968                         g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor), not_usedarea);
1969                 }
1970
1971                 public override void DataGridPaintRelationRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
1972                                                                Rectangle clip, DataGrid grid)
1973                 {
1974                         Rectangle rect_header;
1975                         Rectangle icon_bounds = new Rectangle ();
1976                         Pen pen = ThemeEngine.Current.ResPool.GetPen (grid.CurrentTableStyle.ForeColor);
1977
1978                         /* paint the header if it's visible and intersects the clip */
1979                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
1980                                 rect_header = row_rect;
1981                                 rect_header.Width = grid.RowHeaderWidth;
1982                                 row_rect.X += grid.RowHeaderWidth;
1983                                 if (clip.IntersectsWith (rect_header)) {
1984                                         DataGridPaintRowHeader (g, rect_header, row, grid);
1985                                 }
1986
1987                                 icon_bounds = rect_header;
1988                                 icon_bounds.X += icon_bounds.Width / 2;
1989                                 icon_bounds.Y += 3;
1990                                 icon_bounds.Width = 8;
1991                                 icon_bounds.Height = 8;
1992
1993                                 g.DrawRectangle (pen, icon_bounds);
1994
1995                                 /* the - part of the icon */
1996                                 g.DrawLine (pen,
1997                                             icon_bounds.X + 2, icon_bounds.Y + icon_bounds.Height / 2,
1998                                             icon_bounds.X + icon_bounds.Width - 2, icon_bounds.Y + icon_bounds.Height / 2);
1999                                             
2000                                 if (!grid.IsExpanded (row)) {
2001                                         /* the | part of the icon */
2002                                         g.DrawLine (pen,
2003                                                     icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + 2,
2004                                                     icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height - 2);
2005                                 }
2006                         }
2007
2008                         Rectangle nested_rect = row_rect;
2009
2010                         if (grid.DataGridRows[row].IsExpanded)
2011                                 nested_rect.Height -= grid.DataGridRows[row].RelationHeight;
2012
2013                         DataGridPaintRowContents (g, row, nested_rect, is_newrow, clip, grid);
2014
2015                         if (grid.DataGridRows[row].IsExpanded) {
2016                                 // XXX we should create this in the
2017                                 // datagrid and cache it for use by
2018                                 // the theme instead of doing it each
2019                                 // time through here
2020                                 string[] relations = grid.CurrentTableStyle.Relations;
2021                                 StringBuilder relation_builder = new StringBuilder ("");
2022
2023                                 for (int i = 0; i < relations.Length; i ++) {
2024                                         if (i > 0)
2025                                                 relation_builder.Append ("\n");
2026
2027                                         relation_builder.Append (relations[i]);
2028                                 }
2029                                 string relation_text = relation_builder.ToString ();
2030
2031                                 StringFormat string_format = new StringFormat ();
2032                                 string_format.FormatFlags |= StringFormatFlags.NoWrap;
2033
2034
2035                                 //Region prev_clip = g.Clip;
2036                                 //Region current_clip;
2037                                 Rectangle rect_cell = row_rect;
2038
2039                                 rect_cell.X = nested_rect.X + grid.GetColumnStartingPixel (grid.FirstVisibleColumn) - grid.HorizPixelOffset;
2040                                 rect_cell.Y += nested_rect.Height;
2041                                 rect_cell.Height = grid.DataGridRows[row].RelationHeight;
2042
2043                                 rect_cell.Width = 0;
2044                                 int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2045                                 for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2046                                         if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2047                                                 continue;
2048                                         rect_cell.Width += grid.CurrentTableStyle.GridColumnStyles[column].Width;
2049                                 }
2050                                 rect_cell.Width = Math.Max (rect_cell.Width, grid.DataGridRows[row].relation_area.Width);
2051
2052                                 g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (grid.CurrentTableStyle.BackColor),
2053                                                  rect_cell);
2054
2055
2056                                 /* draw the line leading from the +/- to the relation area */
2057                                 Rectangle outline = grid.DataGridRows[row].relation_area;
2058                                 outline.Y = rect_cell.Y;
2059                                 outline.Height --;
2060
2061                                 g.DrawLine (pen,
2062                                             icon_bounds.X + icon_bounds.Width / 2, icon_bounds.Y + icon_bounds.Height,
2063                                             icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2);
2064
2065                                 g.DrawLine (pen,
2066                                             icon_bounds.X + icon_bounds.Width / 2, outline.Y + outline.Height / 2,
2067                                             outline.X, outline.Y + outline.Height / 2);
2068
2069                                 g.DrawRectangle (pen, outline);
2070
2071                                 g.DrawString (relation_text, grid.LinkFont, ResPool.GetSolidBrush (grid.LinkColor),
2072                                               outline, string_format);
2073
2074                                 if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2075                                         Rectangle not_usedarea = new Rectangle ();
2076                                         not_usedarea.X = rect_cell.X + rect_cell.Width;
2077                                         not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2078                                         not_usedarea.Y = row_rect.Y;
2079                                         not_usedarea.Height = row_rect.Height;
2080                                         if (clip.IntersectsWith (not_usedarea))
2081                                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2082                                                                  not_usedarea);
2083                                 }
2084                         }
2085                 }
2086
2087                 public override void DataGridPaintRowContents (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2088                                                                Rectangle clip, DataGrid grid)
2089                 {
2090                         Rectangle rect_cell = new Rectangle ();
2091                         int col_pixel;
2092                         Color backcolor, forecolor;
2093                         Brush backBrush, foreBrush;
2094                         Rectangle not_usedarea = Rectangle.Empty;
2095
2096                         rect_cell.Y = row_rect.Y;
2097                         rect_cell.Height = row_rect.Height;
2098
2099                         if (grid.IsSelected (row)) {
2100                                 backcolor =  grid.SelectionBackColor;
2101                                 forecolor =  grid.SelectionForeColor;
2102                         } else {
2103                                 if (row % 2 == 0) {
2104                                         backcolor =  grid.BackColor;
2105                                 } else {
2106                                         backcolor =  grid.AlternatingBackColor;
2107                                 }
2108
2109                                 forecolor =  grid.ForeColor;
2110                         }                       
2111
2112
2113                         backBrush = ResPool.GetSolidBrush (backcolor);
2114                         foreBrush = ResPool.GetSolidBrush (forecolor);
2115
2116                         // PaintCells at row, column
2117                         int column_cnt = grid.FirstVisibleColumn + grid.VisibleColumnCount;
2118
2119                         if (column_cnt > 0) {
2120                                 Region prev_clip = g.Clip;
2121                                 Region current_clip;
2122
2123                                 for (int column = grid.FirstVisibleColumn; column < column_cnt; column++) {
2124                                         if (grid.CurrentTableStyle.GridColumnStyles[column].bound == false)
2125                                                 continue;
2126
2127                                         col_pixel = grid.GetColumnStartingPixel (column);
2128
2129                                         rect_cell.X = row_rect.X + col_pixel - grid.HorizPixelOffset;
2130                                         rect_cell.Width = grid.CurrentTableStyle.GridColumnStyles[column].Width;
2131
2132                                         if (clip.IntersectsWith (rect_cell)) {
2133                                                 current_clip = new Region (rect_cell);
2134                                                 current_clip.Intersect (row_rect);
2135                                                 current_clip.Intersect (prev_clip);
2136                                                 g.Clip = current_clip;
2137
2138                                                 if (is_newrow) {
2139                                                         grid.CurrentTableStyle.GridColumnStyles[column].PaintNewRow (g, rect_cell, 
2140                                                                                                                      backBrush,
2141                                                                                                                      foreBrush);
2142                                                 } else {
2143                                                         grid.CurrentTableStyle.GridColumnStyles[column].Paint (g, rect_cell, grid.ListManager, row,
2144                                                                                                                backBrush,
2145                                                                                                                foreBrush,
2146                                                                                                                grid.RightToLeft == RightToLeft.Yes);
2147                                                 }
2148
2149                                                 current_clip.Dispose ();
2150                                         }
2151                                 }
2152
2153                                 g.Clip = prev_clip;
2154                         
2155                                 if (row_rect.X + row_rect.Width > rect_cell.X + rect_cell.Width) {
2156                                         not_usedarea.X = rect_cell.X + rect_cell.Width;
2157                                         not_usedarea.Width = row_rect.X + row_rect.Width - rect_cell.X - rect_cell.Width;
2158                                         not_usedarea.Y = row_rect.Y;
2159                                         not_usedarea.Height = row_rect.Height;
2160                                 }
2161                         }
2162                         else {
2163                                 not_usedarea = row_rect;
2164                         }
2165
2166                         if (!not_usedarea.IsEmpty && clip.IntersectsWith (not_usedarea))
2167                                 g.FillRectangle (ResPool.GetSolidBrush (grid.BackgroundColor),
2168                                                  not_usedarea);
2169                 }
2170
2171                 public override void DataGridPaintRow (Graphics g, int row, Rectangle row_rect, bool is_newrow,
2172                                                        Rectangle clip, DataGrid grid)
2173                 {                       
2174                         /* paint the header if it's visible and intersects the clip */
2175                         if (grid.CurrentTableStyle.CurrentRowHeadersVisible) {
2176                                 Rectangle rect_header = row_rect;
2177                                 rect_header.Width = grid.RowHeaderWidth;
2178                                 row_rect.X += grid.RowHeaderWidth;
2179                                 if (clip.IntersectsWith (rect_header)) {
2180                                         DataGridPaintRowHeader (g, rect_header, row, grid);
2181                                 }
2182                         }
2183
2184                         DataGridPaintRowContents (g, row, row_rect, is_newrow, clip, grid);
2185                 }
2186                 
2187                 #endregion // Datagrid
2188
2189 #if NET_2_0
2190                 #region DataGridView
2191                 #region DataGridViewHeaderCell
2192                 #region DataGridViewRowHeaderCell
2193                 public override bool DataGridViewRowHeaderCellDrawBackground (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2194                 {
2195                         return false;
2196                 }
2197
2198                 public override bool DataGridViewRowHeaderCellDrawSelectionBackground (DataGridViewRowHeaderCell cell)
2199                 {
2200                         return false;
2201                 }
2202
2203                 public override bool DataGridViewRowHeaderCellDrawBorder (DataGridViewRowHeaderCell cell, Graphics g, Rectangle bounds)
2204                 {
2205                         return false;
2206                 }
2207                 #endregion
2208
2209                 #region DataGridViewColumnHeaderCell
2210                 public override bool DataGridViewColumnHeaderCellDrawBackground (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2211                 {
2212                         return false;
2213                 }
2214
2215                 public override bool DataGridViewColumnHeaderCellDrawBorder (DataGridViewColumnHeaderCell cell, Graphics g, Rectangle bounds)
2216                 {
2217                         return false;
2218                 }
2219                 #endregion
2220
2221                 public override bool DataGridViewHeaderCellHasPressedStyle  (DataGridView dataGridView)
2222                 {
2223                         return false;
2224                 }
2225
2226                 public override bool DataGridViewHeaderCellHasHotStyle (DataGridView dataGridView)
2227                 {
2228                         return false;
2229                 }
2230                 #endregion
2231                 #endregion
2232 #endif
2233
2234                 #region DateTimePicker
2235
2236                 public override void DrawDateTimePicker(Graphics dc, Rectangle clip_rectangle, DateTimePicker dtp)
2237                 {
2238
2239                         if (!clip_rectangle.IntersectsWith (dtp.ClientRectangle))
2240                                 return;
2241
2242                         // draw the outer border
2243                         Rectangle button_bounds = dtp.ClientRectangle;
2244                         this.CPDrawBorder3D (dc, button_bounds, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, dtp.BackColor);
2245
2246                         // deflate by the border width
2247                         if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) {
2248                                 button_bounds.Inflate (-2,-2);
2249                                 if (!dtp.ShowUpDown) {
2250                                         ButtonState state = dtp.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal;
2251                                         dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), dtp.drop_down_arrow_rect);
2252                                         this.CPDrawComboButton ( 
2253                                           dc, 
2254                                           dtp.drop_down_arrow_rect, 
2255                                           state);
2256                                 } else {
2257                                         ButtonState up_state = dtp.is_up_pressed ? ButtonState.Pushed : ButtonState.Normal;
2258                                         ButtonState down_state = dtp.is_down_pressed ? ButtonState.Pushed : ButtonState.Normal;
2259                                         Rectangle up_bounds = dtp.drop_down_arrow_rect;
2260                                         Rectangle down_bounds = dtp.drop_down_arrow_rect;
2261
2262                                         up_bounds.Height = up_bounds.Height / 2;
2263                                         down_bounds.Y = up_bounds.Height;
2264                                         down_bounds.Height = dtp.Height - up_bounds.Height;
2265                                         if (down_bounds.Height > up_bounds.Height)
2266                                         {
2267                                                 down_bounds.Y += 1;
2268                                                 down_bounds.Height -= 1;
2269                                         }
2270
2271                                         up_bounds.Inflate (-1, -1);
2272                                         down_bounds.Inflate (-1, -1);
2273
2274                                         ControlPaint.DrawScrollButton (dc, up_bounds, ScrollButton.Up, up_state);
2275                                         ControlPaint.DrawScrollButton (dc, down_bounds, ScrollButton.Down, down_state);
2276                                 }
2277                         }
2278
2279                         // render the date part
2280                         if (!clip_rectangle.IntersectsWith (dtp.date_area_rect))
2281                                 return;
2282
2283                         // fill the background
2284                         dc.FillRectangle (SystemBrushes.Window, dtp.date_area_rect);
2285
2286                         // Update date_area_rect if we are drawing the checkbox
2287                         Rectangle date_area_rect = dtp.date_area_rect;
2288                         if (dtp.ShowCheckBox) {
2289                                 Rectangle check_box_rect = dtp.CheckBoxRect;
2290                                 date_area_rect.X = date_area_rect.X + check_box_rect.Width + DateTimePicker.check_box_space * 2;
2291                                 date_area_rect.Width = date_area_rect.Width - check_box_rect.Width - DateTimePicker.check_box_space * 2;
2292
2293                                 ButtonState bs = dtp.Checked ? ButtonState.Checked : ButtonState.Normal;
2294                                 CPDrawCheckBox(dc, check_box_rect, bs);
2295
2296                                 if (dtp.is_checkbox_selected)
2297                                         CPDrawFocusRectangle (dc, check_box_rect, dtp.foreground_color, dtp.background_color);
2298                         }
2299
2300                         // render each text part
2301                         using (StringFormat text_format = StringFormat.GenericTypographic)
2302                         {
2303                                 text_format.LineAlignment = StringAlignment.Near;
2304                                 text_format.Alignment = StringAlignment.Near;
2305                                 text_format.FormatFlags = text_format.FormatFlags | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox;
2306                                 text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2307
2308                                 // Calculate the rectangles for each part 
2309                                 if (dtp.part_data.Length > 0 && dtp.part_data[0].drawing_rectangle.IsEmpty)
2310                                 {
2311                                         Graphics gr = dc;
2312                                         for (int i = 0; i < dtp.part_data.Length; i++)
2313                                         {
2314                                                 DateTimePicker.PartData fd = dtp.part_data[i];
2315                                                 RectangleF text_rect = new RectangleF();
2316                                                 string text = fd.GetText(dtp.Value);
2317                                                 text_rect.Size = gr.MeasureString (text, dtp.Font, 250, text_format);
2318                                                 if (!fd.is_literal)
2319                                                         text_rect.Width = Math.Max (dtp.CalculateMaxWidth(fd.value, gr, text_format), text_rect.Width);
2320
2321                                                 if (i > 0) {
2322                                                         text_rect.X = dtp.part_data[i - 1].drawing_rectangle.Right;
2323                                                 } else {
2324                                                         text_rect.X = date_area_rect.X;
2325                                                 }
2326                                                 text_rect.Y = 2;
2327                                                 text_rect.Inflate (1, 0);
2328                                                 fd.drawing_rectangle = text_rect;
2329                                         }
2330                                 }
2331                                 
2332                                 // draw the text part
2333                                 Brush text_brush = ResPool.GetSolidBrush (dtp.ShowCheckBox && dtp.Checked == false ?
2334                                                 SystemColors.GrayText : dtp.ForeColor); // Use GrayText if Checked is false
2335                                 RectangleF clip_rectangleF = clip_rectangle;
2336
2337                                 for (int i = 0; i < dtp.part_data.Length; i++)
2338                                 {
2339                                         DateTimePicker.PartData fd = dtp.part_data [i];
2340                                         string text;
2341
2342                                         if (!clip_rectangleF.IntersectsWith (fd.drawing_rectangle))
2343                                                 continue;
2344
2345                                         text = fd.GetText (dtp.Value);
2346
2347                                         PointF text_position = new PointF ();
2348                                         SizeF text_size;
2349                                         RectangleF text_rect;
2350
2351                                         text_size = dc.MeasureString (text, dtp.Font, 250, text_format);
2352                                         text_position.X = (fd.drawing_rectangle.Left + fd.drawing_rectangle.Width / 2) - text_size.Width / 2;
2353                                         text_position.Y = (fd.drawing_rectangle.Top + fd.drawing_rectangle.Height / 2) - text_size.Height / 2;
2354                                         text_rect = new RectangleF (text_position, text_size);
2355                                         text_rect = RectangleF.Intersect (text_rect, date_area_rect);
2356                                         
2357                                         if (text_rect.IsEmpty)
2358                                                 break;
2359
2360                                         if (text_rect.Right >= date_area_rect.Right)
2361                                                 text_format.FormatFlags &= ~StringFormatFlags.NoClip;
2362                                         else
2363                                                 text_format.FormatFlags |= StringFormatFlags.NoClip;
2364                                         
2365                                         if (fd.is_selected) {
2366                                                 dc.FillRectangle (SystemBrushes.Highlight, text_rect);
2367                                                 dc.DrawString (text, dtp.Font, SystemBrushes.HighlightText, text_rect, text_format);
2368                                         
2369                                         } else {
2370                                                 dc.DrawString (text, dtp.Font, text_brush, text_rect, text_format);
2371                                         }
2372
2373                                         if (fd.drawing_rectangle.Right > date_area_rect.Right)
2374                                                 break; // the next part would be not be visible, so don't draw anything more.
2375                                 }
2376                         }
2377                 }
2378                 
2379                 #endregion // DateTimePicker
2380
2381                 #region GroupBox
2382                 public override void DrawGroupBox (Graphics dc,  Rectangle area, GroupBox box) {
2383                         StringFormat    text_format;
2384                         SizeF           size;
2385                         int             width;
2386                         int             y;
2387
2388                         dc.FillRectangle (GetControlBackBrush (box.BackColor), box.ClientRectangle);
2389                         
2390                         text_format = new StringFormat();
2391                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
2392
2393                         size = dc.MeasureString (box.Text, box.Font);
2394                         width = 0;
2395
2396                         if (size.Width > 0) {
2397                                 width = ((int) size.Width) + 7;
2398                         
2399                                 if (width > box.Width - 16)
2400                                         width = box.Width - 16;
2401                         }
2402                         
2403                         y = box.Font.Height / 2;
2404
2405                         // Clip the are that the text will be in
2406                         Region prev_clip = dc.Clip;
2407                         dc.SetClip (new Rectangle (10, 0, width, box.Font.Height), CombineMode.Exclude);
2408                         /* Draw group box*/
2409                         CPDrawBorder3D (dc, new Rectangle (0, y, box.Width, box.Height - y), Border3DStyle.Etched, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, box.BackColor);
2410                         dc.Clip = prev_clip;
2411
2412                         /* Text */
2413                         if (box.Text.Length != 0) {
2414                                 if (box.Enabled) {
2415                                         dc.DrawString (box.Text, box.Font, ResPool.GetSolidBrush (box.ForeColor), 10, 0, text_format);
2416                                 } else {
2417                                         CPDrawStringDisabled (dc, box.Text, box.Font, box.BackColor, 
2418                                                               new RectangleF (10, 0, width,  box.Font.Height), text_format);
2419                                 }
2420                         }
2421                         
2422                         text_format.Dispose (); 
2423                 }
2424
2425                 public override Size GroupBoxDefaultSize {
2426                         get {
2427                                 return new Size (200,100);
2428                         }
2429                 }
2430                 #endregion
2431
2432                 #region HScrollBar
2433                 public override Size HScrollBarDefaultSize {
2434                         get {
2435                                 return new Size (80, this.ScrollBarButtonSize);
2436                         }
2437                 }
2438
2439                 #endregion      // HScrollBar
2440
2441                 #region ListBox
2442
2443                 public override void DrawListBoxItem (ListBox ctrl, DrawItemEventArgs e)
2444                 {
2445                         Color back_color, fore_color;
2446                         
2447                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
2448                                 back_color = ColorHighlight;
2449                                 fore_color = ColorHighlightText;
2450                         } else {
2451                                 back_color = e.BackColor;
2452                                 fore_color = e.ForeColor;
2453                         }
2454
2455                         e.Graphics.FillRectangle (ResPool.GetSolidBrush (back_color), e.Bounds);
2456
2457                         e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
2458                                                ResPool.GetSolidBrush (fore_color),
2459                                                e.Bounds, ctrl.StringFormat);
2460                                         
2461                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
2462                                 CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
2463                 }
2464                 
2465                 #endregion ListBox
2466
2467                 #region ListView
2468                 // Drawing
2469                 public override void DrawListViewItems (Graphics dc, Rectangle clip, ListView control)
2470                 {
2471                         bool details = control.View == View.Details;
2472                         int first = control.FirstVisibleIndex;  
2473                         int lastvisibleindex = control.LastVisibleIndex;
2474
2475 #if NET_2_0
2476                         if (control.VirtualMode)
2477                                 control.OnCacheVirtualItems (new CacheVirtualItemsEventArgs (first, lastvisibleindex));
2478 #endif
2479
2480                         for (int i = first; i <= lastvisibleindex; i++) {                                       
2481                                 ListViewItem item = control.GetItemAtDisplayIndex (i);
2482                                 if (clip.IntersectsWith (item.Bounds)) {
2483 #if NET_2_0
2484                                         bool owner_draw = false;
2485                                         if (control.OwnerDraw)
2486                                                 owner_draw = DrawListViewItemOwnerDraw (dc, item, i);
2487                                         if (!owner_draw)
2488 #endif
2489                                                 DrawListViewItem (dc, control, item);
2490                                 }
2491                         }       
2492
2493 #if NET_2_0
2494                         if (control.ShowGroups && control.View != View.List && control.Groups.Count > 0) {
2495                                 // Use InternalCount instead of Count to take into account Default Group as needed
2496                                 for (int i = 0; i < control.Groups.InternalCount; i++) {
2497                                         ListViewGroup group = control.Groups.GetInternalGroup (i);
2498                                         if (group.ItemCount > 0 && clip.IntersectsWith (group.HeaderBounds))
2499                                                 DrawListViewGroupHeader (dc, control, group);
2500                                 }
2501                         }
2502
2503                         ListViewInsertionMark insertion_mark = control.InsertionMark;
2504                         int insertion_mark_index = insertion_mark.Index;
2505                         if (insertion_mark.Bounds != Rectangle.Empty &&
2506                                         (control.View != View.Details && control.View != View.List) &&
2507                                         insertion_mark_index > -1 && insertion_mark_index < control.Items.Count) {
2508
2509                                 Brush brush = ResPool.GetSolidBrush (insertion_mark.Color);
2510                                 dc.FillRectangle (brush, insertion_mark.Line);
2511                                 dc.FillPolygon (brush, insertion_mark.TopTriangle);
2512                                 dc.FillPolygon (brush, insertion_mark.BottomTriangle);
2513                         }
2514 #endif
2515                         
2516                         // draw the gridlines
2517                         if (details && control.GridLines) {
2518                                 int top = (control.HeaderStyle == ColumnHeaderStyle.None) ?
2519                                         2 : control.Font.Height + 2;
2520
2521                                 // draw vertical gridlines
2522                                 foreach (ColumnHeader col in control.Columns)
2523                                         dc.DrawLine (SystemPens.Control,
2524                                                      col.Rect.Right, top,
2525                                                      col.Rect.Right, control.TotalHeight);
2526                                 // draw horizontal gridlines
2527                                 ListViewItem last_item = null;
2528                                 foreach (ListViewItem item in control.Items) {
2529                                         dc.DrawLine (SystemPens.Control,
2530                                                      item.GetBounds (ItemBoundsPortion.Entire).Left, item.GetBounds (ItemBoundsPortion.Entire).Top,
2531                                                      control.TotalWidth, item.GetBounds (ItemBoundsPortion.Entire).Top);
2532                                         last_item = item;
2533                                 }
2534
2535                                 // draw a line after at the bottom of the last item
2536                                 if (last_item != null) {
2537                                         dc.DrawLine (SystemPens.Control,
2538                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Left,
2539                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Bottom,
2540                                                      control.TotalWidth,
2541                                                      last_item.GetBounds (ItemBoundsPortion.Entire).Bottom);
2542                                 }
2543                         }                       
2544                         
2545                         // Draw corner between the two scrollbars
2546                         if (control.h_scroll.Visible == true && control.v_scroll.Visible == true) {
2547                                 Rectangle rect = new Rectangle ();
2548                                 rect.X = control.h_scroll.Location.X + control.h_scroll.Width;
2549                                 rect.Width = control.v_scroll.Width;
2550                                 rect.Y = control.v_scroll.Location.Y + control.v_scroll.Height;
2551                                 rect.Height = control.h_scroll.Height;
2552                                 dc.FillRectangle (SystemBrushes.Control, rect);
2553                         }
2554
2555                         Rectangle box_select_rect = control.item_control.BoxSelectRectangle;
2556                         if (!box_select_rect.Size.IsEmpty)
2557                                 dc.DrawRectangle (ResPool.GetDashPen (ColorControlText, DashStyle.Dot), box_select_rect);
2558
2559                 }
2560
2561                 public override void DrawListViewHeader (Graphics dc, Rectangle clip, ListView control)
2562                 {       
2563                         bool details = (control.View == View.Details);
2564                                 
2565                         // border is drawn directly in the Paint method
2566                         if (details && control.HeaderStyle != ColumnHeaderStyle.None) {                         
2567                                 dc.FillRectangle (SystemBrushes.Control,
2568                                                   0, 0, control.TotalWidth, control.Font.Height + 5);
2569                                 if (control.Columns.Count > 0) {
2570                                         foreach (ColumnHeader col in control.Columns) {
2571                                                 Rectangle rect = col.Rect;
2572                                                 rect.X -= control.h_marker;
2573
2574 #if NET_2_0
2575                                                 bool owner_draw = false;
2576                                                 if (control.OwnerDraw)
2577                                                         owner_draw = DrawListViewColumnHeaderOwnerDraw (dc, control, col, rect);
2578                                                 if (owner_draw)
2579                                                         continue;
2580 #endif
2581
2582                                                 ListViewDrawColumnHeaderBackground (control, col, dc, rect, clip);
2583                                                 rect.X += 5;
2584                                                 rect.Width -= 10;
2585                                                 if (rect.Width <= 0)
2586                                                         continue;
2587
2588                                                 dc.DrawString (col.Text, control.Font,
2589                                                                SystemBrushes.ControlText,
2590                                                                rect, col.Format);
2591                                         }
2592                                         int right = control.GetReorderedColumn (control.Columns.Count - 1).Rect.Right - control.h_marker;
2593                                         if (right < control.Right) {
2594                                                 Rectangle rect = control.Columns [0].Rect;
2595                                                 rect.X = right;
2596                                                 rect.Width = control.Right - right;
2597                                                 ListViewDrawUnusedHeaderBackground (control, dc, rect, clip);
2598                                         }
2599                                 }
2600                         }
2601                 }
2602
2603                 protected virtual void ListViewDrawColumnHeaderBackground (ListView listView, ColumnHeader columnHeader, Graphics g, Rectangle area, Rectangle clippingArea)
2604                 {
2605                         ButtonState state;
2606                         if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2607                                 state = columnHeader.Pressed ? ButtonState.Pushed : ButtonState.Normal;
2608                         else
2609                                 state = ButtonState.Flat;
2610                         CPDrawButton (g, area, state);
2611                 }
2612                 
2613                 protected virtual void ListViewDrawUnusedHeaderBackground (ListView listView, Graphics g, Rectangle area, Rectangle clippingArea)
2614                 {
2615                         ButtonState state;
2616                         if (listView.HeaderStyle == ColumnHeaderStyle.Clickable)
2617                                 state = ButtonState.Normal;
2618                         else
2619                                 state = ButtonState.Flat;
2620                         CPDrawButton (g, area, state);
2621                 }
2622
2623                 public override void DrawListViewHeaderDragDetails (Graphics dc, ListView view, ColumnHeader col, int target_x)
2624                 {
2625                         Rectangle rect = col.Rect;
2626                         rect.X -= view.h_marker;
2627                         Color color = Color.FromArgb (0x7f, ColorControlDark.R, ColorControlDark.G, ColorControlDark.B);
2628                         dc.FillRectangle (ResPool.GetSolidBrush (color), rect);
2629                         rect.X += 3;
2630                         rect.Width -= 8;
2631                         if (rect.Width <= 0)
2632                                 return;
2633                         color = Color.FromArgb (0x7f, ColorControlText.R, ColorControlText.G, ColorControlText.B);
2634                         dc.DrawString (col.Text, view.Font, ResPool.GetSolidBrush (color), rect, col.Format);
2635                         dc.DrawLine (ResPool.GetSizedPen (ColorHighlight, 2), target_x, 0, target_x, col.Rect.Height);
2636                 }
2637
2638 #if NET_2_0
2639                 protected virtual bool DrawListViewColumnHeaderOwnerDraw (Graphics dc, ListView control, ColumnHeader column, Rectangle bounds)
2640                 {
2641                         ListViewItemStates state = ListViewItemStates.ShowKeyboardCues;
2642                         if (column.Pressed)
2643                                 state |= ListViewItemStates.Selected;
2644
2645                         DrawListViewColumnHeaderEventArgs args = new DrawListViewColumnHeaderEventArgs (dc,
2646                                         bounds, column.Index, column, state, SystemColors.ControlText, ThemeEngine.Current.ColorControl, DefaultFont);
2647                         control.OnDrawColumnHeader (args);
2648
2649                         return !args.DrawDefault;
2650                 }
2651
2652                 protected virtual bool DrawListViewItemOwnerDraw (Graphics dc, ListViewItem item, int index)
2653                 {
2654                         ListViewItemStates item_state = ListViewItemStates.ShowKeyboardCues;
2655                         if (item.Selected)
2656                                 item_state |= ListViewItemStates.Selected;
2657                         if (item.Focused)
2658                                 item_state |= ListViewItemStates.Focused;
2659                                                 
2660                         DrawListViewItemEventArgs args = new DrawListViewItemEventArgs (dc,
2661                                         item, item.Bounds, index, item_state);
2662                         item.ListView.OnDrawItem (args);
2663
2664                         if (args.DrawDefault)
2665                                 return false;
2666
2667                         if (item.ListView.View == View.Details) {
2668                                 int count = Math.Min (item.ListView.Columns.Count, item.SubItems.Count);
2669                                 
2670                                 // Do system drawing for subitems if no owner draw is done
2671                                 for (int j = 0; j < count; j++)
2672                                         if (!DrawListViewSubItemOwnerDraw (dc, item, item_state, j))
2673                                                 DrawListViewSubItem (dc, item.ListView, item, j);
2674                         }
2675                         
2676                         return true;
2677                 }
2678 #endif
2679
2680                 protected virtual void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
2681                 {                               
2682                         Rectangle rect_checkrect = item.CheckRectReal;
2683                         Rectangle icon_rect = item.GetBounds (ItemBoundsPortion.Icon);
2684                         Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire);
2685                         Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);                 
2686
2687 #if NET_2_0
2688                         // Tile view doesn't support CheckBoxes
2689                         if (control.CheckBoxes && control.View != View.Tile) {
2690 #else
2691                         if (control.CheckBoxes) {
2692 #endif
2693                                 if (control.StateImageList == null) {
2694                                         // Make sure we've got at least a line width of 1
2695                                         int check_wd = Math.Max (3, rect_checkrect.Width / 6);
2696                                         int scale = Math.Max (1, rect_checkrect.Width / 12);
2697
2698                                         // set the checkbox background
2699                                         dc.FillRectangle (SystemBrushes.Window,
2700                                                           rect_checkrect);
2701                                         // define a rectangle inside the border area
2702                                         Rectangle rect = new Rectangle (rect_checkrect.X + 2,
2703                                                                         rect_checkrect.Y + 2,
2704                                                                         rect_checkrect.Width - 4,
2705                                                                         rect_checkrect.Height - 4);
2706                                         Pen pen = ResPool.GetSizedPen (this.ColorWindowText, 2);
2707                                         dc.DrawRectangle (pen, rect);
2708
2709                                         // Need to draw a check-mark
2710                                         if (item.Checked) {
2711                                                 Pen check_pen = ResPool.GetSizedPen (this.ColorWindowText, 1);
2712                                                 // adjustments to get the check-mark at the right place
2713                                                 rect.X ++; rect.Y ++;
2714                                                 // following logic is taken from DrawFrameControl method
2715                                                 int x_offset = rect.Width / 5;
2716                                                 int y_offset = rect.Height / 3;
2717                                                 for (int i = 0; i < check_wd; i++) {
2718                                                         dc.DrawLine (check_pen, rect.Left + x_offset,
2719                                                                      rect.Top + y_offset + i,
2720                                                                      rect.Left + x_offset + 2 * scale,
2721                                                                      rect.Top + y_offset + 2 * scale + i);
2722                                                         dc.DrawLine (check_pen,
2723                                                                      rect.Left + x_offset + 2 * scale,
2724                                                                      rect.Top + y_offset + 2 * scale + i,
2725                                                                      rect.Left + x_offset + 6 * scale,
2726                                                                      rect.Top + y_offset - 2 * scale + i);
2727                                                 }
2728                                         }
2729                                 }
2730                                 else {
2731                                         int simage_idx;
2732                                         if (item.Checked)
2733 #if NET_2_0
2734                                                 simage_idx = control.StateImageList.Images.Count > 1 ? 1 : -1;
2735 #else
2736                                                 simage_idx = control.StateImageList.Images.Count > 1 ? 1 : 0;
2737 #endif
2738                                         else
2739                                                 simage_idx = control.StateImageList.Images.Count > 0 ? 0 : -1;
2740
2741                                         if (simage_idx > -1)
2742                                                 control.StateImageList.Draw (dc, rect_checkrect.Location, simage_idx);
2743                                 }
2744                         }
2745
2746                         ImageList image_list = control.View == View.LargeIcon 
2747 #if NET_2_0
2748                                 || control.View == View.Tile
2749 #endif
2750                                 ? control.LargeImageList : control.SmallImageList;
2751                         if (image_list != null) {
2752                                 int idx;
2753
2754 #if NET_2_0
2755                                 if (item.ImageKey != String.Empty)
2756                                         idx = image_list.Images.IndexOfKey (item.ImageKey);
2757                                 else
2758 #endif
2759                                         idx = item.ImageIndex;
2760
2761                                 if (idx > -1 && idx < image_list.Images.Count)
2762                                         image_list.Draw (dc, icon_rect.Location, idx);
2763                         }
2764
2765                         // draw the item text                   
2766                         // format for the item text
2767                         StringFormat format = new StringFormat ();
2768                         if (control.View == View.SmallIcon || control.View == View.LargeIcon)
2769                                 format.LineAlignment = StringAlignment.Near;
2770                         else
2771                                 format.LineAlignment = StringAlignment.Center;
2772                         if (control.View == View.LargeIcon)
2773                                 format.Alignment = StringAlignment.Center;
2774                         else
2775                                 format.Alignment = StringAlignment.Near;
2776                         
2777 #if NET_2_0
2778                         if (control.LabelWrap && control.View != View.Details && control.View != View.Tile)
2779 #else
2780                         if (control.LabelWrap && control.View != View.Details)
2781 #endif
2782                                 format.FormatFlags = StringFormatFlags.LineLimit;
2783                         else
2784                                 format.FormatFlags = StringFormatFlags.NoWrap;
2785
2786                         if ((control.View == View.LargeIcon && !item.Focused)
2787                                         || control.View == View.Details 
2788 #if NET_2_0
2789                                         || control.View == View.Tile
2790 #endif
2791                            )
2792                                 format.Trimming = StringTrimming.EllipsisCharacter;
2793
2794                         Rectangle highlight_rect = text_rect;
2795                         if (control.View == View.Details) { // Adjustments for Details view
2796                                 Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
2797
2798                                 if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
2799                                         highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
2800                         }
2801
2802                         if (item.Selected && control.Focused)
2803                                 dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
2804                         else if (item.Selected && !control.HideSelection)
2805                                 dc.FillRectangle (SystemBrushes.Control, highlight_rect);
2806                         else
2807                                 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
2808                         
2809                         Brush textBrush =
2810                                 !control.Enabled ? SystemBrushes.ControlLight :
2811                                 (item.Selected && control.Focused) ? SystemBrushes.HighlightText :
2812                                 this.ResPool.GetSolidBrush (item.ForeColor);
2813
2814 #if NET_2_0
2815                         // Tile view renders its Text in a different fashion
2816                         if (control.View == View.Tile) {
2817                                 // Item.Text is drawn using its first subitem's bounds
2818                                 dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
2819
2820                                 int count = Math.Min (control.Columns.Count, item.SubItems.Count);
2821                                 for (int i = 1; i < count; i++) {
2822                                         ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
2823                                         if (sub_item.Text == null || sub_item.Text.Length == 0)
2824                                                 continue;
2825
2826                                         Brush itemBrush = item.Selected && control.Focused ? 
2827                                                 SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
2828                                         dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
2829                                 }
2830                         } else
2831 #endif
2832                         
2833                         if (item.Text != null && item.Text.Length > 0) {
2834                                 Font font = item.Font;
2835 #if NET_2_0
2836                                 if (control.HotTracking && item.Hot)
2837                                         font = item.HotFont;
2838 #endif
2839
2840                                 if (item.Selected && control.Focused)
2841                                         dc.DrawString (item.Text, font, textBrush, highlight_rect, format);
2842                                 else
2843                                         dc.DrawString (item.Text, font, textBrush, text_rect, format);
2844                         }
2845
2846                         if (control.View == View.Details && control.Columns.Count > 0) {
2847                                 // draw subitems for details view
2848                                 ListViewItem.ListViewSubItemCollection subItems = item.SubItems;
2849                                 int count = (control.Columns.Count < subItems.Count ? 
2850                                              control.Columns.Count : subItems.Count);
2851
2852                                 if (count > 0) {
2853                                         // 0th subitem is the item already drawn
2854                                         for (int index = 1; index < count; index++)
2855                                                 DrawListViewSubItem (dc, control, item, index);
2856
2857                                         // Fill in selection for remaining columns if Column.Count > SubItems.Count
2858                                         ColumnHeader col;
2859                                         Rectangle sub_item_rect = text_rect;
2860                                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
2861                                                 for (int index = count; index < control.Columns.Count; index++) {
2862                                                         col = control.Columns [index];
2863                                                         sub_item_rect.X = col.Rect.X - control.h_marker;
2864                                                         sub_item_rect.Width = col.Wd;
2865                                                         if (control.Focused)
2866                                                                 dc.FillRectangle (SystemBrushes.Highlight, sub_item_rect);
2867                                                         else
2868                                                                 dc.FillRectangle (SystemBrushes.Control, sub_item_rect);
2869                                                 }
2870                                         }
2871                                 }
2872                         }
2873
2874                         if (item.Focused && control.Focused) {                          
2875                                 Rectangle focus_rect = highlight_rect;
2876                                 if (control.FullRowSelect && control.View == View.Details) {
2877                                         int width = 0;
2878                                         foreach (ColumnHeader col in control.Columns)
2879                                                 width += col.Width;
2880                                         focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height);
2881                                 }
2882                                 if (item.Selected)
2883                                         CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight);
2884                                 else
2885                                         CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor);
2886                         }
2887
2888                         format.Dispose ();
2889                 }
2890
2891                 protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index)
2892                 {
2893                         ListViewItem.ListViewSubItem subItem = item.SubItems [index];
2894                         ColumnHeader col = control.Columns [index];
2895                         StringFormat format = new StringFormat ();
2896                         format.Alignment = col.Format.Alignment;
2897                         format.FormatFlags = StringFormatFlags.NoWrap;
2898                         format.Trimming = StringTrimming.EllipsisCharacter;
2899
2900                         Rectangle sub_item_rect = subItem.Bounds;
2901                         Rectangle sub_item_text_rect = sub_item_rect;
2902                         sub_item_text_rect.X += 3;
2903                         sub_item_text_rect.Width -= ListViewItemPaddingWidth;
2904                                                 
2905                         SolidBrush sub_item_back_br = null;
2906                         SolidBrush sub_item_fore_br = null;
2907                         Font sub_item_font = null;
2908                                                 
2909                         if (item.UseItemStyleForSubItems) {
2910                                 sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
2911                                 sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
2912 #if NET_2_0
2913                                 // Hot tracking for subitems only applies when UseStyle is true
2914                                 if (control.HotTracking && item.Hot)
2915                                         sub_item_font = item.HotFont;
2916                                 else
2917 #endif
2918                                         sub_item_font = item.Font;
2919                         } else {
2920                                 sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
2921                                 sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
2922                                 sub_item_font = subItem.Font;
2923                         }
2924                                                 
2925                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
2926                                 Brush bg, text;
2927                                 if (control.Focused) {
2928                                         bg = SystemBrushes.Highlight;
2929                                         text = SystemBrushes.HighlightText;
2930                                 } else {
2931                                         bg = SystemBrushes.Control;
2932                                         text = sub_item_fore_br;
2933                                                         
2934                                 }
2935                                                         
2936                                 dc.FillRectangle (bg, sub_item_rect);
2937                                 if (subItem.Text != null && subItem.Text.Length > 0)
2938                                         dc.DrawString (subItem.Text, sub_item_font,
2939                                                         text, sub_item_text_rect, format);
2940                         } else {
2941                                 dc.FillRectangle (sub_item_back_br, sub_item_rect);
2942                                 if (subItem.Text != null && subItem.Text.Length > 0)
2943                                         dc.DrawString (subItem.Text, sub_item_font,
2944                                                         sub_item_fore_br,
2945                                                         sub_item_text_rect, format);
2946                         }
2947
2948                         format.Dispose ();
2949                 }
2950
2951 #if NET_2_0
2952                 protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index)
2953                 {
2954                         ListView control = item.ListView;
2955                         ListViewItem.ListViewSubItem subitem = item.SubItems [index];
2956
2957                         DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item, 
2958                                         subitem, item.Index, index, control.Columns [index], state);
2959                         control.OnDrawSubItem (args);
2960                         
2961                         return !args.DrawDefault;
2962                 }
2963
2964                 protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group)
2965                 {
2966                         Rectangle text_bounds = group.HeaderBounds;
2967                         Rectangle header_bounds = group.HeaderBounds;
2968                         text_bounds.Offset (8, 0);
2969                         text_bounds.Inflate (-8, 0);
2970                         Size text_size = control.text_size;
2971
2972                         Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
2973                         Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0), 
2974                                         SystemColors.Desktop, Color.White);
2975                         Pen pen = new Pen (brush);
2976
2977                         StringFormat sformat = new StringFormat ();
2978                         switch (group.HeaderAlignment) {
2979                                 case HorizontalAlignment.Left:
2980                                         sformat.Alignment = StringAlignment.Near;
2981                                         break;
2982                                 case HorizontalAlignment.Center:
2983                                         sformat.Alignment = StringAlignment.Center;
2984                                         break;
2985                                 case HorizontalAlignment.Right:
2986                                         sformat.Alignment = StringAlignment.Far;
2987                                         break;
2988                         }
2989
2990                         sformat.LineAlignment = StringAlignment.Near;
2991                         dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat);
2992                         dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_size.Height, header_bounds.Left + ListViewGroupLineWidth, 
2993                                         header_bounds.Top + text_size.Height);
2994
2995                         sformat.Dispose ();
2996                         font.Dispose ();
2997                         pen.Dispose ();
2998                         brush.Dispose ();
2999                 }
3000 #endif
3001
3002                 public override bool ListViewHasHotHeaderStyle {
3003                         get {
3004                                 return false;
3005                         }
3006                 }
3007
3008                 // Sizing
3009                 public override int ListViewGetHeaderHeight (ListView listView, Font font)
3010                 {
3011                         return font.Height + 5;
3012                 }
3013
3014                 public override Size ListViewCheckBoxSize {
3015                         get { return new Size (16, 16); }
3016                 }
3017
3018                 public override int ListViewColumnHeaderHeight {
3019                         get { return 16; }
3020                 }
3021
3022                 public override int ListViewDefaultColumnWidth {
3023                         get { return 60; }
3024                 }
3025
3026                 public override int ListViewVerticalSpacing {
3027                         get { return 22; }
3028                 }
3029
3030                 public override int ListViewEmptyColumnWidth {
3031                         get { return 10; }
3032                 }
3033
3034                 public override int ListViewHorizontalSpacing {
3035                         get { return 4; }
3036                 }
3037
3038                 public override int ListViewItemPaddingWidth {
3039                         get { return 6; }
3040                 }
3041
3042                 public override Size ListViewDefaultSize {
3043                         get { return new Size (121, 97); }
3044                 }
3045
3046                 public override int ListViewGroupHeight { 
3047                         get { return 20; }
3048                 }
3049
3050                 public int ListViewGroupLineWidth {
3051                         get { return 200; }
3052                 }
3053
3054                 public override int ListViewTileWidthFactor {
3055                         get { return 22; }
3056                 }
3057
3058                 public override int ListViewTileHeightFactor {
3059                         get { return 3; }
3060                 }
3061                 #endregion      // ListView
3062                 
3063                 #region Menus
3064                 
3065                 public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
3066                 {
3067                         item.X = x;
3068                         item.Y = y;
3069
3070                         if (item.Visible == false) {
3071                                 item.Width = 0;
3072                                 item.Height = 0;
3073                                 return;
3074                         }
3075
3076                         if (item.Separator == true) {
3077                                 item.Height = SEPARATOR_HEIGHT;
3078                                 item.Width = SEPARATOR_MIN_WIDTH;
3079                                 return;
3080                         }
3081                         
3082                         if (item.MeasureEventDefined) {
3083                                 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
3084                                 item.PerformMeasureItem (mi);
3085                                 item.Height = mi.ItemHeight;
3086                                 item.Width = mi.ItemWidth;
3087                                 return;
3088                         } else {                
3089                                 SizeF size;
3090                                 size =  dc.MeasureString (item.Text, MenuFont, int.MaxValue, string_format_menu_text);
3091                                 item.Width = (int) size.Width;
3092                                 item.Height = (int) size.Height;
3093         
3094                                 if (!menuBar) {
3095                                         if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
3096                                                 item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
3097                                                 size =  dc.MeasureString (" " + item.GetShortCutText (), MenuFont);
3098                                                 item.Width += MENU_TAB_SPACE + (int) size.Width;
3099                                         }
3100         
3101                                         item.Width += 4 + (MenuCheckSize.Width * 2);
3102                                 } else {
3103                                         item.Width += MENU_BAR_ITEMS_SPACE;
3104                                         x += item.Width;
3105                                 }
3106         
3107                                 if (item.Height < MenuHeight)
3108                                         item.Height = MenuHeight;
3109                         }
3110                 }
3111                 
3112                 // Updates the menu rect and returns the height
3113                 public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
3114                 {
3115                         int x = 0;
3116                         int y = 0;
3117                         menu.Height = 0;
3118
3119                         foreach (MenuItem item in menu.MenuItems) {
3120
3121                                 CalcItemSize (dc, item, y, x, true);
3122
3123                                 if (x + item.Width > width) {
3124                                         item.X = 0;
3125                                         y += item.Height;
3126                                         item.Y = y;
3127                                         x = 0;
3128                                 }
3129
3130                                 x += item.Width;
3131                                 item.MenuBar = true;                            
3132
3133                                 if (y + item.Height > menu.Height)
3134                                         menu.Height = item.Height + y;
3135                         }
3136
3137                         menu.Width = width;                                             
3138                         return menu.Height;
3139                 }
3140
3141                 public override void CalcPopupMenuSize (Graphics dc, Menu menu)
3142                 {
3143                         int x = 3;
3144                         int start = 0;
3145                         int i, n, y, max;
3146
3147                         menu.Height = 0;
3148
3149                         while (start < menu.MenuItems.Count) {
3150                                 y = 3;
3151                                 max = 0;
3152                                 for (i = start; i < menu.MenuItems.Count; i++) {
3153                                         MenuItem item = menu.MenuItems [i];
3154
3155                                         if ((i != start) && (item.Break || item.BarBreak))
3156                                                 break;
3157
3158                                         CalcItemSize (dc, item, y, x, false);
3159                                         y += item.Height;
3160
3161                                         if (item.Width > max)
3162                                                 max = item.Width;
3163                                 }
3164
3165                                 // Replace the -1 by the menu width (separators)
3166                                 for (n = start; n < i; n++, start++)
3167                                         menu.MenuItems [n].Width = max;
3168
3169                                 if (y > menu.Height)
3170                                         menu.Height = y;
3171
3172                                 x+= max;
3173                         }
3174
3175                         menu.Width = x;
3176                         
3177                         //space for border
3178                         menu.Width += 2;
3179                         menu.Height += 2;
3180
3181                         menu.Width += SM_CXBORDER;
3182                 menu.Height += SM_CYBORDER;
3183                 }
3184                 
3185                 // Draws a menu bar in a window
3186                 public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
3187                 {
3188                         if (menu.Height == 0)
3189                                 CalcMenuBarSize (dc, menu, rect.Width);
3190
3191                         bool keynav = (menu as MainMenu).tracker.hotkey_active;
3192                         HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
3193                         string_format_menu_menubar_text.HotkeyPrefix = hp;
3194                         string_format_menu_text.HotkeyPrefix = hp;
3195
3196                         rect.Height = menu.Height;
3197                         dc.FillRectangle (SystemBrushes.Menu, rect);
3198                         
3199                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3200                                 MenuItem item = menu.MenuItems [i];
3201                                 Rectangle item_rect = item.bounds;
3202                                 item_rect.X += rect.X;
3203                                 item_rect.Y += rect.Y;
3204                                 item.MenuHeight = menu.Height;
3205                                 item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status)); 
3206                         }       
3207                 }               
3208                 
3209                 protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color)
3210                 {
3211                         Color bg_color;
3212                         if (color.R == 0 && color.G == 0 && color.B == 0)
3213                                 bg_color = Color.White;
3214                         else
3215                                 bg_color = Color.Black;
3216                         
3217                         Bitmap  bmp = new Bitmap (size.Width, size.Height);
3218                         Graphics gr = Graphics.FromImage (bmp);
3219                         Rectangle rect = new Rectangle (Point.Empty, size);
3220                         gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
3221                         CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty);
3222                         bmp.MakeTransparent (bg_color);
3223                         gr.Dispose ();
3224                         
3225                         return bmp;
3226                 }
3227
3228                 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
3229                 {
3230                         StringFormat string_format;
3231                         Rectangle rect_text = e.Bounds;
3232                         
3233                         if (item.Visible == false)
3234                                 return;
3235
3236                         if (item.MenuBar)
3237                                 string_format = string_format_menu_menubar_text;
3238                         else
3239                                 string_format = string_format_menu_text;
3240
3241                         if (item.Separator == true) {
3242                                 int liney = e.Bounds.Y + (e.Bounds.Height / 2);
3243                                 
3244                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3245                                         e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney);
3246
3247                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3248                                         e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1);
3249
3250                                 return;
3251                         }
3252
3253                         if (!item.MenuBar)
3254                                 rect_text.X += MenuCheckSize.Width;
3255
3256                         if (item.BarBreak) { /* Draw vertical break bar*/
3257                                 Rectangle rect = e.Bounds;
3258                                 rect.Y++;
3259                                 rect.Width = 3;
3260                                 rect.Height = item.MenuHeight - 6;
3261
3262                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3263                                         rect.X, rect.Y , rect.X, rect.Y + rect.Height);
3264
3265                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3266                                         rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
3267                         }                       
3268                         
3269                         Color color_text;
3270                         Color color_back;
3271                         Brush brush_text = null;
3272                         Brush brush_back = null;
3273                         
3274                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) {
3275                                 color_text = ColorHighlightText;
3276                                 color_back = ColorHighlight;
3277                                 brush_text = SystemBrushes.HighlightText;
3278                                 brush_back = SystemBrushes.Highlight;
3279                         } else {
3280                                 color_text = ColorMenuText;
3281                                 color_back = ColorMenu;
3282                                 brush_text = ResPool.GetSolidBrush (ColorMenuText);
3283                                 brush_back = SystemBrushes.Menu;
3284                         }
3285
3286                         /* Draw background */
3287                         if (!item.MenuBar)
3288                                 e.Graphics.FillRectangle (brush_back, e.Bounds);
3289                         
3290                         if (item.Enabled) {
3291                                 e.Graphics.DrawString (item.Text, e.Font,
3292                                         brush_text,
3293                                         rect_text, string_format);
3294                                 
3295                                 if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
3296                                         string str = item.GetShortCutText ();
3297                                         Rectangle rect = rect_text;
3298                                         rect.X = item.XTab;
3299                                         rect.Width -= item.XTab;
3300
3301                                         e.Graphics.DrawString (str, e.Font, brush_text,
3302                                                 rect, string_format_menu_shortcut);
3303                                 }
3304                                 
3305                                 if (item.MenuBar) {
3306                                         Border3DStyle border_style = Border3DStyle.Adjust;
3307                                         if ((item.Status & DrawItemState.HotLight) != 0)
3308                                                 border_style = Border3DStyle.RaisedInner;
3309                                         else if ((item.Status & DrawItemState.Selected) != 0)
3310                                                 border_style = Border3DStyle.SunkenOuter;
3311                                         
3312                                         if (border_style != Border3DStyle.Adjust)
3313                                                 CPDrawBorder3D(e.Graphics, e.Bounds, border_style,  Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu);
3314                                 }
3315                         } else {
3316                                 if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3317                                         e.Graphics.DrawString (item.Text, e.Font, Brushes.White, 
3318                                                                new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height),
3319                                                                string_format);
3320                                 }
3321                                 
3322                                 e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format);
3323                         }
3324
3325                         /* Draw arrow */
3326                         if (item.MenuBar == false && (item.IsPopup || item.MdiList)) {
3327
3328                                 int cx = MenuCheckSize.Width;
3329                                 int cy = MenuCheckSize.Height;
3330                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text);
3331                                 
3332                                 if (item.Enabled) {
3333                                         e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
3334                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
3335                                 } else {
3336                                         ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
3337                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
3338                                 }
3339  
3340                                 bmp.Dispose ();
3341                         }
3342
3343                         /* Draw checked or radio */
3344                         if (item.MenuBar == false && item.Checked) {
3345
3346                                 Rectangle area = e.Bounds;
3347                                 int cx = MenuCheckSize.Width;
3348                                 int cy = MenuCheckSize.Height;
3349                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text);
3350
3351                                 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
3352
3353                                 bmp.Dispose ();
3354                         }                       
3355                 }               
3356                         
3357                 public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
3358                 {
3359                         // Fill rectangle area
3360                         dc.FillRectangle (SystemBrushes.Menu, cliparea);
3361                         
3362                         // Draw menu borders
3363                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
3364                         
3365                         // Draw menu items
3366                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3367                                 if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
3368                                         MenuItem item = menu.MenuItems [i];
3369                                         item.MenuHeight = menu.Height;
3370                                         item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status));
3371                                 }
3372                         }
3373                 }
3374                 
3375                 #endregion // Menus
3376
3377                 #region MonthCalendar
3378
3379                 // draw the month calendar
3380                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) 
3381                 {
3382                         Rectangle client_rectangle = mc.ClientRectangle;
3383                         Size month_size = mc.SingleMonthSize;
3384                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3385                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
3386                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3387                         
3388                         // draw the singlecalendars
3389                         int x_offset = 1;
3390                         int y_offset = 1;
3391                         // adjust for the position of the specific month
3392                         for (int i=0; i < mc.CalendarDimensions.Height; i++) 
3393                         {
3394                                 if (i > 0) 
3395                                 {
3396                                         y_offset += month_size.Height + calendar_spacing.Height;
3397                                 }
3398                                 // now adjust for x position    
3399                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) 
3400                                 {
3401                                         if (j > 0) 
3402                                         {
3403                                                 x_offset += month_size.Width + calendar_spacing.Width;
3404                                         } 
3405                                         else 
3406                                         {
3407                                                 x_offset = 1;
3408                                         }
3409
3410                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
3411                                         if (month_rect.IntersectsWith (clip_rectangle)) {
3412                                                 DrawSingleMonth (
3413                                                         dc,
3414                                                         clip_rectangle,
3415                                                         month_rect,
3416                                                         mc,
3417                                                         i,
3418                                                         j);
3419                                         }
3420                                 }
3421                         }
3422                         
3423                         Rectangle bottom_rect = new Rectangle (
3424                                                 client_rectangle.X,
3425                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
3426                                                 client_rectangle.Width,
3427                                                 date_cell_size.Height + 2);
3428                         // draw the today date if it's set
3429                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) 
3430                         {
3431                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect);
3432                                 if (mc.ShowToday) {
3433                                         int today_offset = 5;
3434                                         if (mc.ShowTodayCircle) 
3435                                         {
3436                                                 Rectangle today_circle_rect = new Rectangle (
3437                                                         client_rectangle.X + 5,
3438                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
3439                                                         date_cell_size.Width,
3440                                                         date_cell_size.Height);
3441                                                         DrawTodayCircle (dc, today_circle_rect);
3442                                                 today_offset += date_cell_size.Width + 5;
3443                                         }
3444                                         // draw today's date
3445                                         StringFormat text_format = new StringFormat();
3446                                         text_format.LineAlignment = StringAlignment.Center;
3447                                         text_format.Alignment = StringAlignment.Near;
3448                                         Rectangle today_rect = new Rectangle (
3449                                                         today_offset + client_rectangle.X,
3450                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
3451                                                         Math.Max(client_rectangle.Width - today_offset, 0),
3452                                                         date_cell_size.Height);
3453                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format);
3454                                         text_format.Dispose ();
3455                                 }                               
3456                         }
3457                         
3458                         Brush border_brush;
3459                         
3460                         if (mc.owner == null)
3461                                 border_brush = GetControlBackBrush (mc.BackColor);
3462                         else
3463                                 border_brush = SystemBrushes.ControlDarkDark;
3464                                 
3465                         // finally paint the borders of the calendars as required
3466                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
3467                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
3468                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height);
3469                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
3470                                         dc.FillRectangle (border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height);
3471                                 } else { 
3472                                         Rectangle rect = new Rectangle (
3473                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
3474                                                 client_rectangle.Y,
3475                                                 calendar_spacing.Width,
3476                                                 client_rectangle.Height);
3477                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3478                                                 dc.FillRectangle (border_brush, rect);
3479                                         }
3480                                 }
3481                         }
3482                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
3483                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
3484                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1);
3485                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
3486                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1);
3487                                 } else { 
3488                                         Rectangle rect = new Rectangle (
3489                                                 client_rectangle.X,
3490                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
3491                                                 client_rectangle.Width,
3492                                                 calendar_spacing.Height);
3493                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3494                                                 dc.FillRectangle (border_brush, rect);
3495                                         }
3496                                 }
3497                         }
3498                         
3499                         // draw the drop down border if need
3500                         if (mc.owner != null) {
3501                                 Rectangle bounds = mc.ClientRectangle;
3502                                 if (clip_rectangle.Contains (mc.Location)) {
3503                                         // find out if top or left line to draw
3504                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3505                                         
3506                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
3507                                         }
3508                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3509                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
3510                                         }
3511                                 }
3512                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
3513                                         // find out if bottom or right line to draw
3514                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3515                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
3516                                         }
3517                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3518                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
3519                                         }
3520                                 }
3521                         }
3522                 }
3523
3524                 // darws a single part of the month calendar (with one month)
3525                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) 
3526                 {
3527                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3528                         Size title_size = (Size)((object)mc.title_size);
3529                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3530                         DateTime current_month = (DateTime)((object)mc.current_month);
3531                         DateTime sunday = new DateTime(2006, 10, 1);
3532                         
3533                         // draw the title back ground
3534                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
3535                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
3536                         if (title_rect.IntersectsWith (clip_rectangle)) {
3537                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
3538                                 // draw the title                               
3539                                 string title_text = this_month.ToString ("MMMM yyyy");
3540                                 dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format);
3541
3542                                 if (mc.ShowYearUpDown) {
3543                                         Rectangle year_rect;
3544                                         Rectangle upRect, downRect;
3545                                         ButtonState upState, downState;
3546                                         
3547                                         mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect);
3548                                         dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect);
3549                                         dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format);
3550                                         
3551                                         upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal;
3552                                         downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal;
3553
3554                                         ControlPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState);
3555                                         ControlPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState);
3556                                 }
3557
3558                                 // draw previous and next buttons if it's time
3559                                 if (row == 0 && col == 0) 
3560                                 {
3561                                         // draw previous button
3562                                         DrawMonthCalendarButton (
3563                                                 dc,
3564                                                 rectangle,
3565                                                 mc,
3566                                                 title_size,
3567                                                 mc.button_x_offset,
3568                                                 (System.Drawing.Size)((object)mc.button_size),
3569                                                 true);
3570                                 }
3571                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) 
3572                                 {
3573                                         // draw next button
3574                                         DrawMonthCalendarButton (
3575                                                 dc,
3576                                                 rectangle,
3577                                                 mc,
3578                                                 title_size,
3579                                                 mc.button_x_offset,
3580                                                 (System.Drawing.Size)((object)mc.button_size),
3581                                                 false);
3582                                 }
3583                         }
3584                         
3585                         // set the week offset and draw week nums if needed
3586                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
3587                         Rectangle day_name_rect = new Rectangle(
3588                                 rectangle.X,
3589                                 rectangle.Y + title_size.Height,
3590                                 (7 + col_offset) * date_cell_size.Width,
3591                                 date_cell_size.Height);
3592                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
3593                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect);
3594                                 // draw the day names 
3595                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
3596                                 for (int i=0; i < 7; i++) 
3597                                 {
3598                                         int position = i - (int) first_day_of_week;
3599                                         if (position < 0) 
3600                                         {
3601                                                 position = 7 + position;
3602                                         }
3603                                         // draw it
3604                                         Rectangle day_rect = new Rectangle(
3605                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
3606                                                 day_name_rect.Y,
3607                                                 date_cell_size.Width,
3608                                                 date_cell_size.Height);
3609                                         dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format);
3610                                 }
3611                                 
3612                                 // draw the vertical divider
3613                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
3614                                 dc.DrawLine (
3615                                         ResPool.GetPen (mc.ForeColor),
3616                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
3617                                         rectangle.Y + vert_divider_y,
3618                                         rectangle.Right - mc.divider_line_offset,
3619                                         rectangle.Y + vert_divider_y);
3620                         }
3621
3622
3623                         // draw the actual date items in the grid (including the week numbers)
3624                         Rectangle date_rect = new Rectangle (
3625                                 rectangle.X,
3626                                 rectangle.Y + title_size.Height + date_cell_size.Height,
3627                                 date_cell_size.Width,
3628                                 date_cell_size.Height);
3629                         int month_row_count = 0;
3630                         bool draw_week_num_divider = false;
3631                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
3632                         for (int i=0; i < 6; i++) 
3633                         {
3634                                 // establish if this row is in our clip_area
3635                                 Rectangle row_rect = new Rectangle (
3636                                         rectangle.X,
3637                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
3638                                         date_cell_size.Width * 7,
3639                                         date_cell_size.Height);
3640                                 if (mc.ShowWeekNumbers) {
3641                                         row_rect.Width += date_cell_size.Width;
3642                                 }
3643                 
3644                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
3645                                 if (draw_row) {
3646                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect);
3647                                 }
3648                                 // establish if this is a valid week to draw
3649                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
3650                                         month_row_count = i;
3651                                 }
3652                                 
3653                                 // draw the week number if required
3654                                 if (mc.ShowWeekNumbers && month_row_count == i) {
3655                                         if (!draw_week_num_divider) {
3656                                                 draw_week_num_divider = draw_row;
3657                                         }
3658                                         // get the week for this row
3659                                         int week = mc.GetWeekOfYear (current_date);     
3660
3661                                         if (draw_row) {
3662                                                 dc.DrawString (
3663                                                         week.ToString(),
3664                                                         mc.Font,
3665                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
3666                                                         date_rect,
3667                                                         mc.centered_format);
3668                                         }
3669                                         date_rect.Offset(date_cell_size.Width, 0);
3670                                 }
3671                                                                 
3672                                 // only draw the days if we have to
3673                                 if(month_row_count == i) {
3674                                         for (int j=0; j < 7; j++) 
3675                                         {
3676                                                 if (draw_row) {
3677                                                         DrawMonthCalendarDate (
3678                                                                 dc,
3679                                                                 date_rect,
3680                                                                 mc,
3681                                                                 current_date,
3682                                                                 this_month,
3683                                                                 row,
3684                                                                 col);
3685                                                 }
3686
3687                                                 // move the day on
3688                                                 current_date = current_date.AddDays(1);
3689                                                 date_rect.Offset(date_cell_size.Width, 0);
3690                                         }
3691
3692                                         // shift the rectangle down one row
3693                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
3694                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
3695                                 }
3696                         }
3697
3698                         // month_row_count is zero based, so add one
3699                         month_row_count++;
3700
3701                         // draw week numbers if required
3702                         if (draw_week_num_divider) {
3703                                 col_offset = 1;
3704                                 dc.DrawLine (
3705                                         ResPool.GetPen (mc.ForeColor),
3706                                         rectangle.X + date_cell_size.Width - 1,
3707                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
3708                                         rectangle.X + date_cell_size.Width - 1,
3709                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
3710                         }
3711                 }
3712
3713                 // draws the pervious or next button
3714                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) 
3715                 {
3716                         const int arrow_width = 4;
3717                         const int arrow_height = 7;
3718
3719                         bool is_clicked = false;
3720                         Rectangle button_rect;
3721                         PointF arrow_center;
3722                         PointF [] arrow_path = new PointF [3];
3723                         
3724                         // prepare the button
3725                         if (is_previous) 
3726                         {
3727                                 is_clicked = mc.is_previous_clicked;
3728
3729                                 button_rect = new Rectangle (
3730                                         rectangle.X + 1 + x_offset,
3731                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3732                                         Math.Max(button_size.Width - 1, 0),
3733                                         Math.Max(button_size.Height - 1, 0));
3734
3735                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3736                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3737                                 if (is_clicked) {
3738                                         arrow_center.X += 1;
3739                                         arrow_center.Y += 1;
3740                                 }
3741
3742                                 arrow_path [0].X = arrow_center.X;
3743                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3744                                 arrow_path [1].X = arrow_center.X;
3745                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3746                                 arrow_path [2].X = arrow_center.X - arrow_width;
3747                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3748                         }
3749                         else
3750                         {
3751                                 is_clicked = mc.is_next_clicked;
3752
3753                                 button_rect = new Rectangle (
3754                                         rectangle.Right - 1 - x_offset - button_size.Width,
3755                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3756                                         Math.Max(button_size.Width - 1, 0),
3757                                         Math.Max(button_size.Height - 1, 0));
3758
3759                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3760                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3761                                 if (is_clicked) {
3762                                         arrow_center.X += 1;
3763                                         arrow_center.Y += 1;
3764                                 }
3765
3766                                 arrow_path [0].X = arrow_center.X - arrow_width;
3767                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3768                                 arrow_path [1].X = arrow_center.X - arrow_width;
3769                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3770                                 arrow_path [2].X = arrow_center.X;
3771                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3772                         }
3773
3774                         // fill the background
3775                         dc.FillRectangle (SystemBrushes.Control, button_rect);
3776                         // draw the border
3777                         if (is_clicked) {
3778                                 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
3779                         }
3780                         else {
3781                                 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
3782                         }
3783                         // draw the arrow
3784                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);                 
3785                         //dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding);
3786                 }
3787                 
3788
3789                 // draws one day in the calendar grid
3790                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
3791                         Color date_color = mc.ForeColor;
3792                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
3793
3794                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
3795                         if (date.Year != month.Year || date.Month != month.Month) {
3796                                 DateTime check_date = month.AddMonths (-1);
3797                                 // check if it's the month before 
3798                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
3799                                         date_color = mc.TrailingForeColor;
3800                                 } else {
3801                                         // check if it's the month after
3802                                         check_date = month.AddMonths (1);
3803                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
3804                                                 date_color = mc.TrailingForeColor;
3805                                         } else {
3806                                                 return;
3807                                         }
3808                                 }
3809                         } else {
3810                                 date_color = mc.ForeColor;
3811                         }
3812
3813                         const int inflate = -1;
3814
3815                         if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) {
3816                                 // see if the date is in the start of selection
3817                                 date_color = mc.BackColor;
3818                                 // draw the left hand of the back ground
3819                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
3820                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360);
3821                         } else if (date == mc.SelectionStart.Date) {
3822                                 // see if the date is in the start of selection
3823                                 date_color = mc.BackColor;
3824                                 // draw the left hand of the back ground
3825                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
3826                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
3827                                 // fill the other side as a straight rect
3828                                 if (date < mc.SelectionEnd.Date) 
3829                                 {
3830                                         // use rectangle instead of rectangle to go all the way to edge of rect
3831                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
3832                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
3833                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3834                                 }
3835                         } else if (date == mc.SelectionEnd.Date) {
3836                                 // see if it is the end of selection
3837                                 date_color = mc.BackColor;
3838                                 // draw the left hand of the back ground
3839                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
3840                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
3841                                 // fill the other side as a straight rect
3842                                 if (date > mc.SelectionStart.Date) {
3843                                         selection_rect.X = rectangle.X;
3844                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
3845                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3846                                 }
3847                         } else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) {
3848                                 // now see if it's in the middle
3849                                 date_color = mc.BackColor;
3850                                 // draw the left hand of the back ground
3851                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate);
3852                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3853                         }
3854
3855                         // establish if it's a bolded font
3856                         Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font;
3857
3858                         // just draw the date now
3859                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format);
3860
3861                         // today circle if needed
3862                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
3863                                 DrawTodayCircle (dc, interior);
3864                         }
3865
3866                         // draw the selection grid
3867                         if (mc.is_date_clicked && mc.clicked_date == date) {
3868                                 Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot);
3869                                 dc.DrawRectangle (pen, interior);
3870                         }
3871                 }
3872
3873                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
3874                         Color circle_color = Color.FromArgb (248, 0, 0);
3875                         // draw the left hand of the circle 
3876                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
3877                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
3878                         Point [] curve_points = new Point [3];
3879                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
3880                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
3881                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
3882
3883                         Pen pen = ResPool.GetSizedPen(circle_color, 2);
3884                         dc.DrawArc (pen, lhs_circle_rect, 90, 180);
3885                         dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
3886                         dc.DrawCurve (pen, curve_points);
3887                         dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
3888                 }
3889
3890                 #endregion      // MonthCalendar
3891
3892                 #region Panel
3893                 public override Size PanelDefaultSize {
3894                         get {
3895                                 return new Size (200, 100);
3896                         }
3897                 }
3898                 #endregion      // Panel
3899
3900                 #region PictureBox
3901                 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
3902                         Rectangle client = pb.ClientRectangle;
3903
3904                         // FIXME - instead of drawing the whole picturebox every time
3905                         // intersect the clip rectangle with the drawn picture and only draw what's needed,
3906                         // Also, we only need a background fill where no image goes
3907                         if (pb.Image != null) {
3908                                 switch (pb.SizeMode) {
3909                                 case PictureBoxSizeMode.StretchImage:
3910                                         dc.DrawImage (pb.Image, 0, 0, client.Width, client.Height);
3911                                         break;
3912
3913                                 case PictureBoxSizeMode.CenterImage:
3914                                         dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
3915                                         break;
3916 #if NET_2_0
3917                                 case PictureBoxSizeMode.Zoom:
3918                                         Size image_size;
3919                                         
3920                                         if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height))
3921                                                 image_size = new Size (client.Width, (pb.Image.Height * client.Width) / pb.Image.Width);
3922                                         else
3923                                                 image_size = new Size ((pb.Image.Width * client.Height) / pb.Image.Height, client.Height);
3924
3925                                         dc.DrawImage (pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height);
3926                                         break;
3927 #endif
3928                                 default:
3929                                         // Normal, AutoSize
3930                                         dc.DrawImage(pb.Image, 0, 0, pb.Image.Width, pb.Image.Height);
3931                                         break;
3932                                 }
3933
3934                                 return;
3935                         }
3936                 }
3937
3938                 public override Size PictureBoxDefaultSize {
3939                         get {
3940                                 return new Size (100, 50);
3941                         }
3942                 }
3943                 #endregion      // PictureBox
3944
3945                 #region PrintPreviewControl
3946                 public override int PrintPreviewControlPadding {
3947                         get { return 8; }
3948                 }
3949
3950                 public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview)
3951                 {
3952                         int page_width, page_height;
3953                         int padding = PrintPreviewControlPadding;
3954                         PreviewPageInfo[] pis = preview.page_infos;
3955
3956                         if (preview.AutoZoom) {
3957                                 int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding;
3958                                 int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding;
3959
3960                                 float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height;
3961
3962                                 /* try to lay things out using the width to determine the size */
3963                                 page_width = width_available / preview.Columns;
3964                                 page_height = (int)(page_width / image_ratio);
3965
3966                                 /* does the height fit? */
3967                                 if (page_height * (preview.Rows + 1) > height_available) {
3968                                         /* no, lay things out via the height */
3969                                         page_height = height_available / (preview.Rows + 1);
3970                                         page_width = (int)(page_height * image_ratio);
3971                                 }
3972                         }
3973                         else {
3974                                 page_width = (int)(pis[0].Image.Width * preview.Zoom);
3975                                 page_height = (int)(pis[0].Image.Height * preview.Zoom);
3976                         }
3977
3978                         return new Size (page_width, page_height);
3979                 }
3980
3981                 public override void PrintPreviewControlPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size)
3982                 {
3983                         int padding = 8;
3984                         PreviewPageInfo[] pis = preview.page_infos;
3985                         if (pis == null)
3986                                 return;
3987
3988                         int page_x, page_y;
3989
3990                         int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding;
3991                         int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding;
3992
3993                         Rectangle viewport = preview.ViewPort;
3994
3995                         pe.Graphics.Clip = new Region (viewport);
3996
3997                         /* center things if we can */
3998                         int off_x = viewport.Width / 2 - width / 2;
3999                         if (off_x < 0) off_x = 0;
4000                         int off_y = viewport.Height / 2 - height / 2;
4001                         if (off_y < 0) off_y = 0;
4002
4003                         page_y = off_y + padding - preview.vbar_value;
4004
4005                         if (preview.StartPage > 0) {
4006                                 int p = preview.StartPage - 1;
4007                                 for (int py = 0; py < preview.Rows + 1; py ++) {
4008                                         page_x = off_x + padding - preview.hbar_value;
4009                                         for (int px = 0; px < preview.Columns; px ++) {
4010                                                 if (p >= pis.Length)
4011                                                         continue;
4012                                                 Image image = preview.image_cache[p];
4013                                                 if (image == null)
4014                                                         image = pis[p].Image;
4015                                                 Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size);
4016
4017                                                 pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
4018
4019                                                 page_x += padding + page_size.Width;
4020                                                 p++;
4021                                         }
4022                                         page_y += padding + page_size.Height;
4023                                 }
4024                         }
4025                 }
4026                 #endregion      // PrintPreviewControl
4027
4028                 #region ProgressBar
4029                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) 
4030                 {
4031                         Rectangle client_area = ctrl.client_area;
4032                         
4033                         /* Draw border */
4034                         CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl);
4035                         
4036                         /* Draw Blocks */
4037                         int draw_mode = 0;
4038                         int max_blocks = int.MaxValue;
4039                         int start_pixel = client_area.X;
4040 #if NET_2_0
4041                         draw_mode = (int) ctrl.Style;
4042 #endif
4043                         switch (draw_mode) {
4044 #if NET_2_0
4045                         case 1: { // Continuous
4046                                 int pixels_to_draw;
4047                                 pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1))));
4048                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
4049                                 break;
4050                         }
4051                         case 2: // Marquee
4052                                 if (XplatUI.ThemesEnabled) {
4053                                         int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds;
4054                                         double percent_done = (double) ms_diff % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
4055                                         max_blocks = 5;
4056                                         start_pixel = client_area.X + (int) (client_area.Width * percent_done);
4057                                 }
4058                                 
4059                                 goto case 0;
4060 #endif
4061                         case 0:
4062                         default:  // Blocks
4063                                 Rectangle block_rect;
4064                                 int space_betweenblocks = 2;
4065                                 int block_width;
4066                                 int increment;
4067                                 int barpos_pixels;
4068                                 int block_count = 0;
4069                                 
4070                                 block_width = (client_area.Height * 2) / 3;
4071                                 barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)));
4072                                 increment = block_width + space_betweenblocks;
4073                                 
4074                                 block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
4075                                 while (true) {
4076                                         if (max_blocks != int.MaxValue) {
4077                                                 if (block_count >= max_blocks)
4078                                                         break;
4079                                                 if (block_rect.X > client_area.Width)
4080                                                         block_rect.X -= client_area.Width;
4081                                         } else {
4082                                                 if ((block_rect.X - client_area.X) >= barpos_pixels)
4083                                                         break;
4084                                         }
4085                                         
4086                                         if (clip_rect.IntersectsWith (block_rect) == true) {                            
4087                                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), block_rect);
4088                                         }                               
4089                                         
4090                                         block_rect.X  += increment;
4091                                         block_count++;
4092                                 }
4093                                 break;
4094                         
4095                         }
4096                 }
4097                 
4098                 public override Size ProgressBarDefaultSize {
4099                         get {
4100                                 return new Size (100, 23);
4101                         }
4102                 }
4103
4104                 #endregion      // ProgressBar
4105
4106                 #region RadioButton
4107                 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
4108                         StringFormat    text_format;
4109                         Rectangle       client_rectangle;
4110                         Rectangle       text_rectangle;
4111                         Rectangle       radiobutton_rectangle;
4112                         int             radiobutton_size = 13;
4113                         int     radiobutton_space = 4;
4114
4115                         client_rectangle = radio_button.ClientRectangle;
4116                         text_rectangle = client_rectangle;
4117                         radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
4118
4119                         text_format = new StringFormat();
4120                         text_format.Alignment = StringAlignment.Near;
4121                         text_format.LineAlignment = StringAlignment.Center;
4122                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
4123
4124                         /* Calculate the position of text and checkbox rectangle */
4125                         if (radio_button.appearance!=Appearance.Button) {
4126                                 switch(radio_button.radiobutton_alignment) {
4127                                 case ContentAlignment.BottomCenter: {
4128                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4129                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4130                                         text_rectangle.X=client_rectangle.X;
4131                                         text_rectangle.Width=client_rectangle.Width;
4132                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4133                                         break;
4134                                 }
4135
4136                                 case ContentAlignment.BottomLeft: {
4137                                         radiobutton_rectangle.X=client_rectangle.Left;
4138                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4139                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4140                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;                                 
4141                                         break;
4142                                 }
4143
4144                                 case ContentAlignment.BottomRight: {
4145                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4146                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4147                                         text_rectangle.X=client_rectangle.X;
4148                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4149                                         break;
4150                                 }
4151
4152                                 case ContentAlignment.MiddleCenter: {
4153                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4154                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4155                                         text_rectangle.X=client_rectangle.X;
4156                                         text_rectangle.Width=client_rectangle.Width;
4157                                         break;
4158                                 }
4159
4160                                 default:
4161                                 case ContentAlignment.MiddleLeft: {
4162                                         radiobutton_rectangle.X=client_rectangle.Left;
4163                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4164                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4165                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4166                                         break;
4167                                 }
4168
4169                                 case ContentAlignment.MiddleRight: {
4170                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4171                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4172                                         text_rectangle.X=client_rectangle.X;
4173                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4174                                         break;
4175                                 }
4176
4177                                 case ContentAlignment.TopCenter: {
4178                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4179                                         radiobutton_rectangle.Y=client_rectangle.Top;
4180                                         text_rectangle.X=client_rectangle.X;
4181                                         text_rectangle.Y=radiobutton_size+radiobutton_space;
4182                                         text_rectangle.Width=client_rectangle.Width;
4183                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4184                                         break;
4185                                 }
4186
4187                                 case ContentAlignment.TopLeft: {
4188                                         radiobutton_rectangle.X=client_rectangle.Left;
4189                                         radiobutton_rectangle.Y=client_rectangle.Top;
4190                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4191                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4192                                         break;
4193                                 }
4194
4195                                 case ContentAlignment.TopRight: {
4196                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4197                                         radiobutton_rectangle.Y=client_rectangle.Top;
4198                                         text_rectangle.X=client_rectangle.X;
4199                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4200                                         break;
4201                                 }
4202                                 }
4203                         } else {
4204                                 text_rectangle.X=client_rectangle.X;
4205                                 text_rectangle.Width=client_rectangle.Width;
4206                         }
4207                         
4208                         /* Set the horizontal alignment of our text */
4209                         switch(radio_button.text_alignment) {
4210                                 case ContentAlignment.BottomLeft:
4211                                 case ContentAlignment.MiddleLeft:
4212                                 case ContentAlignment.TopLeft: {
4213                                         text_format.Alignment=StringAlignment.Near;
4214                                         break;
4215                                 }
4216
4217                                 case ContentAlignment.BottomCenter:
4218                                 case ContentAlignment.MiddleCenter:
4219                                 case ContentAlignment.TopCenter: {
4220                                         text_format.Alignment=StringAlignment.Center;
4221                                         break;
4222                                 }
4223
4224                                 case ContentAlignment.BottomRight:
4225                                 case ContentAlignment.MiddleRight:
4226                                 case ContentAlignment.TopRight: {
4227                                         text_format.Alignment=StringAlignment.Far;
4228                                         break;
4229                                 }
4230                         }
4231
4232                         /* Set the vertical alignment of our text */
4233                         switch(radio_button.text_alignment) {
4234                                 case ContentAlignment.TopLeft: 
4235                                 case ContentAlignment.TopCenter: 
4236                                 case ContentAlignment.TopRight: {
4237                                         text_format.LineAlignment=StringAlignment.Near;
4238                                         break;
4239                                 }
4240
4241                                 case ContentAlignment.BottomLeft:
4242                                 case ContentAlignment.BottomCenter:
4243                                 case ContentAlignment.BottomRight: {
4244                                         text_format.LineAlignment=StringAlignment.Far;
4245                                         break;
4246                                 }
4247
4248                                 case ContentAlignment.MiddleLeft:
4249                                 case ContentAlignment.MiddleCenter:
4250                                 case ContentAlignment.MiddleRight: {
4251                                         text_format.LineAlignment=StringAlignment.Center;
4252                                         break;
4253                                 }
4254                         }
4255
4256                         ButtonState state = ButtonState.Normal;
4257                         if (radio_button.FlatStyle == FlatStyle.Flat) {
4258                                 state |= ButtonState.Flat;
4259                         }
4260                         
4261                         if (radio_button.Checked) {
4262                                 state |= ButtonState.Checked;
4263                         }
4264                         
4265                         if (!radio_button.Enabled) {
4266                                 state |= ButtonState.Inactive;
4267                         }
4268
4269                         // Start drawing
4270                         RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
4271                         
4272                         if ((radio_button.image != null) || (radio_button.image_list != null))
4273                                 ButtonBase_DrawImage(radio_button, dc);
4274                         
4275                         RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
4276
4277                         if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) {
4278                                 SizeF text_size = dc.MeasureString (radio_button.Text, radio_button.Font);
4279                                 
4280                                 Rectangle focus_rect = Rectangle.Empty;
4281                                 focus_rect.X = text_rectangle.X;
4282                                 focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
4283                                 focus_rect.Size = text_size.ToSize ();
4284
4285                                 RadioButton_DrawFocus (radio_button, dc, focus_rect);
4286                         }
4287                         
4288                         text_format.Dispose ();
4289                 }
4290
4291                 protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
4292                 {
4293                         dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle);
4294                         
4295                         if (radio_button.appearance==Appearance.Button) {
4296                                 ButtonBase_DrawButton (radio_button, dc);
4297                                 
4298                                 if ((radio_button.Focused) && radio_button.Enabled)
4299                                         ButtonBase_DrawFocus(radio_button, dc);
4300                         } else {
4301                                 // establish if we are rendering a flat style of some sort
4302                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
4303                                         DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
4304                                 } else {
4305                                         CPDrawRadioButton(dc, radiobutton_rectangle, state);
4306                                 }
4307                         }
4308                 }
4309                 
4310                 protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
4311                 {
4312                         DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc, 
4313                                                           text_format, radio_button.Appearance, radio_button.Checked);
4314                 }
4315                 
4316                 protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
4317                 {
4318                         DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
4319                 }
4320                 
4321                 
4322                 // renders a radio button with the Flat and Popup FlatStyle
4323                 protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
4324                 {
4325                         int     lineWidth;
4326                         
4327                         if (radio_button.Enabled) {
4328                                 
4329                                 // draw the outer flatstyle arcs
4330                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
4331                                         graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359);
4332                                         
4333                                         // fill in the area depending on whether or not the mouse is hovering
4334                                         if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) {
4335                                                 graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4336                                         } else {
4337                                                 graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4338                                         }
4339                                 } else {
4340                                         // must be a popup radio button
4341                                         // fill the control
4342                                         graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359);
4343
4344                                         if (radio_button.is_entered || radio_button.Capture) {
4345                                                 // draw the popup 3d button knob
4346                                                 graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
4347
4348                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180);
4349                                                 graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180);
4350                                                 
4351                                         } else {
4352                                                 // just draw lighter flatstyle outer circle
4353                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);                                           
4354                                         }                                                                               
4355                                 }
4356                         } else {
4357                                 // disabled
4358                                 // fill control background color regardless of actual backcolor
4359                                 graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4360                                 // draw the ark as control dark
4361                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4362                         }
4363
4364                         // draw the check
4365                         if (radio_button.Checked) {
4366                                 lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
4367                                 
4368                                 Pen dot_pen = SystemPens.ControlDarkDark;
4369                                 Brush dot_brush = SystemBrushes.ControlDarkDark;
4370
4371                                 if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) {
4372                                         dot_pen = SystemPens.ControlDark;
4373                                         dot_brush = SystemBrushes.ControlDark;
4374                                 } 
4375                                 
4376                                 if (rectangle.Height >  13) {
4377                                         graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
4378                                 } else {
4379                                         int x_half_pos = (rectangle.Width / 2) + rectangle.X;
4380                                         int y_half_pos = (rectangle.Height / 2) + rectangle.Y;
4381                                         
4382                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
4383                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
4384                                         
4385                                         graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
4386                                         graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
4387                                 }
4388                         }
4389                 }
4390
4391                 public override Size RadioButtonDefaultSize {
4392                         get {
4393                                 return new Size (104,24);
4394                         }
4395                 }
4396
4397 #if NET_2_0
4398                 public override void DrawRadioButton (Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
4399                 {
4400                         // Draw Button Background
4401                         if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) {
4402                                 glyphArea.Height -= 2;
4403                                 glyphArea.Width -= 2;
4404                         }
4405                         
4406                         DrawRadioButtonGlyph (g, rb, glyphArea);
4407
4408                         // If we have an image, draw it
4409                         if (imageBounds.Size != Size.Empty)
4410                                 DrawRadioButtonImage (g, rb, imageBounds);
4411
4412                         if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty)
4413                                 DrawRadioButtonFocus (g, rb, textBounds);
4414
4415                         // If we have text, draw it
4416                         if (textBounds != Rectangle.Empty)
4417                                 DrawRadioButtonText (g, rb, textBounds);
4418                 }
4419
4420                 public virtual void DrawRadioButtonGlyph (Graphics g, RadioButton rb, Rectangle glyphArea)
4421                 {
4422                         if (rb.Pressed)
4423                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked);
4424                         else if (rb.InternalSelected)
4425                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4426                         else if (rb.Entered)
4427                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked);
4428                         else if (!rb.Enabled)
4429                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked);
4430                         else
4431                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4432                 }
4433
4434                 public virtual void DrawRadioButtonFocus (Graphics g, RadioButton rb, Rectangle focusArea)
4435                 {
4436                         ControlPaint.DrawFocusRectangle (g, focusArea);
4437                 }
4438
4439                 public virtual void DrawRadioButtonImage (Graphics g, RadioButton rb, Rectangle imageBounds)
4440                 {
4441                         if (rb.Enabled)
4442                                 g.DrawImage (rb.Image, imageBounds);
4443                         else
4444                                 CPDrawImageDisabled (g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
4445                 }
4446
4447                 public virtual void DrawRadioButtonText (Graphics g, RadioButton rb, Rectangle textBounds)
4448                 {
4449                         if (rb.Enabled)
4450                                 TextRenderer.DrawTextInternal (g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4451                         else
4452                                 DrawStringDisabled20 (g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4453                 }
4454
4455                 public override Size CalculateRadioButtonAutoSize (RadioButton rb)
4456                 {
4457                         Size ret_size = Size.Empty;
4458                         Size text_size = TextRenderer.MeasureTextInternal (rb.Text, rb.Font, rb.UseCompatibleTextRendering);
4459                         Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size;
4460
4461                         // Pad the text size
4462                         if (rb.Text.Length != 0) {
4463                                 text_size.Height += 4;
4464                                 text_size.Width += 4;
4465                         }
4466
4467                         switch (rb.TextImageRelation) {
4468                                 case TextImageRelation.Overlay:
4469                                         ret_size.Height = Math.Max (rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
4470                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4471                                         break;
4472                                 case TextImageRelation.ImageAboveText:
4473                                 case TextImageRelation.TextAboveImage:
4474                                         ret_size.Height = text_size.Height + image_size.Height;
4475                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4476                                         break;
4477                                 case TextImageRelation.ImageBeforeText:
4478                                 case TextImageRelation.TextBeforeImage:
4479                                         ret_size.Height = Math.Max (text_size.Height, image_size.Height);
4480                                         ret_size.Width = text_size.Width + image_size.Width;
4481                                         break;
4482                         }
4483
4484                         // Pad the result
4485                         ret_size.Height += (rb.Padding.Vertical);
4486                         ret_size.Width += (rb.Padding.Horizontal) + 15;
4487
4488                         // There seems to be a minimum height
4489                         if (ret_size.Height == rb.Padding.Vertical)
4490                                 ret_size.Height += 14;
4491
4492                         return ret_size;
4493                 }
4494
4495                 public override void CalculateRadioButtonTextAndImageLayout (ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
4496                 {
4497                         CalculateCheckBoxTextAndImageLayout (b, offset, out glyphArea, out textRectangle, out imageRectangle);
4498                 }
4499 #endif
4500                 #endregion      // RadioButton
4501
4502                 #region ScrollBar
4503                 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
4504                 {
4505                         int             scrollbutton_width = bar.scrollbutton_width;
4506                         int             scrollbutton_height = bar.scrollbutton_height;
4507                         Rectangle       first_arrow_area;
4508                         Rectangle       second_arrow_area;                      
4509                         Rectangle       thumb_pos;
4510                         
4511                         thumb_pos = bar.ThumbPos;
4512
4513                         if (bar.vert) {
4514                                 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
4515                                 bar.FirstArrowArea = first_arrow_area;
4516
4517                                 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
4518                                 bar.SecondArrowArea = second_arrow_area;
4519
4520                                 thumb_pos.Width = bar.Width;
4521                                 bar.ThumbPos = thumb_pos;
4522
4523                                 Brush VerticalBrush;
4524                                 /* Background, upper track */
4525                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4526                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4527                                 else
4528                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4529                                 Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom);
4530                                 if (clip.IntersectsWith (UpperTrack))
4531                                         dc.FillRectangle (VerticalBrush, UpperTrack);
4532
4533                                 /* Background, lower track */
4534                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4535                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4536                                 else
4537                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4538                                 Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom);
4539                                 if (clip.IntersectsWith (LowerTrack))
4540                                         dc.FillRectangle (VerticalBrush, LowerTrack);
4541
4542                                 /* Buttons */
4543                                 if (clip.IntersectsWith (first_arrow_area))
4544                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
4545                                 if (clip.IntersectsWith (second_arrow_area))
4546                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
4547                         } else {
4548                                 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
4549                                 bar.FirstArrowArea = first_arrow_area;
4550
4551                                 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
4552                                 bar.SecondArrowArea = second_arrow_area;
4553
4554                                 thumb_pos.Height = bar.Height;
4555                                 bar.ThumbPos = thumb_pos;
4556
4557                                 Brush HorizontalBrush;
4558                                 //Background, left track
4559                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4560                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4561                                 else
4562                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4563                                 Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height);
4564                                 if (clip.IntersectsWith (LeftTrack))
4565                                         dc.FillRectangle (HorizontalBrush, LeftTrack);
4566
4567                                 //Background, right track
4568                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4569                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4570                                 else
4571                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4572                                 Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height);
4573                                 if (clip.IntersectsWith (RightTrack))
4574                                         dc.FillRectangle (HorizontalBrush, RightTrack);
4575
4576                                 /* Buttons */
4577                                 if (clip.IntersectsWith (first_arrow_area))
4578                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
4579                                 if (clip.IntersectsWith (second_arrow_area))
4580                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
4581                         }
4582
4583                         /* Thumb */
4584                         ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);                          
4585                 }
4586
4587                 protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
4588                 {
4589                         if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
4590                                 DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
4591                 }
4592
4593                 public override int ScrollBarButtonSize {
4594                         get { return 16; }
4595                 }
4596
4597                 public override bool ScrollBarHasHotElementStyles {
4598                         get {
4599                                 return false;
4600                         }
4601                 }
4602
4603                 public override bool ScrollBarHasPressedThumbStyle {
4604                         get { 
4605                                 return false;
4606                         }
4607                 }
4608
4609                 public override bool ScrollBarHasHoverArrowButtonStyle {
4610                         get {
4611                                 return false;
4612                         }
4613                 }
4614                 #endregion      // ScrollBar
4615
4616                 #region StatusBar
4617                 public  override void DrawStatusBar (Graphics real_dc, Rectangle clip, StatusBar sb) {
4618                         Rectangle area = sb.ClientRectangle;
4619                         int horz_border = 2;
4620                         int vert_border = 2;
4621
4622                         Image backbuffer = new Bitmap (sb.ClientSize.Width, sb.ClientSize.Height, real_dc);
4623                         Graphics dc = Graphics.FromImage (backbuffer);
4624                         
4625                         DrawStatusBarBackground (dc, clip, sb);
4626                         
4627                         if (!sb.ShowPanels && sb.Text != String.Empty) {
4628                                 string text = sb.Text;
4629                                 StringFormat string_format = new StringFormat ();
4630                                 string_format.Trimming = StringTrimming.Character;
4631                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
4632                                 
4633                                 if (text.Length > 127)
4634                                         text = text.Substring (0, 127);
4635
4636                                 if (text [0] == '\t') {
4637                                         string_format.Alignment = StringAlignment.Center;
4638                                         text = text.Substring (1);
4639                                         if (text [0] == '\t') {
4640                                                 string_format.Alignment = StringAlignment.Far;
4641                                                 text = text.Substring (1);
4642                                         }
4643                                 }
4644                 
4645                                 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
4646                                                 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
4647                                 string_format.Dispose ();
4648                         } else if (sb.ShowPanels) {
4649                                 Brush br_forecolor = GetControlForeBrush (sb.ForeColor);
4650                                 int prev_x = area.X + horz_border;
4651                                 int y = area.Y + vert_border;
4652                                 for (int i = 0; i < sb.Panels.Count; i++) {
4653                                         Rectangle pr = new Rectangle (prev_x, y,
4654                                                 sb.Panels [i].Width, area.Height);
4655                                         prev_x += pr.Width + StatusBarHorzGapWidth;
4656                                         if (pr.IntersectsWith (clip))
4657                                                 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
4658                                 }
4659                         }
4660
4661                         if (sb.SizingGrip)
4662                                 DrawStatusBarSizingGrip (dc, clip, sb, area);
4663                         
4664                         real_dc.DrawImage (backbuffer, 0, 0);
4665                         dc.Dispose ();
4666                         backbuffer.Dispose ();
4667
4668                 }
4669
4670                 protected virtual void DrawStatusBarBackground (Graphics dc, Rectangle clip, StatusBar sb)
4671                 {
4672                         bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
4673
4674                         Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
4675                         dc.FillRectangle (brush, clip);
4676                 }
4677
4678                 protected virtual void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area)
4679                 {
4680                         area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16);
4681                         CPDrawSizeGrip (dc, ColorControl, area);
4682                 }
4683
4684                 protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
4685                         Brush br_forecolor, StatusBarPanel panel) {
4686                         int border_size = 3; // this is actually const, even if the border style is none
4687                         int icon_width = 16;
4688                         
4689                         area.Height -= border_size;
4690
4691                         DrawStatusBarPanelBackground (dc, area, panel);
4692
4693                         if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
4694                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
4695                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
4696                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor);
4697                                 panel.Parent.OnDrawItemInternal (e);
4698                                 return;
4699                         }
4700
4701                         if (panel.Text == String.Empty)
4702                                         return;
4703
4704                         string text = panel.Text;
4705                         StringFormat string_format = new StringFormat ();
4706                         string_format.Trimming = StringTrimming.Character;
4707                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4708
4709                         
4710                         if (text [0] == '\t') {
4711                                 string_format.Alignment = StringAlignment.Center;
4712                                 text = text.Substring (1);
4713                                 if (text [0] == '\t') {
4714                                         string_format.Alignment = StringAlignment.Far;
4715                                         text = text.Substring (1);
4716                                 }
4717                         }
4718
4719                         Rectangle string_rect = Rectangle.Empty;
4720                         int x;
4721                         int len;
4722                         int icon_x = 0;
4723                         int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1;
4724
4725                         switch (panel.Alignment) {
4726                         case HorizontalAlignment.Right:
4727                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4728                                 x = area.Right - len - 4;
4729                                 string_rect = new Rectangle (x, y, 
4730                                                 area.Right - x - border_size,
4731                                                 area.Bottom - y - border_size);
4732                                 if (panel.Icon != null) {
4733                                         icon_x = x - icon_width - 2;
4734                                 }
4735                                 break;
4736                         case HorizontalAlignment.Center:
4737                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4738                                 x = (panel.Width / 2) + (len / 2);
4739                                 string_rect = new Rectangle (x, y, 
4740                                                 area.Right - x - border_size,
4741                                                 area.Bottom - y - border_size);
4742
4743                                 if (panel.Icon != null) {
4744                                         icon_x = x - icon_width - 2;
4745                                 }
4746                                 break;
4747
4748                                 
4749                         default:
4750                                 int left = area.Left + border_size;;
4751                                 if (panel.Icon != null) {
4752                                         icon_x = area.Left + 2;
4753                                         left = icon_x + icon_width + 2;
4754                                 }
4755
4756                                 x = left;
4757                                 string_rect = new Rectangle (x, y, 
4758                                                 area.Right - x - border_size,
4759                                                 area.Bottom - y - border_size);
4760                                 break;
4761                         }
4762
4763                         RectangleF clip_bounds = dc.ClipBounds;
4764                         dc.SetClip (area);
4765                         dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format);                      
4766                         dc.SetClip (clip_bounds);
4767
4768                         if (panel.Icon != null) {
4769                                 dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width));
4770                         }
4771                 }
4772
4773                 protected virtual void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel)
4774                 {
4775                         if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
4776                                 Border3DStyle border_style = Border3DStyle.SunkenOuter;
4777                                 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
4778                                         border_style = Border3DStyle.RaisedInner;
4779                                         
4780                                 CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor);
4781                         }
4782                 }
4783
4784                 public override int StatusBarSizeGripWidth {
4785                         get { return 15; }
4786                 }
4787
4788                 public override int StatusBarHorzGapWidth {
4789                         get { return 3; }
4790                 }
4791
4792                 public override Size StatusBarDefaultSize {
4793                         get {
4794                                 return new Size (100, 22);
4795                         }
4796                 }
4797                 #endregion      // StatusBar
4798
4799                 #region TabControl
4800
4801                 #region TabControl settings
4802
4803                 public override Size TabControlDefaultItemSize {
4804                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultItemSize; }
4805                 }
4806
4807                 public override Point TabControlDefaultPadding {
4808                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultPadding; }
4809                 }
4810
4811                 public override int TabControlMinimumTabWidth {
4812                         get { return ThemeElements.CurrentTheme.TabControlPainter.MinimumTabWidth; }
4813                 }
4814
4815                 public override Rectangle TabControlSelectedDelta {
4816                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedTabDelta; }
4817                 }
4818
4819                 public override int TabControlSelectedSpacing {
4820                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedSpacing; }
4821                 }
4822                 
4823                 public override int TabPanelOffsetX {
4824                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.X; }
4825                 }
4826                 
4827                 public override int TabPanelOffsetY {
4828                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.Y; }
4829                 }
4830
4831                 public override int TabControlColSpacing {
4832                         get { return ThemeElements.CurrentTheme.TabControlPainter.ColSpacing; }
4833                 }
4834
4835                 public override Point TabControlImagePadding {
4836                         get { return ThemeElements.CurrentTheme.TabControlPainter.ImagePadding; }
4837                 }
4838
4839                 public override int TabControlScrollerWidth {
4840                         get {return ThemeElements.CurrentTheme.TabControlPainter.ScrollerWidth; }
4841                 }
4842
4843
4844                 public override Size TabControlGetSpacing (TabControl tab) 
4845                 {
4846                         try {
4847                                 return ThemeElements.CurrentTheme.TabControlPainter.RowSpacing (tab);
4848                         } catch {
4849                                 throw new Exception ("Invalid Appearance value: " + tab.Appearance);
4850                         }
4851                 }
4852                 #endregion
4853
4854                 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
4855                 {
4856                         ThemeElements.CurrentTheme.TabControlPainter.Draw (dc, area, tab);
4857                 }
4858
4859                 public override Rectangle TabControlGetLeftScrollRect (TabControl tab)
4860                 {
4861                         return ThemeElements.CurrentTheme.TabControlPainter.GetLeftScrollRect (tab);
4862                 }
4863
4864                 public override Rectangle TabControlGetRightScrollRect (TabControl tab)
4865                 {
4866                         return ThemeElements.CurrentTheme.TabControlPainter.GetRightScrollRect (tab);
4867                 }
4868
4869                 public override Rectangle TabControlGetDisplayRectangle (TabControl tab)
4870                 {
4871                         return ThemeElements.CurrentTheme.TabControlPainter.GetDisplayRectangle (tab);
4872                 }
4873
4874                 public override Rectangle TabControlGetPanelRect (TabControl tab)
4875                 {
4876                         return ThemeElements.CurrentTheme.TabControlPainter.GetTabPanelRect (tab);
4877                 }
4878
4879                 #endregion
4880
4881                 #region TextBox
4882                 public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea)
4883                 {
4884                         if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) {
4885                                 g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea);
4886                         } else {
4887                                 g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea);
4888                         }
4889                 }
4890
4891                 public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m)
4892                 {
4893                         return false;
4894                 }
4895
4896                 public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase)
4897                 {
4898                         return true;
4899                 }
4900                 #endregion
4901
4902                 #region ToolBar
4903                 public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) 
4904                 {
4905                         StringFormat format = new StringFormat ();
4906                         format.Trimming = StringTrimming.EllipsisCharacter;
4907                         format.LineAlignment = StringAlignment.Center;
4908                         if (control.ShowKeyboardCuesInternal)
4909                                 format.HotkeyPrefix = HotkeyPrefix.Show;
4910                         else
4911                                 format.HotkeyPrefix = HotkeyPrefix.Hide;
4912
4913                         if (control.TextAlign == ToolBarTextAlign.Underneath)
4914                                 format.Alignment = StringAlignment.Center;
4915                         else
4916                                 format.Alignment = StringAlignment.Near;
4917 #if !NET_2_0
4918                         if (control is PropertyGrid.PropertyToolBar) {
4919                                 dc.FillRectangle (ResPool.GetSolidBrush(control.BackColor), clip_rectangle);
4920                                 
4921                                 if (clip_rectangle.X == 0) {
4922                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.X, control.Bottom);
4923                                 }
4924
4925                                 if (clip_rectangle.Y < 2) {
4926                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
4927                                 }
4928
4929                                 if (clip_rectangle.Bottom == control.Bottom) {
4930                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, clip_rectangle.Bottom - 1, clip_rectangle.Right, clip_rectangle.Bottom - 1);
4931                                 }
4932
4933                                 if (clip_rectangle.Right == control.Right) {
4934                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.Right - 1, 1, clip_rectangle.Right - 1, control.Bottom - 1);
4935                                 }
4936                         } else {
4937 #endif
4938                                 if (control.Appearance != ToolBarAppearance.Flat || control.Parent == null) {
4939                                         dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
4940                                 }
4941
4942                                 if (control.Divider && clip_rectangle.Y < 2) {
4943                                         if (clip_rectangle.Y < 1) {
4944                                                 dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
4945                                         }
4946                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
4947                                 }
4948 #if !NET_2_0
4949                         }
4950 #endif
4951
4952                         foreach (ToolBarItem item in control.items)
4953                                 if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
4954                                         DrawToolBarButton (dc, control, item, format);
4955
4956                         format.Dispose ();
4957                 }
4958
4959                 protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
4960                 {
4961                         bool is_flat = (control.Appearance == ToolBarAppearance.Flat);
4962                         
4963                         DrawToolBarButtonBorder (dc, item, is_flat);
4964
4965                         switch (item.Button.Style) {
4966                         case ToolBarButtonStyle.DropDownButton:
4967                                 if (control.DropDownArrows)
4968                                         DrawToolBarDropDownArrow (dc, item, is_flat);
4969                                 DrawToolBarButtonContents (dc, control, item, format);
4970                                 break;
4971
4972                         case ToolBarButtonStyle.Separator:
4973                                 if (is_flat)
4974                                         DrawToolBarSeparator (dc, item);
4975                                 break;
4976
4977                         case ToolBarButtonStyle.ToggleButton:
4978                                 DrawToolBarToggleButtonBackground (dc, item);
4979                                 DrawToolBarButtonContents (dc, control, item, format);
4980                                 break;
4981
4982                         default:
4983                                 DrawToolBarButtonContents (dc, control, item, format);
4984                                 break;
4985                         }
4986                 }
4987
4988                 const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom;
4989
4990                 protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat)
4991                 {
4992                         if (item.Button.Style == ToolBarButtonStyle.Separator)
4993                                 return;
4994
4995                         Border3DStyle style;
4996
4997                         if (is_flat) {
4998                                 if (item.Button.Pushed || item.Pressed)
4999                                         style = Border3DStyle.SunkenOuter;
5000                                 else if (item.Hilight)
5001                                         style = Border3DStyle.RaisedInner;
5002                                 else
5003                                         return;
5004
5005                         } else {
5006                                 if (item.Button.Pushed || item.Pressed)
5007                                         style = Border3DStyle.Sunken;
5008                                 else 
5009                                         style = Border3DStyle.Raised;
5010                         }
5011                         
5012                         Rectangle rect = item.Rectangle;
5013                         if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat)
5014                                 rect.Width -= ToolBarDropDownWidth;
5015
5016                         CPDrawBorder3D (dc, rect, style, all_sides);
5017                 }
5018
5019                 protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item)
5020                 {
5021                         Rectangle area = item.Rectangle;
5022                         int offset = (int) SystemPens.Control.Width + 1;
5023                         dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom);
5024                         dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom);
5025                 }
5026
5027                 protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item)
5028                 {
5029                         Brush brush;
5030                         Rectangle area = item.Rectangle;
5031                         area.X += ToolBarImageGripWidth;
5032                         area.Y += ToolBarImageGripWidth;
5033                         area.Width -= 2 * ToolBarImageGripWidth;
5034                         area.Height -= 2 * ToolBarImageGripWidth;
5035                         
5036                         if (item.Button.Pushed)
5037                                 brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight);
5038                         else if (item.Button.PartialPush)
5039                                 brush = SystemBrushes.ControlLight;
5040                         else
5041                                 brush = SystemBrushes.Control;
5042                          
5043                         dc.FillRectangle (brush, area);
5044                 }
5045
5046                 protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat)
5047                 {
5048                         Rectangle rect = item.Rectangle;
5049                         rect.X = item.Rectangle.Right - ToolBarDropDownWidth;
5050                         rect.Width = ToolBarDropDownWidth;
5051                         
5052                         if (is_flat) {
5053                                 if (item.DDPressed)
5054                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5055                                 else if (item.Button.Pushed || item.Pressed)
5056                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5057                                 else if (item.Hilight)
5058                                         CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides);
5059                         } else {
5060                                 if (item.DDPressed)
5061                                         CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides);
5062                                 else if (item.Button.Pushed || item.Pressed)
5063                                         CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides);
5064                                 else
5065                                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
5066                         }
5067                         
5068                         PointF [] vertices = new PointF [3];
5069                         PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2));
5070                         
5071                         // Increase vertical and horizontal position by 1 when button is pressed
5072                         if (item.Pressed || item.Button.Pushed || item.DDPressed) {
5073                             ddCenter.X += 1;
5074                             ddCenter.Y += 1;
5075                         }
5076                         
5077                         vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5078                         vertices [0].Y = ddCenter.Y;
5079                         vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5080                         vertices [1].Y = ddCenter.Y;
5081                         vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
5082                         vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight;
5083                         dc.FillPolygon (SystemBrushes.ControlText, vertices);
5084                 }
5085
5086                 protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5087                 {
5088                         if (item.Button.Image != null) {
5089                                 int x = item.ImageRectangle.X + ToolBarImageGripWidth;
5090                                 int y = item.ImageRectangle.Y + ToolBarImageGripWidth;
5091                                 
5092                                 // Increase vertical and horizontal position by 1 when button is pressed
5093                                 if (item.Pressed || item.Button.Pushed) {
5094                                     x += 1;
5095                                     y += 1;
5096                                 }
5097                                 
5098                                 if (item.Button.Enabled)
5099                                         dc.DrawImage (item.Button.Image, x, y);
5100                                 else 
5101                                         CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl);
5102                         }
5103
5104                         Rectangle text_rect = item.TextRectangle;
5105                         if (text_rect.Width <= 0 || text_rect.Height <= 0)
5106                                 return;
5107
5108                         if (item.Pressed || item.Button.Pushed) {
5109                                 text_rect.X += 1;
5110                                 text_rect.Y += 1;
5111                         }
5112                         
5113                         if (item.Button.Enabled)
5114                                 dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
5115                         else
5116                                 CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format);
5117                 }
5118
5119                 // Grip width for the ToolBar
5120                 public override int ToolBarGripWidth {
5121                         get { return 2;}
5122                 }
5123
5124                 // Grip width for the Image on the ToolBarButton
5125                 public override int ToolBarImageGripWidth {
5126                         get { return 2;}
5127                 }
5128
5129                 // width of the separator
5130                 public override int ToolBarSeparatorWidth {
5131                         get { return 4; }
5132                 }
5133
5134                 // width of the dropdown arrow rect
5135                 public override int ToolBarDropDownWidth {
5136                         get { return 13; }
5137                 }
5138
5139                 // width for the dropdown arrow on the ToolBarButton
5140                 public override int ToolBarDropDownArrowWidth {
5141                         get { return 5;}
5142                 }
5143
5144                 // height for the dropdown arrow on the ToolBarButton
5145                 public override int ToolBarDropDownArrowHeight {
5146                         get { return 3;}
5147                 }
5148
5149                 public override Size ToolBarDefaultSize {
5150                         get {
5151                                 return new Size (100, 42);
5152                         }
5153                 }
5154
5155                 public override bool ToolBarHasHotElementStyles (ToolBar toolBar)
5156                 {
5157                         return toolBar.Appearance == ToolBarAppearance.Flat;
5158                 }
5159
5160                 public override bool ToolBarHasHotCheckedElementStyles {
5161                         get {
5162                                 return false;
5163                         }
5164                 }
5165                 #endregion      // ToolBar
5166
5167                 #region ToolTip
5168                 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5169                 {
5170                         ToolTipDrawBackground (dc, clip_rectangle, control);
5171
5172                         Rectangle text_rect = Rectangle.Inflate (control.ClientRectangle, -2, -1);
5173 #if NET_2_0
5174                         Color foreground = control.ForeColor;
5175 #else
5176                         Color foreground = this.ColorInfoText;
5177 #endif
5178                         TextFormatFlags flags = TextFormatFlags.HidePrefix | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter;
5179                         TextRenderer.DrawTextInternal (dc, control.Text, control.Font, text_rect, foreground, flags, false);
5180                 }
5181
5182                 protected virtual void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5183                 {
5184 #if NET_2_0
5185                         Brush back_brush = ResPool.GetSolidBrush (control.BackColor);;
5186 #else
5187                         Brush back_brush = SystemBrushes.Info;
5188 #endif
5189                         dc.FillRectangle (back_brush, control.ClientRectangle);
5190                         dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1);
5191                 }
5192
5193                 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text)
5194                 {
5195                         Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false);
5196
5197                         size.Width += 4;
5198                         size.Height += 3;
5199                         
5200                         return size;
5201                 }
5202                 
5203                 public override bool ToolTipTransparentBackground {
5204                         get {
5205                                 return false;
5206                         }
5207                 }
5208                 #endregion      // ToolTip
5209
5210                 #region BalloonWindow
5211 #if NET_2_0
5212                 NotifyIcon.BalloonWindow balloon_window;
5213                 
5214                 public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
5215                 {
5216                         Control control = Control.FromHandle(handle);
5217                         
5218                         if (control == null)
5219                                 return;
5220
5221                         if (balloon_window != null) {
5222                                 balloon_window.Close ();
5223                                 balloon_window.Dispose ();
5224                         }
5225
5226                         balloon_window = new NotifyIcon.BalloonWindow (handle);
5227                         balloon_window.Title = title;
5228                         balloon_window.Text = text;
5229                         balloon_window.Icon = icon;
5230                         balloon_window.Timeout = timeout;
5231                         balloon_window.Show ();
5232                 }
5233
5234                 private const int balloon_iconsize = 16;
5235                 private const int balloon_bordersize = 8; 
5236                 
5237                 public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) 
5238                 {
5239                         Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText);
5240                         Rectangle rect = control.ClientRectangle;
5241                         int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
5242                         
5243                         // Rectangle borders and background.
5244                         dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
5245                         dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1);
5246
5247                         // Icon
5248                         Image image;
5249                         switch (control.Icon) {
5250                                 case ToolTipIcon.Info: {
5251                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
5252                                         break;
5253                                 }
5254
5255                                 case ToolTipIcon.Warning: {
5256                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
5257                                         break;
5258                                 }
5259
5260                                 case ToolTipIcon.Error: {
5261                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
5262                                         break;
5263                                 }
5264                                 
5265                                 default: {
5266                                         image = null;
5267                                         break;
5268                                 }
5269                         }
5270
5271                         if (control.Icon != ToolTipIcon.None)
5272                                 dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize));
5273                         
5274                         // Title
5275                         Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0), 
5276                                                                                                 rect.Y + balloon_bordersize, 
5277                                                                                                 rect.Width - ((3 * balloon_bordersize) + iconsize), 
5278                                                                                                 rect.Height - (2 * balloon_bordersize));
5279                         
5280                         Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
5281                         dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
5282                         
5283                         // Text
5284                         Rectangle textrect = new Rectangle (rect.X + balloon_bordersize, 
5285                                                                                                 rect.Y + balloon_bordersize, 
5286                                                                                                 rect.Width - (2 * balloon_bordersize), 
5287                                                                                                 rect.Height - (2 * balloon_bordersize));
5288
5289                         StringFormat textformat = control.Format;
5290                         textformat.LineAlignment = StringAlignment.Far;
5291                         dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
5292                 }
5293
5294                 public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
5295                 {
5296                         Rectangle deskrect = Screen.GetWorkingArea (control);
5297                         SizeF maxsize = new SizeF (250, 200);
5298
5299                         SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
5300                         SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
5301                         
5302                         if (titlesize.Height < balloon_iconsize)
5303                                 titlesize.Height = balloon_iconsize;
5304                         
5305                         Rectangle rect = new Rectangle ();
5306                         rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
5307                         rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize);
5308                         rect.X = deskrect.Width - rect.Width - 2;
5309                         rect.Y = deskrect.Height - rect.Height - 2;
5310                         
5311                         return rect;
5312                 }
5313 #endif
5314                 #endregion      // BalloonWindow
5315
5316                 #region TrackBar
5317                 public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb)
5318                 {
5319                         int result = tb.Value;
5320                         int value_pos = tb.Value;
5321                         float pixels_betweenticks;
5322                         Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty;
5323                         Point channel_startpoint = Point.Empty, na_point = Point.Empty;
5324                         
5325                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point);
5326                         
5327                         /* Convert thumb position from mouse position to value*/
5328                         if (tb.Orientation == Orientation.Vertical) {
5329                                 value_pos = (int)Math.Round (((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0);
5330
5331                                 if (value_pos + tb.Minimum > tb.Maximum)
5332                                         value_pos = tb.Maximum - tb.Minimum;
5333                                 else if (value_pos + tb.Minimum < tb.Minimum)
5334                                         value_pos = 0;
5335
5336                                 result = value_pos + tb.Minimum;
5337                         } else {
5338                                 value_pos = (int)Math.Round (((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float) pixels_betweenticks), 0);
5339
5340                                 if (value_pos + tb.Minimum > tb.Maximum)
5341                                         value_pos = tb.Maximum - tb.Minimum;
5342                                 else if (value_pos + tb.Minimum < tb.Minimum)
5343                                         value_pos = 0;
5344
5345                                 result = value_pos + tb.Minimum;
5346                         }
5347                         
5348                         return result;
5349                 }
5350                 
5351                 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)
5352                 {
5353                         thumb_area = Rectangle.Empty;
5354                         thumb_pos = Rectangle.Empty;
5355                         
5356                         if (tb.Orientation == Orientation.Vertical) {
5357                                 toptick_startpoint = new Point ();
5358                                 bottomtick_startpoint = new Point ();
5359                                 channel_startpoint = new Point ();
5360                                 float pixel_len;
5361                                 const int space_from_right = 8;
5362                                 const int space_from_left = 8;
5363                                 const int space_from_bottom = 11;
5364                                 Rectangle area = tb.ClientRectangle;
5365
5366                                 switch (tb.TickStyle) {
5367                                 case TickStyle.BottomRight:
5368                                 case TickStyle.None:
5369                                         channel_startpoint.Y = 8;
5370                                         channel_startpoint.X = 9;
5371                                         bottomtick_startpoint.Y = 13;
5372                                         bottomtick_startpoint.X = 24;
5373                                         break;
5374                                 case TickStyle.TopLeft:
5375                                         channel_startpoint.Y = 8;
5376                                         channel_startpoint.X = 19;
5377                                         toptick_startpoint.Y = 13;
5378                                         toptick_startpoint.X = 8;
5379                                         break;
5380                                 case TickStyle.Both:
5381                                         channel_startpoint.Y = 8;
5382                                         channel_startpoint.X = 18;
5383                                         bottomtick_startpoint.Y = 13;
5384                                         bottomtick_startpoint.X = 32;
5385                                         toptick_startpoint.Y = 13;
5386                                         toptick_startpoint.X = 8;
5387                                         break;
5388                                 default:
5389                                         break;
5390                                 }
5391
5392                                 thumb_area.X = area.X + channel_startpoint.X;
5393                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5394                                 thumb_area.Height = area.Height - space_from_right - space_from_left;
5395                                 thumb_area.Width = 4;
5396
5397                                 pixel_len = thumb_area.Height - 11;
5398                                 if (tb.Maximum == tb.Minimum) {
5399                                         pixels_betweenticks = 0;
5400                                 } else {
5401                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5402                                 }
5403
5404                                 thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum));
5405                         } else {        
5406                                 toptick_startpoint = new Point ();
5407                                 bottomtick_startpoint = new Point ();
5408                                 channel_startpoint = new Point ();
5409                                 float pixel_len;
5410                                 const int space_from_right = 8;
5411                                 const int space_from_left = 8;
5412                                 Rectangle area = tb.ClientRectangle;
5413                                                         
5414                                 switch (tb.TickStyle) {
5415                                 case TickStyle.BottomRight:
5416                                 case TickStyle.None:
5417                                         channel_startpoint.X = 8;
5418                                         channel_startpoint.Y = 9;
5419                                         bottomtick_startpoint.X = 13;
5420                                         bottomtick_startpoint.Y = 24;                           
5421                                         break;
5422                                 case TickStyle.TopLeft:
5423                                         channel_startpoint.X = 8;
5424                                         channel_startpoint.Y = 19;
5425                                         toptick_startpoint.X = 13;
5426                                         toptick_startpoint.Y = 8;
5427                                         break;
5428                                 case TickStyle.Both:
5429                                         channel_startpoint.X = 8;
5430                                         channel_startpoint.Y = 18;      
5431                                         bottomtick_startpoint.X = 13;
5432                                         bottomtick_startpoint.Y = 32;                           
5433                                         toptick_startpoint.X = 13;
5434                                         toptick_startpoint.Y = 8;                               
5435                                         break;
5436                                 default:
5437                                         break;
5438                                 }
5439                                                         
5440                                 thumb_area.X = area.X + channel_startpoint.X;
5441                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5442                                 thumb_area.Width = area.Width - space_from_right - space_from_left;
5443                                 thumb_area.Height = 4;
5444
5445                                 pixel_len = thumb_area.Width - 11;
5446                                 if (tb.Maximum == tb.Minimum) {
5447                                         pixels_betweenticks = 0;
5448                                 } else {
5449                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5450                                 }
5451
5452                                 thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum));
5453                         }
5454
5455                         thumb_pos.Size = TrackBarGetThumbSize (tb);
5456                 }
5457
5458                 protected virtual Size TrackBarGetThumbSize (TrackBar trackBar)
5459                 {
5460                         /* Draw thumb fixed 10x22 size */
5461                         return new Size (10, 22);
5462                 }
5463
5464                 #region Ticks
5465                 protected interface ITrackBarTickPainter
5466                 {
5467                         void Paint (float x1, float y1, float x2, float y2);
5468                 }
5469
5470                 class TrackBarTickPainter : ITrackBarTickPainter
5471                 {
5472                         readonly Graphics g;
5473                         readonly Pen pen;
5474                         public TrackBarTickPainter (Graphics g, Pen pen)
5475                         {
5476                                 this.g = g;
5477                                 this.pen = pen;
5478                         }
5479                         public void Paint (float x1, float y1, float x2, float y2)
5480                         {
5481                                 g.DrawLine (pen, x1, y1, x2, y2);
5482                         }
5483                 }
5484                 protected virtual ITrackBarTickPainter GetTrackBarTickPainter (Graphics g)
5485                 {
5486                         return new TrackBarTickPainter (g, ResPool.GetPen (pen_ticks_color));
5487                 }
5488                 #endregion
5489
5490                 #region DrawTrackBar_Vertical
5491                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5492                         ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
5493                         float ticks, int value_pos, bool mouse_value) {                 
5494
5495                         Point toptick_startpoint = new Point ();
5496                         Point bottomtick_startpoint = new Point ();
5497                         Point channel_startpoint = new Point ();
5498                         float pixel_len;
5499                         float pixels_betweenticks;
5500                         Rectangle area = tb.ClientRectangle;
5501                         
5502                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5503
5504                         #region Track
5505                         TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5506                         #endregion
5507
5508                         #region Thumb
5509                         switch (tb.TickStyle)   {
5510                         case TickStyle.BottomRight:
5511                         case TickStyle.None:
5512                                 thumb_pos.X = channel_startpoint.X - 8;
5513                                 TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5514                                 break;
5515                         case TickStyle.TopLeft:
5516                                 thumb_pos.X = channel_startpoint.X - 10;
5517                                 TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5518                                 break;
5519                         default:
5520                                 thumb_pos.X = area.X + 10;
5521                                 TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5522                                 break;
5523                         }
5524                         #endregion
5525
5526                         pixel_len = thumb_area.Height - 11;
5527                         pixels_betweenticks = pixel_len / ticks;
5528                         
5529                         thumb_area.X = thumb_pos.X;
5530                         thumb_area.Y = channel_startpoint.Y;
5531                         thumb_area.Width = thumb_pos.Height;
5532
5533                         #region Ticks
5534                         if (pixels_betweenticks <= 0)
5535                                 return;
5536                         if (tb.TickStyle == TickStyle.None)
5537                                 return;
5538                         Region outside = new Region (area);
5539                         outside.Exclude (thumb_area);                   
5540                         
5541                         if (outside.IsVisible (clip_rectangle)) {
5542                                 ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter (dc);
5543
5544                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5545                                         float x = area.X + bottomtick_startpoint.X;
5546                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks)    {
5547                                                 float y = area.Y + bottomtick_startpoint.Y + inc;
5548                                                 tick_painter.Paint (
5549                                                         x, y,
5550                                                         x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y);
5551                                         }
5552                                 }
5553
5554                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5555                                         float x = area.X + toptick_startpoint.X; 
5556                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
5557                                                 float y = area.Y + toptick_startpoint.Y + inc;
5558                                                 tick_painter.Paint (
5559                                                         x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y,
5560                                                         x, y);
5561                                         }                       
5562                                 }
5563                         }
5564                         
5565                         outside.Dispose ();
5566                         #endregion
5567                 }
5568
5569                 #region Track
5570                 protected virtual void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5571                 {
5572                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5573                                 1, thumb_area.Height);
5574
5575                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y,
5576                                 1, thumb_area.Height);
5577
5578                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y,
5579                                 1, thumb_area.Height);
5580                 }
5581                 #endregion
5582
5583                 #region Thumb
5584                 protected virtual void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5585                 {
5586                         Pen pen = SystemPens.ControlLightLight;
5587                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10);
5588                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
5589                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
5590
5591                         pen = SystemPens.ControlDark;
5592                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9);
5593                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4);
5594
5595                         pen = SystemPens.ControlDarkDark;
5596                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10);
5597                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5);
5598
5599                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
5600                         dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
5601                         dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
5602                         dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
5603                 }
5604
5605                 protected virtual void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5606                 {
5607                         Pen pen = SystemPens.ControlLightLight;
5608                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
5609                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
5610
5611                         pen = SystemPens.ControlDark;
5612                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9);
5613                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5);
5614                         dc.DrawLine (pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1);
5615
5616                         pen = SystemPens.ControlDarkDark;
5617                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10);
5618                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5);
5619                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10);
5620
5621                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
5622                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
5623                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
5624                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
5625                 }
5626
5627                 protected virtual void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5628                 {
5629                         Pen pen = SystemPens.ControlLightLight;
5630                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
5631                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
5632
5633                         pen = SystemPens.ControlDark;
5634                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9);
5635                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8);
5636
5637                         pen = SystemPens.ControlDarkDark;
5638                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10);
5639                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9);
5640
5641                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
5642                 }
5643                 #endregion
5644
5645                 #region Ticks
5646                 protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g)
5647                 {
5648                         return GetTrackBarTickPainter (g);
5649                 }
5650                 #endregion
5651                 #endregion
5652
5653                 #region DrawTrackBar_Horizontal
5654                 /* 
5655                         Horizontal trackbar 
5656                   
5657                         Does not matter the size of the control, Win32 always draws:
5658                                 - Ticks starting from pixel 13, 8
5659                                 - Channel starting at pos 8, 19 and ends at Width - 8
5660                                 - Autosize makes always the control 45 pixels high
5661                                 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
5662                                 
5663                 */
5664                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5665                         ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5666                         float ticks, int value_pos, bool mouse_value) {                 
5667                         Point toptick_startpoint = new Point ();
5668                         Point bottomtick_startpoint = new Point ();
5669                         Point channel_startpoint = new Point ();
5670                         float pixel_len;
5671                         float pixels_betweenticks;
5672                         Rectangle area = tb.ClientRectangle;
5673                         
5674                         GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5675
5676                         #region Track
5677                         TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5678                         #endregion
5679
5680                         #region Thumb
5681                         switch (tb.TickStyle) {
5682                         case TickStyle.BottomRight:
5683                         case TickStyle.None:
5684                                 thumb_pos.Y = channel_startpoint.Y - 8;
5685                                 TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5686                                 break;
5687                         case TickStyle.TopLeft:
5688                                 thumb_pos.Y = channel_startpoint.Y - 10;
5689                                 TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5690                                 break;
5691                         default:
5692                                 thumb_pos.Y = area.Y + 10;
5693                                 TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5694                                 break;
5695                         }
5696                         #endregion
5697
5698                         pixel_len = thumb_area.Width - 11;
5699                         pixels_betweenticks = pixel_len / ticks;
5700
5701                         thumb_area.Y = thumb_pos.Y;
5702                         thumb_area.X = channel_startpoint.X;
5703                         thumb_area.Height = thumb_pos.Height;
5704                         #region Ticks
5705                         if (pixels_betweenticks <= 0)
5706                                 return;
5707                         if (tb.TickStyle == TickStyle.None)
5708                                 return;
5709                         Region outside = new Region (area);
5710                         outside.Exclude (thumb_area);
5711
5712                         if (outside.IsVisible (clip_rectangle)) {
5713                                 ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter (dc);
5714
5715                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5716                                         float y = area.Y + bottomtick_startpoint.Y;
5717                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5718                                                 float x = area.X + bottomtick_startpoint.X + inc;
5719                                                 tick_painter.Paint (
5720                                                         x, y, 
5721                                                         x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2));
5722                                         }
5723                                 }
5724
5725                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5726                                         float y = area.Y + toptick_startpoint.Y;
5727                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5728                                                 float x = area.X + toptick_startpoint.X + inc;
5729                                                 tick_painter.Paint (
5730                                                         x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2), 
5731                                                         x, y);
5732                                         }                       
5733                                 }
5734                         }
5735                         
5736                         outside.Dispose ();
5737                         #endregion
5738                 }
5739
5740                 #region Track
5741                 protected virtual void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5742                 {
5743                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5744                                 thumb_area.Width, 1);
5745
5746                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1,
5747                                 thumb_area.Width, 1);
5748
5749                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3,
5750                                 thumb_area.Width, 1);
5751                 }
5752                 #endregion
5753
5754                 #region Thumb
5755                 protected virtual void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5756                 {
5757                         Pen pen = SystemPens.ControlLightLight;
5758                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
5759                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
5760                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
5761
5762                         pen = SystemPens.ControlDark;
5763                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15);
5764                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4);
5765
5766                         pen = SystemPens.ControlDarkDark;
5767                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16);
5768                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5);
5769
5770                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
5771                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
5772                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
5773                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
5774                 }
5775
5776                 protected virtual void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5777                 {
5778                         Pen pen = SystemPens.ControlLightLight;
5779                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
5780                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
5781
5782                         pen = SystemPens.ControlDark;
5783                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
5784                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
5785                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19);
5786
5787                         pen = SystemPens.ControlDarkDark;
5788                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
5789                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1);
5790                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
5791
5792                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
5793                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
5794                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
5795                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
5796                 }
5797
5798                 protected virtual void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5799                 {
5800                         Pen pen = SystemPens.ControlLightLight;
5801                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
5802                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
5803
5804                         pen = SystemPens.ControlDark;
5805                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
5806                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
5807
5808                         pen = SystemPens.ControlDarkDark;
5809                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20);
5810                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
5811
5812                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
5813                 }
5814                 #endregion
5815
5816                 #region Ticks
5817                 protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g)
5818                 {
5819                         return GetTrackBarTickPainter (g);
5820                 }
5821                 #endregion
5822                 #endregion
5823
5824                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) 
5825                 {
5826                         Brush           br_thumb;
5827                         int             value_pos;
5828                         bool            mouse_value;
5829                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
5830                         Rectangle       area;
5831                         Rectangle       thumb_pos = tb.ThumbPos;
5832                         Rectangle       thumb_area = tb.ThumbArea;
5833                         
5834                         if (tb.thumb_pressed) {
5835                                 value_pos = tb.thumb_mouseclick;
5836                                 mouse_value = true;
5837                         } else {
5838                                 value_pos = tb.Value - tb.Minimum;
5839                                 mouse_value = false;
5840                         }
5841
5842                         area = tb.ClientRectangle;
5843
5844                         if (!tb.Enabled) {
5845                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
5846                         } else if (tb.thumb_pressed == true) {
5847                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
5848                         } else {
5849                                 br_thumb = SystemBrushes.Control;
5850                         }
5851
5852                         
5853                         /* Control Background */
5854                         if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
5855                                 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5856                         } else {
5857                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
5858                         }
5859                         
5860                         if (tb.Focused) {
5861                                 CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor);
5862                         }
5863
5864                         if (tb.Orientation == Orientation.Vertical) {
5865                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
5866                                         br_thumb, ticks, value_pos, mouse_value);
5867                         
5868                         } else {
5869                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
5870                                         br_thumb, ticks, value_pos, mouse_value);
5871                         }
5872
5873                         tb.ThumbPos = thumb_pos;
5874                         tb.ThumbArea = thumb_area;
5875                 }
5876
5877                 public override Size TrackBarDefaultSize {
5878                         get {
5879                                 return new Size (104, 42);
5880                         }
5881                 }
5882
5883                 public override bool TrackBarHasHotThumbStyle {
5884                         get {
5885                                 return false;
5886                         }
5887                 }
5888                 #endregion      // TrackBar
5889
5890                 #region UpDownBase
5891                 public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state)
5892                 {
5893                         ControlPaint.DrawScrollButton (g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal);
5894                 }
5895
5896                 public override bool UpDownBaseHasHotButtonStyle {
5897                         get {
5898                                 return false;
5899                         }
5900                 }
5901                 #endregion
5902
5903                 #region VScrollBar
5904                 public override Size VScrollBarDefaultSize {
5905                         get {
5906                                 return new Size (this.ScrollBarButtonSize, 80);
5907                         }
5908                 }
5909                 #endregion      // VScrollBar
5910
5911                 #region TreeView
5912                 public override Size TreeViewDefaultSize {
5913                         get {
5914                                 return new Size (121, 97);
5915                         }
5916                 }
5917
5918                 public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle)
5919                 {
5920                         int height = treeView.ActualItemHeight - 2;
5921                         dc.FillRectangle (ResPool.GetSolidBrush (treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height);
5922                         
5923                         dc.DrawRectangle (SystemPens.ControlDarkDark, x, middle - 4, 8, 8);
5924
5925                         if (node.IsExpanded) {
5926                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); 
5927                         } else {
5928                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
5929                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2);
5930                         }
5931                 }
5932                 #endregion
5933
5934                 #region Managed window
5935                 public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
5936                 {
5937                         if (wm.IsToolWindow && !wm.IsMinimized)
5938                                 return SystemInformation.ToolWindowCaptionHeight;
5939                         if (wm.Form.FormBorderStyle == FormBorderStyle.None)
5940                                 return 0;
5941                         return SystemInformation.CaptionHeight;
5942                 }
5943
5944                 public override int ManagedWindowBorderWidth (InternalWindowManager wm)
5945                 {
5946                         if (wm is ToolWindowManager && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow)
5947                                 return 3;
5948                         else
5949                                 return 4;
5950                 }
5951
5952                 public override int ManagedWindowIconWidth (InternalWindowManager wm)
5953                 {
5954                         return ManagedWindowTitleBarHeight (wm) - 5;
5955                 }
5956
5957                 public override void ManagedWindowSetButtonLocations (InternalWindowManager wm)
5958                 {
5959                         TitleButtons buttons = wm.TitleButtons;
5960                         Form form = wm.form;
5961                         
5962                         buttons.HelpButton.Visible = form.HelpButton;
5963                         
5964                         foreach (TitleButton button in buttons) {
5965                                 button.Visible = false;
5966                         }
5967                         
5968                         switch (form.FormBorderStyle) {
5969                         case FormBorderStyle.None:
5970                                 if (form.WindowState != FormWindowState.Normal)
5971                                         goto case FormBorderStyle.Sizable;
5972                                 break;
5973                         case FormBorderStyle.FixedToolWindow:
5974                         case FormBorderStyle.SizableToolWindow:
5975                                 buttons.CloseButton.Visible = true;
5976                                 if (form.WindowState != FormWindowState.Normal)
5977                                         goto case FormBorderStyle.Sizable;
5978                                 break;
5979                         case FormBorderStyle.FixedSingle:
5980                         case FormBorderStyle.Fixed3D:
5981                         case FormBorderStyle.FixedDialog:
5982                         case FormBorderStyle.Sizable:
5983                                 switch (form.WindowState) {
5984                                         case FormWindowState.Normal:
5985                                                 buttons.MinimizeButton.Visible = true;
5986                                                 buttons.MaximizeButton.Visible = true;
5987                                                 buttons.RestoreButton.Visible = false;
5988                                                 break;
5989                                         case FormWindowState.Maximized:
5990                                                 buttons.MinimizeButton.Visible = true;
5991                                                 buttons.MaximizeButton.Visible = false;
5992                                                 buttons.RestoreButton.Visible = true;
5993                                                 break;
5994                                         case FormWindowState.Minimized:
5995                                                 buttons.MinimizeButton.Visible = false;
5996                                                 buttons.MaximizeButton.Visible = true;
5997                                                 buttons.RestoreButton.Visible = true;
5998                                                 break;
5999                                 }
6000                                 buttons.CloseButton.Visible = true;
6001                                 break;
6002                         }
6003
6004                         int bw = ManagedWindowBorderWidth (wm);
6005                         Size btsize = ManagedWindowButtonSize (wm);
6006                         int btw = btsize.Width;
6007                         int bth = btsize.Height;
6008                         int top = bw + 2;
6009                         int left = form.Width - bw - btw - 2;
6010                         
6011                         if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
6012                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6013                                 left -= 2 + btw;
6014                                 
6015                                 if (buttons.MaximizeButton.Visible) {
6016                                         buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6017                                         left -= 2 + btw;
6018                                 } 
6019                                 if (buttons.RestoreButton.Visible) {
6020                                         buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth);
6021                                         left -= 2 + btw;
6022                                 }
6023
6024                                 buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6025                                 left -= 2 + btw;
6026                         } else if (wm.IsToolWindow) {
6027                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6028                                 left -= 2 + btw;
6029                         }
6030                 }
6031
6032                 public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
6033                 {
6034                         Form form = wm.Form;
6035                         int tbheight = ManagedWindowTitleBarHeight (wm);
6036                         int bdwidth = ManagedWindowBorderWidth (wm);
6037                         Color titlebar_color = Color.FromArgb (255, 10, 36, 106);
6038                         Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240);
6039                         Color color = ThemeEngine.Current.ColorControlDark;
6040                         Color color2 = Color.FromArgb (255, 192, 192, 192);
6041
6042 #if debug
6043                         Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations");
6044                         dc.FillRectangle (Brushes.Black, clip);
6045 #endif
6046                         
6047                         Pen pen = ResPool.GetPen (ColorControl);
6048                         Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
6049                         ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
6050                         // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves
6051                         borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5);
6052                         for (int i = 2; i < bdwidth; i++) {
6053                                 dc.DrawRectangle (pen, borders);
6054                                 borders.Inflate (-1, -1);
6055                         }                               
6056
6057
6058                         bool draw_titlebar_enabled = false;
6059                         if (wm.Form.Parent != null && wm.Form.Parent is Form) {
6060                                 draw_titlebar_enabled = false;
6061                         } else if (wm.IsActive && !wm.IsMaximized) {
6062                                 draw_titlebar_enabled = true;
6063                         }
6064                         if (draw_titlebar_enabled) {
6065                                 color = titlebar_color;
6066                                 color2 = titlebar_color2;
6067                         }
6068
6069                         Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1);
6070
6071                         // HACK: For now always draw the titlebar until we get updates better
6072                         if (tb.Width > 0 && tb.Height > 0) {
6073                                 using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal))
6074                                 {
6075                                         dc.FillRectangle (gradient, tb);
6076                                 }       
6077                         }
6078                         
6079                         // Draw the line just beneath the title bar
6080                         dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth,
6081                                         tbheight + bdwidth - 1, form.Width - bdwidth - 1,
6082                                         tbheight + bdwidth - 1);
6083
6084                         if (!wm.IsToolWindow) {
6085                                 tb.X += 18; // Room for the icon and the buttons
6086                                 tb.Width = (form.Width - 62) - tb.X;
6087                         }
6088
6089                         string window_caption = form.Text;
6090                         window_caption = window_caption.Replace (Environment.NewLine, string.Empty);
6091
6092                         if (window_caption != null && window_caption != string.Empty) {
6093                                 StringFormat format = new StringFormat ();
6094                                 format.FormatFlags = StringFormatFlags.NoWrap;
6095                                 format.Trimming = StringTrimming.EllipsisCharacter;
6096                                 format.LineAlignment = StringAlignment.Center;
6097
6098                                 if (tb.IntersectsWith (clip))
6099                                         dc.DrawString (window_caption, WindowBorderFont,
6100                                                 ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
6101                                                 tb, format);
6102                         }
6103
6104                         if (wm.ShowIcon) {
6105                                 Rectangle icon = ManagedWindowGetTitleBarIconArea (wm);
6106                                 if (icon.IntersectsWith (clip))
6107                                         dc.DrawIcon (form.Icon, icon);
6108                         }
6109                         
6110                         foreach (TitleButton button in wm.TitleButtons.AllButtons) {
6111                                 DrawTitleButton (dc, button, clip);
6112                         }
6113                 }
6114
6115                 public override Size ManagedWindowButtonSize (InternalWindowManager wm)
6116                 {
6117                         int height = ManagedWindowTitleBarHeight (wm);
6118                         if (!wm.IsMaximized && !wm.IsMinimized) {
6119                                 if (wm.IsToolWindow)
6120                                         return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
6121                                                         height - 5);
6122                                 if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6123                                         return Size.Empty;
6124                         } else
6125                                 height = SystemInformation.CaptionHeight;
6126
6127                         return new Size (SystemInformation.CaptionButtonSize.Width - 2,
6128                                         height - 5);
6129                 }
6130
6131                 private void DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip)
6132                 {
6133                         if (!button.Visible) {
6134                                 return;
6135                         }
6136                         
6137                         if (!button.Rectangle.IntersectsWith (clip))
6138                                 return;
6139
6140                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6141
6142                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6143                                         button.Caption, button.State);
6144                 }
6145
6146                 public override Rectangle ManagedWindowGetTitleBarIconArea (InternalWindowManager wm)
6147                 {
6148                         int bw = ManagedWindowBorderWidth (wm);
6149                         return new Rectangle (bw + 3, bw + 2, wm.IconWidth, wm.IconWidth);
6150                 }
6151                 #endregion
6152
6153                 #region ControlPaint
6154                 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
6155                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6156                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6157                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6158                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6159                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6160                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6161                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6162                 }
6163
6164                 public override void CPDrawBorder (Graphics graphics, RectangleF bounds, Color leftColor, int leftWidth,
6165                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6166                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6167                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6168                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6169                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6170                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6171                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6172                 }
6173
6174                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
6175                         CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
6176                 }
6177
6178                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)
6179                 {
6180                         Pen             penTopLeft;
6181                         Pen             penTopLeftInner;
6182                         Pen             penBottomRight;
6183                         Pen             penBottomRightInner;
6184                         Rectangle       rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6185                         bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
6186                         
6187                         if ((style & Border3DStyle.Adjust) != 0) {
6188                                 rect.Y -= 2;
6189                                 rect.X -= 2;
6190                                 rect.Width += 4;
6191                                 rect.Height += 4;
6192                         }
6193                         
6194                         penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color);
6195                         
6196                         CPColor cpcolor = CPColor.Empty;
6197                         
6198                         if (!is_ColorControl)
6199                                 cpcolor = ResPool.GetCPColor (control_color);
6200                         
6201                         switch (style) {
6202                         case Border3DStyle.Raised:
6203                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6204                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6205                                 penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6206                                 break;
6207                         case Border3DStyle.Sunken:
6208                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6209                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6210                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6211                                 break;
6212                         case Border3DStyle.Etched:
6213                                 penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6214                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6215                                 break;
6216                         case Border3DStyle.RaisedOuter:
6217                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6218                                 break;
6219                         case Border3DStyle.SunkenOuter:
6220                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6221                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6222                                 break;
6223                         case Border3DStyle.RaisedInner:
6224                                 penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6225                                 penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6226                                 break;
6227                         case Border3DStyle.SunkenInner:
6228                                 penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6229                                 break;
6230                         case Border3DStyle.Flat:
6231                                 penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6232                                 break;
6233                         case Border3DStyle.Bump:
6234                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6235                                 break;
6236                         default:
6237                                 break;
6238                         }
6239                         
6240                         bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter));
6241                         
6242                         if ((sides & Border3DSide.Middle) != 0) {
6243                                 Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color);
6244                                 graphics.FillRectangle (brush, rect);
6245                         }
6246                         
6247                         if ((sides & Border3DSide.Left) != 0) {
6248                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top);
6249                                 if ((rect.Width > 2) && inner)
6250                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top);
6251                         }
6252                         
6253                         if ((sides & Border3DSide.Top) != 0) {
6254                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top);
6255                                 if ((rect.Height > 2) && inner)
6256                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1);
6257                         }
6258                         
6259                         if ((sides & Border3DSide.Right) != 0) {
6260                                 graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
6261                                 if ((rect.Width > 3) && inner)
6262                                         graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2);
6263                         }
6264                         
6265                         if ((sides & Border3DSide.Bottom) != 0) {
6266                                 graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6267                                 if ((rect.Height > 3) && inner)
6268                                         graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
6269                         }
6270                 }
6271
6272                 public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
6273                 {
6274                         CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight);
6275                 }
6276
6277                 private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)
6278                 {
6279                         // sadly enough, the rectangle gets always filled with a hatchbrush
6280                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6281                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6282                                                                                  ColorControl.G, ColorControl.B),
6283                                                                  ColorControl),
6284                                           rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2);
6285                         
6286                         if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) {
6287                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6288                                 
6289                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6290                         } else
6291                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6292                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6293                         } else
6294                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6295                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6296                                 
6297                                 Pen pen = DarkPen;
6298                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6299                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6300                                 
6301                                 pen = NormalPen;
6302                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6303                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6304                                 
6305                                 pen = LightPen;
6306                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6307                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6308                         } else
6309                         if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) {
6310                                 Pen pen = DarkPen;
6311                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6312                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6313                                 
6314                                 pen = NormalPen;
6315                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6316                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6317                                 
6318                                 pen = LightPen;
6319                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6320                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6321                         } else
6322                         if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) {
6323                                 Pen pen = LightPen;
6324                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6325                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6326                                 
6327                                 pen = NormalPen;
6328                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2);
6329                                 dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3);
6330                                 
6331                                 pen = DarkPen;
6332                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1);
6333                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2);
6334                         }
6335                 }
6336
6337
6338                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
6339                         Rectangle       captionRect;
6340                         int                     lineWidth;
6341
6342                         CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight);
6343
6344                         if (rectangle.Width<rectangle.Height) {
6345                                 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
6346                         } else {
6347                                 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
6348                         }
6349
6350                         if ((state & ButtonState.Pushed)!=0) {
6351                                 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
6352                         }
6353
6354                         /* Make sure we've got at least a line width of 1 */
6355                         lineWidth=Math.Max(1, captionRect.Width/7);
6356
6357                         switch(button) {
6358                         case CaptionButton.Close: {
6359                                 Pen     pen;
6360
6361                                 if ((state & ButtonState.Inactive)!=0) {
6362                                         pen = ResPool.GetSizedPen (ColorControlLight, lineWidth);
6363                                         DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
6364
6365                                         pen = ResPool.GetSizedPen (ColorControlDark, lineWidth);
6366                                         DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
6367                                         return;
6368                                 } else {
6369                                         pen = ResPool.GetSizedPen (ColorControlText, lineWidth);
6370                                         DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
6371                                         return;
6372                                 }
6373                         }
6374
6375                         case CaptionButton.Help:
6376                         case CaptionButton.Maximize:
6377                         case CaptionButton.Minimize:
6378                         case CaptionButton.Restore: {
6379                                 if ((state & ButtonState.Inactive)!=0) {
6380                                         DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
6381
6382                                         DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
6383                                         return;
6384                                 } else {
6385                                         DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
6386                                         return;
6387                                 }
6388                         }
6389                         }
6390                 }
6391
6392                 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
6393                 {
6394                         Pen check_pen = Pens.Black;
6395                         
6396                         Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6397                         
6398                         if ((state & ButtonState.All) == ButtonState.All) {
6399                                 cb_rect.Width -= 2;
6400                                 cb_rect.Height -= 2;
6401                                 
6402                                 dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6403                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6404                                 
6405                                 check_pen = SystemPens.ControlDark;
6406                         } else
6407                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6408                                 cb_rect.Width -= 2;
6409                                 cb_rect.Height -= 2;
6410                                 
6411                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6412                                         dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6413                                 else
6414                                         dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6415                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6416                         } else {
6417                                 cb_rect.Width -= 1;
6418                                 cb_rect.Height -= 1;
6419                                 
6420                                 int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height;
6421                                 
6422                                 int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2);
6423                                 int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2);
6424                                 
6425                                 Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
6426                                 
6427                                 if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) {
6428                                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6429                                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6430                                                                                                  ColorControl.G, ColorControl.B),
6431                                                                                  ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6432                                 } else
6433                                         dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6434                                 
6435                                 Pen pen = SystemPens.ControlDark;
6436                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1);
6437                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y);
6438                                 
6439                                 pen = SystemPens.ControlDarkDark;
6440                                 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2);
6441                                 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1);
6442                                 
6443                                 pen = SystemPens.ControlLightLight;
6444                                 dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom);
6445                                 dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom);
6446                                 
6447                                 // oh boy, matching ms is like fighting against windmills
6448                                 using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
6449                                                                                    Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6450                                                                                                    ColorControl.G, ColorControl.B), ColorControl))) {
6451                                         dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6452                                         dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1);
6453                                 }
6454                                 
6455                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6456                                         check_pen = SystemPens.ControlDark;
6457                         }
6458                         
6459                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6460                                 int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2;
6461                                 
6462                                 if (check_size < 7) {
6463                                         int lineWidth = Math.Max (3, check_size / 3);
6464                                         int Scale = Math.Max (1, check_size / 9);
6465                                         
6466                                         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, 
6467                                                                         check_size, check_size);
6468                                         
6469                                         for (int i = 0; i < lineWidth; i++) {
6470                                                 dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
6471                                                 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);
6472                                         }
6473                                 } else {
6474                                         int lineWidth = Math.Max (3, check_size / 3) + 1;
6475                                         
6476                                         int x_half = cb_rect.Width / 2;
6477                                         int y_half = cb_rect.Height / 2;
6478                                         
6479                                         Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2), 
6480                                                                         check_size, check_size);
6481                                         
6482                                         int gradient_left = check_size / 3;
6483                                         int gradient_right = check_size - gradient_left - 1;
6484                                         
6485                                         
6486                                         for (int i = 0; i < lineWidth; i++) {
6487                                                 dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
6488                                                 dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i  - 1 - gradient_right);
6489                                         }
6490                                 }
6491                         }
6492                 }
6493
6494                 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
6495                         Point[]                 arrow = new Point[3];
6496                         Point                           P1;
6497                         Point                           P2;
6498                         Point                           P3;
6499                         int                             centerX;
6500                         int                             centerY;
6501                         int                             shiftX;
6502                         int                             shiftY;
6503                         Rectangle               rect;
6504
6505                         if ((state & ButtonState.Checked)!=0) {
6506                                 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);                              
6507                         }
6508
6509                         if ((state & ButtonState.Flat)!=0) {
6510                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
6511                         } else {
6512                                 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
6513                                         // this needs to render like a pushed button - jba
6514                                         // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6515                                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6516                                         graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle);
6517                                 } else {
6518                                         CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6519                                 }
6520                         }
6521
6522                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
6523                         centerX=rect.Left+rect.Width/2;
6524                         centerY=rect.Top+rect.Height/2;
6525                         shiftX=Math.Max(1, rect.Width/8);
6526                         shiftY=Math.Max(1, rect.Height/8);
6527
6528                         if ((state & ButtonState.Pushed)!=0) {
6529                                 shiftX++;
6530                                 shiftY++;
6531                         }
6532
6533                         rect.Y-=shiftY;
6534                         centerY-=shiftY;
6535                         P1=new Point(rect.Left, centerY);
6536                         P2=new Point(rect.Right, centerY);
6537                         P3=new Point(centerX, rect.Bottom);
6538
6539                         arrow[0]=P1;
6540                         arrow[1]=P2;
6541                         arrow[2]=P3;
6542                         
6543                         /* Draw the arrow */
6544                         if ((state & ButtonState.Inactive)!=0) {
6545                                 /* Move away from the shadow */
6546                                 arrow[0].X += 1;        arrow[0].Y += 1;
6547                                 arrow[1].X += 1;        arrow[1].Y += 1;
6548                                 arrow[2].X += 1;        arrow[2].Y += 1;
6549                                 
6550                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
6551
6552                                 arrow[0]=P1;
6553                                 arrow[1]=P2;
6554                                 arrow[2]=P3;
6555
6556                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
6557                         } else {
6558                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
6559                         }
6560                 }
6561
6562
6563                 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds)
6564                 {
6565                         Pen                     pen     = Pens.Black;
6566                         Rectangle       rect    = new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);      // Dunno why, but MS does it that way, too
6567                         int                     X;
6568                         int                     Y;
6569                         
6570                         graphics.FillRectangle (SystemBrushes.ControlLightLight, rect);
6571                         graphics.DrawRectangle (pen, rect);
6572                         
6573                         X = rect.X + rect.Width / 2;
6574                         Y = rect.Y + rect.Height / 2;
6575                         
6576                         /* Draw the cross */
6577                         graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2);
6578                         graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y);
6579                         
6580                         /* Draw 'arrows' for vertical lines */
6581                         graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3);
6582                         graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3);
6583                         
6584                         /* Draw 'arrows' for horizontal lines */
6585                         graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1);
6586                         graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1);
6587                 }
6588
6589                 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
6590                         // make a rectange to trace around border of the button
6591                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6592                         
6593                         Color outerColor = foreColor;
6594                         // adjust focus color according to the flatstyle
6595                         if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
6596                                 outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;                              
6597                         }
6598                         
6599                         // draw the outer rectangle
6600                         graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);                  
6601                         
6602                         // draw the inner rectangle                                             
6603                         if (button.FlatStyle == FlatStyle.Popup) {
6604                                 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
6605                         } else {
6606                                 // draw a flat inner rectangle
6607                                 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
6608                                 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));                               
6609                         }
6610                 }
6611                 
6612                 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
6613                 {       
6614                         // make a rectange to trace around border of the button
6615                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6616                         
6617 #if NotUntilCairoIsFixed
6618                         Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6619                         DashStyle oldStyle; // used for caching old penstyle
6620                         Pen pen = ResPool.GetPen (colorBackInverted);
6621
6622                         oldStyle = pen.DashStyle; 
6623                         pen.DashStyle = DashStyle.Dot;
6624
6625                         graphics.DrawRectangle (pen, trace_rectangle);
6626                         pen.DashStyle = oldStyle;
6627 #else
6628                         CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
6629 #endif
6630                 }
6631                                 
6632
6633                 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) 
6634                 {                       
6635                         Rectangle rect = rectangle;
6636                         Pen pen;
6637                         HatchBrush brush;
6638                                 
6639                         if (backColor.GetBrightness () >= 0.5) {
6640                                 foreColor = Color.Transparent;
6641                                 backColor = Color.Black;
6642                                 
6643                         } else {
6644                                 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6645                                 foreColor = Color.Black;
6646                         }
6647                                                 
6648                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
6649                         pen = new Pen (brush, 1);
6650                                                 
6651                         rect.Width--;
6652                         rect.Height--;                  
6653                         
6654                         graphics.DrawRectangle (pen, rect);
6655                         pen.Dispose ();
6656                 }
6657                 
6658                 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled)
6659                 {
6660                         Brush   sb;
6661                         Pen pen;
6662                         
6663                         if (primary == true) {
6664                                 pen = Pens.Black;
6665                                 if (enabled == true) {
6666                                         sb = Brushes.White;
6667                                 } else {
6668                                         sb = SystemBrushes.Control;
6669                                 }
6670                         } else {
6671                                 pen = Pens.White;
6672                                 if (enabled == true) {
6673                                         sb = Brushes.Black;
6674                                 } else {
6675                                         sb = SystemBrushes.Control;
6676                                 }
6677                         }
6678                         graphics.FillRectangle (sb, rectangle);
6679                         graphics.DrawRectangle (pen, rectangle);                        
6680                 }
6681
6682
6683                 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
6684                         Color   foreColor;
6685                         int     h;
6686                         int     b;
6687                         int     s;
6688
6689                         ControlPaint.Color2HBS(backColor, out h, out b, out s);
6690                         
6691                         if (b>127) {
6692                                 foreColor=Color.Black;
6693                         } else {
6694                                 foreColor=Color.White;
6695                         }
6696
6697                         // still not perfect. it seems that ms calculates the position of the first dot or line
6698
6699                         using (Pen pen = new Pen (foreColor)) {
6700                                 pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
6701                                 
6702                                 for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
6703                                         graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
6704                         }
6705                 }
6706
6707                 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
6708                         /*
6709                                 Microsoft seems to ignore the background and simply make
6710                                 the image grayscale. At least when having > 256 colors on
6711                                 the display.
6712                         */
6713                         
6714                         if (imagedisabled_attributes == null) {                         
6715                                 imagedisabled_attributes = new ImageAttributes ();
6716                                 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
6717                                           // This table would create a perfect grayscale image, based on luminance
6718                                           //                            new float[]{0.3f,0.3f,0.3f,0,0},
6719                                           //                            new float[]{0.59f,0.59f,0.59f,0,0},
6720                                           //                            new float[]{0.11f,0.11f,0.11f,0,0},
6721                                           //                            new float[]{0,0,0,1,0,0},
6722                                           //                            new float[]{0,0,0,0,1,0},
6723                                           //                            new float[]{0,0,0,0,0,1}
6724                 
6725                                           // This table generates a image that is grayscaled and then
6726                                           // brightened up. Seems to match MS close enough.
6727                                           new float[]{0.2f,0.2f,0.2f,0,0},
6728                                           new float[]{0.41f,0.41f,0.41f,0,0},
6729                                           new float[]{0.11f,0.11f,0.11f,0,0},
6730                                           new float[]{0.15f,0.15f,0.15f,1,0,0},
6731                                           new float[]{0.15f,0.15f,0.15f,0,1,0},
6732                                           new float[]{0.15f,0.15f,0.15f,0,0,1}
6733                                   });
6734                                   
6735                                  imagedisabled_attributes.SetColorMatrix (colorMatrix);
6736                         }
6737                         
6738                         graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
6739                         
6740                 }
6741
6742
6743                 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
6744                         Pen     penBorder;
6745                         Pen     penInside;
6746
6747                         if (primary) {
6748                                 penBorder = ResPool.GetSizedPen (Color.White, 2);
6749                                 penInside = ResPool.GetPen (Color.Black);
6750                         } else {
6751                                 penBorder = ResPool.GetSizedPen (Color.Black, 2);
6752                                 penInside = ResPool.GetPen (Color.White);
6753                         }
6754                         penBorder.Alignment=PenAlignment.Inset;
6755                         penInside.Alignment=PenAlignment.Inset;
6756
6757                         graphics.DrawRectangle(penBorder, rectangle);
6758                         graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
6759                 }
6760
6761
6762                 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) {
6763                         Rectangle       rect;
6764                         int                     lineWidth;
6765
6766                         if (backColor != Color.Empty)
6767                                 graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle);
6768                                 
6769                         Brush brush = ResPool.GetSolidBrush (color);
6770
6771                         switch(glyph) {
6772                         case MenuGlyph.Arrow: {
6773                                 float height = rectangle.Height * 0.7f;
6774                                 float width  = height / 2.0f;
6775                                 
6776                                 PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f));
6777
6778                                 PointF [] vertices = new PointF [3];
6779                                 vertices [0].X = ddCenter.X;
6780                                 vertices [0].Y = ddCenter.Y - (height / 2.0f);
6781                                 vertices [1].X = ddCenter.X;
6782                                 vertices [1].Y = ddCenter.Y + (height / 2.0f);
6783                                 vertices [2].X = ddCenter.X + width + 0.1f;
6784                                 vertices [2].Y = ddCenter.Y;
6785                                 
6786                                 graphics.FillPolygon (brush, vertices);
6787
6788                                 return;
6789                         }
6790
6791                         case MenuGlyph.Bullet: {
6792                                 
6793                                 lineWidth=Math.Max(2, rectangle.Width/3);
6794                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
6795                                 
6796                                 graphics.FillEllipse(brush, rect);
6797                                 
6798                                 return;
6799                         }
6800
6801                         case MenuGlyph.Checkmark: {
6802                                 
6803                                 Pen pen = ResPool.GetPen (color);
6804                                 lineWidth = Math.Max (2, rectangle.Width / 6);
6805                                 rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2);
6806
6807                                 int Scale = Math.Max (1, rectangle.Width / 12);
6808                                 int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2));
6809
6810                                 for (int i=0; i<lineWidth; i++) {
6811                                         graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i);
6812                                         graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i);
6813                                 }
6814                                 return;
6815                         }
6816                         }
6817
6818                 }
6819
6820                 [MonoTODO]
6821                 public override void CPDrawMixedCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state)
6822                 {
6823                         CPDrawCheckBox (graphics, rectangle, state);
6824                 }
6825
6826                 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
6827                 {
6828                         CPColor cpcolor = ResPool.GetCPColor (ColorControl);
6829                         
6830                         Color dot_color = Color.Black;
6831                         
6832                         Color top_left_outer = Color.Black;
6833                         Color top_left_inner = Color.Black;
6834                         Color bottom_right_outer = Color.Black;
6835                         Color bottom_right_inner = Color.Black;
6836                         
6837                         int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height  * 0.9f) : (int)(rectangle.Width * 0.9f);
6838                         int radius = ellipse_diameter / 2;
6839                         
6840                         Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter);
6841                         
6842                         Brush brush = null;
6843                         
6844                         if ((state & ButtonState.All) == ButtonState.All) {
6845                                 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6846                                                                                                      ColorControl.G, ColorControl.B), ColorControl);
6847                                 dot_color = cpcolor.Dark;
6848                         } else
6849                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6850                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
6851                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
6852                                 else
6853                                         brush = SystemBrushes.ControlLightLight;
6854                         } else {
6855                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
6856                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
6857                                 else
6858                                         brush = SystemBrushes.ControlLightLight;
6859                                 
6860                                 top_left_outer = cpcolor.Dark;
6861                                 top_left_inner = cpcolor.DarkDark;
6862                                 bottom_right_outer = cpcolor.Light;
6863                                 bottom_right_inner = Color.Transparent;
6864                                 
6865                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6866                                         dot_color = cpcolor.Dark;
6867                         }
6868                         
6869                         dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1);
6870                         
6871                         int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f));
6872                         
6873                         dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f);
6874                         dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f);
6875                         dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f);
6876                         
6877                         if (bottom_right_inner != Color.Transparent)
6878                                 dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
6879                         else
6880                                 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)) {
6881                                         dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
6882                                 }
6883                         
6884                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6885                                 int inflate = line_width * 4;
6886                                 Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate);
6887                                 if (rectangle.Height >  13) {
6888                                         tmp.X += 1;
6889                                         tmp.Y += 1;
6890                                         tmp.Height -= 1;
6891                                         dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp);
6892                                 } else {
6893                                         Pen pen = ResPool.GetPen (dot_color);
6894                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2));
6895                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1);
6896                                         
6897                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom);
6898                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom);
6899                                 }
6900                         }
6901                 }
6902
6903                 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
6904
6905                 }
6906
6907
6908                 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
6909
6910                 }
6911
6912
6913                 /* Scroll button: regular button + direction arrow */
6914                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
6915                 {
6916                         DrawScrollButtonPrimitive (dc, area, state);
6917                         
6918                         bool fill_rect = true;
6919                         int offset = 0;
6920                         
6921                         if ((state & ButtonState.Pushed) != 0)
6922                                 offset = 1;
6923                         
6924                         // skip the border
6925                         Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
6926                         
6927                         Point [] arrow = new Point [3];
6928                         for (int i = 0; i < 3; i++)
6929                                 arrow [i] = new Point ();
6930                         
6931                         Pen pen = SystemPens.ControlText;
6932                         
6933                         if ((state & ButtonState.Inactive) != 0) {
6934                                 pen = SystemPens.ControlDark;
6935                         }
6936                         
6937                         switch (type) {
6938                                 default:
6939                                 case ScrollButton.Down:
6940                                         int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
6941                                         int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
6942                                         if (x_middle == 1)
6943                                                 x_middle = 2;
6944                                         
6945                                         int triangle_height;
6946                                         
6947                                         if (rect.Height < 8) {
6948                                                 triangle_height = 2;
6949                                                 fill_rect = false;
6950                                         } else if (rect.Height == 11) {
6951                                                 triangle_height = 3;
6952                                         } else {
6953                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
6954                                         }
6955                                         
6956                                         arrow [0].X = rect.X + x_middle;
6957                                         arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
6958                                         
6959                                         arrow [1].X = arrow [0].X + triangle_height - 1;
6960                                         arrow [1].Y = arrow [0].Y - triangle_height + 1;
6961                                         arrow [2].X = arrow [0].X - triangle_height + 1;
6962                                         arrow [2].Y = arrow [1].Y;
6963                                         
6964                                         dc.DrawPolygon (pen, arrow);
6965                                         
6966                                         if ((state & ButtonState.Inactive) != 0) {
6967                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
6968                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
6969                                         }
6970                                         
6971                                         if (fill_rect) {
6972                                                 for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
6973                                                         dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
6974                                                         arrow [1].X -= 1;
6975                                                         arrow [2].X += 1;
6976                                                 }
6977                                         }
6978                                         break;
6979                                         
6980                                 case ScrollButton.Up:
6981                                         x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
6982                                         y_middle = (int)Math.Round (rect.Height / 2.0f);
6983                                         if (x_middle == 1)
6984                                                 x_middle = 2;
6985                                         
6986                                         if (y_middle == 1)
6987                                                 y_middle = 2;
6988                                         
6989                                         if (rect.Height < 8) {
6990                                                 triangle_height = 2;
6991                                                 fill_rect = false;
6992                                         } else if (rect.Height == 11) {
6993                                                 triangle_height = 3;
6994                                         } else {
6995                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
6996                                         }
6997                                         
6998                                         arrow [0].X = rect.X + x_middle;
6999                                         arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
7000                                         
7001                                         arrow [1].X = arrow [0].X + triangle_height - 1;
7002                                         arrow [1].Y = arrow [0].Y + triangle_height - 1;
7003                                         arrow [2].X = arrow [0].X - triangle_height + 1;
7004                                         arrow [2].Y = arrow [1].Y;
7005                                         
7006                                         dc.DrawPolygon (pen, arrow);
7007                                         
7008                                         if ((state & ButtonState.Inactive) != 0) {
7009                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
7010                                         }
7011                                         
7012                                         if (fill_rect) {
7013                                                 for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
7014                                                         dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
7015                                                         arrow [1].X -= 1;
7016                                                         arrow [2].X += 1;
7017                                                 }
7018                                         }
7019                                         break;
7020                                         
7021                                 case ScrollButton.Left:
7022                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7023                                         if (y_middle == 1)
7024                                                 y_middle = 2;
7025                                         
7026                                         int triangle_width;
7027                                         
7028                                         if (rect.Width < 8) {
7029                                                 triangle_width = 2;
7030                                                 fill_rect = false;
7031                                         } else if (rect.Width == 11) {
7032                                                 triangle_width = 3;
7033                                         } else {
7034                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7035                                         }
7036                                         
7037                                         arrow [0].X = rect.Left + triangle_width - 1;
7038                                         arrow [0].Y = rect.Y + y_middle;
7039                                         
7040                                         if (arrow [0].X - 1 == rect.X)
7041                                                 arrow [0].X += 1;
7042                                         
7043                                         arrow [1].X = arrow [0].X + triangle_width - 1;
7044                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7045                                         arrow [2].X = arrow [1].X;
7046                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7047                                         
7048                                         dc.DrawPolygon (pen, arrow);
7049                                         
7050                                         if ((state & ButtonState.Inactive) != 0) {
7051                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7052                                         }
7053                                         
7054                                         if (fill_rect) {
7055                                                 for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
7056                                                         dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
7057                                                         arrow [1].Y += 1;
7058                                                         arrow [2].Y -= 1;
7059                                                 }
7060                                         }
7061                                         break;
7062                                         
7063                                 case ScrollButton.Right:
7064                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7065                                         if (y_middle == 1)
7066                                                 y_middle = 2;
7067                                         
7068                                         if (rect.Width < 8) {
7069                                                 triangle_width = 2;
7070                                                 fill_rect = false;
7071                                         } else if (rect.Width == 11) {
7072                                                 triangle_width = 3;
7073                                         } else {
7074                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7075                                         }
7076                                         
7077                                         arrow [0].X = rect.Right - triangle_width - 1;
7078                                         arrow [0].Y = rect.Y + y_middle;
7079                                         
7080                                         if (arrow [0].X - 1 == rect.X)
7081                                                 arrow [0].X += 1;
7082                                         
7083                                         arrow [1].X = arrow [0].X - triangle_width + 1;
7084                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7085                                         arrow [2].X = arrow [1].X;
7086                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7087                                         
7088                                         dc.DrawPolygon (pen, arrow);
7089                                         
7090                                         if ((state & ButtonState.Inactive) != 0) {
7091                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7092                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
7093                                         }
7094                                         
7095                                         if (fill_rect) {
7096                                                 for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
7097                                                         dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
7098                                                         arrow [1].Y += 1;
7099                                                         arrow [2].Y -= 1;
7100                                                 }
7101                                         }
7102                                         break;
7103                         }
7104                 }
7105
7106                 public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
7107                         Color backColor) {
7108
7109                 }
7110
7111
7112                 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds)
7113                 {
7114                         Pen pen_dark = ResPool.GetPen(ControlPaint.Dark(backColor));
7115                         Pen pen_light_light = ResPool.GetPen(ControlPaint.LightLight(backColor));
7116                         
7117                         for (int i = 2; i < bounds.Width - 2; i += 4) {
7118                                 dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1);
7119                                 dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i);
7120                                 dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1);
7121                         }
7122                 }
7123
7124                 private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)
7125                 {
7126                         CPColor cpcolor = ResPool.GetCPColor (color);
7127
7128                         layoutRectangle.Offset (1, 1);
7129                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString);
7130
7131                         layoutRectangle.Offset (-1, -1);
7132                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString);
7133                 }
7134
7135                 public  override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)
7136                 {
7137                         CPColor cpcolor = ResPool.GetCPColor (color);
7138                         
7139                         dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight), 
7140                                        new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height),
7141                                        format);
7142                         dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
7143                 }
7144
7145 #if NET_2_0
7146                 public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
7147                 {
7148                         CPColor cpcolor = ResPool.GetCPColor (color);
7149
7150                         layoutRectangle.Offset (1, 1);
7151                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format);
7152
7153                         layoutRectangle.Offset (-1, -1);
7154                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format);
7155                 }
7156
7157                 public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
7158                 {
7159                         graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds);
7160                 }
7161 #endif
7162
7163                 private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY,
7164                         int width, Color color, ButtonBorderStyle style, Border3DSide side) 
7165                 {
7166                         DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY, 
7167                                 width, color, style, side);
7168                 }
7169
7170                 private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY,
7171                         int width, Color color, ButtonBorderStyle style, Border3DSide side) {
7172
7173                         Pen pen = null;
7174
7175                         switch (style) {
7176                         case ButtonBorderStyle.Solid:
7177                         case ButtonBorderStyle.Inset:
7178                         case ButtonBorderStyle.Outset:
7179                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid);
7180                                         break;
7181                         case ButtonBorderStyle.Dashed:
7182                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash);
7183                                         break;
7184                         case ButtonBorderStyle.Dotted:
7185                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot);
7186                                         break;
7187                         default:
7188                         case ButtonBorderStyle.None:
7189                                         return;
7190                         }
7191
7192                         switch(style) {
7193                         case ButtonBorderStyle.Outset: {
7194                                 Color           colorGrade;
7195                                 int             hue, brightness, saturation;
7196                                 int             brightnessSteps;
7197                                 int             brightnessDownSteps;
7198
7199                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7200
7201                                 brightnessDownSteps=brightness/width;
7202                                 if (brightness>127) {
7203                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7204                                 } else {
7205                                         brightnessSteps=(127-brightness)/width;
7206                                 }
7207
7208                                 for (int i=0; i<width; i++) {
7209                                         switch(side) {
7210                                         case Border3DSide.Left: {
7211                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7212                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7213                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7214                                                 break;
7215                                         }
7216
7217                                         case Border3DSide.Right: {
7218                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7219                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7220                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7221                                                 break;
7222                                         }
7223
7224                                         case Border3DSide.Top: {
7225                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7226                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7227                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7228                                                 break;
7229                                         }
7230
7231                                         case Border3DSide.Bottom: {
7232                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7233                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7234                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7235                                                 break;
7236                                         }
7237                                         }
7238                                 }
7239                                 break;
7240                         }
7241
7242                         case ButtonBorderStyle.Inset: {
7243                                 Color           colorGrade;
7244                                 int             hue, brightness, saturation;
7245                                 int             brightnessSteps;
7246                                 int             brightnessDownSteps;
7247
7248                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7249
7250                                 brightnessDownSteps=brightness/width;
7251                                 if (brightness>127) {
7252                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7253                                 } else {
7254                                         brightnessSteps=(127-brightness)/width;
7255                                 }
7256
7257                                 for (int i=0; i<width; i++) {
7258                                         switch(side) {
7259                                         case Border3DSide.Left: {
7260                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7261                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7262                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7263                                                 break;
7264                                         }
7265
7266                                         case Border3DSide.Right: {
7267                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7268                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7269                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7270                                                 break;
7271                                         }
7272
7273                                         case Border3DSide.Top: {
7274                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7275                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7276                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7277                                                 break;
7278                                         }
7279
7280                                         case Border3DSide.Bottom: {
7281                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7282                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7283                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7284                                                 break;
7285                                         }
7286                                         }
7287                                 }
7288                                 break;
7289                         }
7290
7291                                 /*
7292                                         I decided to have the for-loop duplicated for speed reasons;
7293                                         that way we only have to switch once (as opposed to have the
7294                                         for-loop around the switch)
7295                                 */
7296                         default: {
7297                                 switch(side) {
7298                                 case Border3DSide.Left: {
7299                                         for (int i=0; i<width; i++) {
7300                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7301                                         }
7302                                         break;
7303                                 }
7304
7305                                 case Border3DSide.Right: {
7306                                         for (int i=0; i<width; i++) {
7307                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
7308                                         }
7309                                         break;
7310                                 }
7311
7312                                 case Border3DSide.Top: {
7313                                         for (int i=0; i<width; i++) {
7314                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
7315                                         }
7316                                         break;
7317                                 }
7318
7319                                 case Border3DSide.Bottom: {
7320                                         for (int i=0; i<width; i++) {
7321                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
7322                                         }
7323                                         break;
7324                                 }
7325                                 }
7326                                 break;
7327                         }
7328                         }
7329                 }
7330
7331                 /*
7332                         This function actually draws the various caption elements.
7333                         This way we can scale them nicely, no matter what size, and they
7334                         still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
7335                 */
7336
7337                 private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
7338                         switch(button) {
7339                         case CaptionButton.Close: {
7340                                 if (lineWidth<2) {
7341                                         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);
7342                                         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);
7343                                 }
7344
7345                                 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7346                                 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7347                                 return;
7348                         }
7349
7350                         case CaptionButton.Help: {
7351                                 StringFormat    sf = new StringFormat();                                
7352                                 Font                            font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
7353
7354                                 sf.Alignment=StringAlignment.Center;
7355                                 sf.LineAlignment=StringAlignment.Center;
7356
7357
7358                                 graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
7359
7360                                 sf.Dispose();                           
7361                                 font.Dispose();
7362
7363                                 return;
7364                         }
7365
7366                         case CaptionButton.Maximize: {
7367                                 /* Top 'caption bar' line */
7368                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7369                                         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);
7370                                 }
7371
7372                                 /* Left side line */
7373                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7374                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7375                                 }
7376
7377                                 /* Right side line */
7378                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7379                                         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);
7380                                 }
7381
7382                                 /* Bottom line */
7383                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7384                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7385                                 }
7386                                 return;
7387                         }
7388
7389                         case CaptionButton.Minimize: {
7390                                 /* Bottom line */
7391                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7392                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
7393                                 }
7394                                 return;
7395                         }
7396
7397                         case CaptionButton.Restore: {
7398                                 /** First 'window' **/
7399                                 /* Top 'caption bar' line */
7400                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7401                                         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);
7402                                 }
7403
7404                                 /* Left side line */
7405                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7406                                         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);
7407                                 }
7408
7409                                 /* Right side line */
7410                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7411                                         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);
7412                                 }
7413
7414                                 /* Bottom line */
7415                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7416                                         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);
7417                                 }
7418
7419                                 /** Second 'window' **/
7420                                 /* Top 'caption bar' line */
7421                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7422                                         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);
7423                                 }
7424
7425                                 /* Left side line */
7426                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7427                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7428                                 }
7429
7430                                 /* Right side line */
7431                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7432                                         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);
7433                                 }
7434
7435                                 /* Bottom line */
7436                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7437                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7438                                 }
7439
7440                                 return;
7441                         }
7442
7443                         }
7444                 }
7445
7446                 /* Generic scroll button */
7447                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
7448                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
7449                                 dc.FillRectangle (SystemBrushes.Control, area.X + 1,
7450                                         area.Y + 1, area.Width - 2 , area.Height - 2);
7451
7452                                 dc.DrawRectangle (SystemPens.ControlDark, area.X,
7453                                         area.Y, area.Width, area.Height);
7454
7455                                 return;
7456                         }                       
7457         
7458                         Brush sb_control = SystemBrushes.Control;
7459                         Brush sb_lightlight = SystemBrushes.ControlLightLight;
7460                         Brush sb_dark = SystemBrushes.ControlDark;
7461                         Brush sb_darkdark = SystemBrushes.ControlDarkDark;
7462                         
7463                         dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1);
7464                         dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height);
7465
7466                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1);
7467                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1,
7468                                 area.Height - 4);
7469                         
7470                         dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2,
7471                                 area.Width - 2, 1);
7472
7473                         dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1,
7474                                 area.Width , 1);
7475
7476                         dc.FillRectangle (sb_dark, area.X + area.Width - 2,
7477                                 area.Y + 1, 1, area.Height -3);
7478
7479                         dc.FillRectangle (sb_darkdark, area.X + area.Width -1,
7480                                 area.Y, 1, area.Height - 1);
7481
7482                         dc.FillRectangle (sb_control, area.X + 2,
7483                                 area.Y + 2, area.Width - 4, area.Height - 4);
7484                         
7485                 }
7486                 
7487                 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
7488                         switch (border_style){
7489                         case BorderStyle.Fixed3D:
7490                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
7491                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
7492                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width , 
7493                                         area.Y + area.Height - 1);
7494                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, 
7495                                         area.Y + area.Height);
7496
7497                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
7498                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
7499                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
7500                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
7501                                 break;
7502                         case BorderStyle.FixedSingle:
7503                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
7504                                 break;
7505                         case BorderStyle.None:
7506                         default:
7507                                 break;
7508                         }
7509                         
7510                 }
7511                 #endregion      // ControlPaint
7512
7513
7514         } //class
7515 }