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