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