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