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