[runtime] Updates comments.
[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                                         image_list.Draw (dc, icon_rect.Location, idx);
2961                         }
2962
2963                         // draw the item text                   
2964                         // format for the item text
2965                         StringFormat format = new StringFormat ();
2966                         if (control.View == View.SmallIcon || control.View == View.LargeIcon)
2967                                 format.LineAlignment = StringAlignment.Near;
2968                         else
2969                                 format.LineAlignment = StringAlignment.Center;
2970                         if (control.View == View.LargeIcon)
2971                                 format.Alignment = StringAlignment.Center;
2972                         else
2973                                 format.Alignment = StringAlignment.Near;
2974                         
2975                         if (control.LabelWrap && control.View != View.Details && control.View != View.Tile)
2976                                 format.FormatFlags = StringFormatFlags.LineLimit;
2977                         else
2978                                 format.FormatFlags = StringFormatFlags.NoWrap;
2979
2980                         if ((control.View == View.LargeIcon && !item.Focused) || control.View == View.Details || control.View == View.Tile)
2981                                 format.Trimming = StringTrimming.EllipsisCharacter;
2982
2983                         Rectangle highlight_rect = text_rect;
2984                         if (control.View == View.Details) { // Adjustments for Details view
2985                                 Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
2986
2987                                 if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
2988                                         highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
2989                         }
2990
2991                         if (item.Selected && control.Focused)
2992                                 dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
2993                         else if (item.Selected && !control.HideSelection)
2994                                 dc.FillRectangle (SystemBrushes.Control, highlight_rect);
2995                         else
2996                                 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
2997                         
2998                         Brush textBrush =
2999                                 !control.Enabled ? SystemBrushes.ControlLight :
3000                                 (item.Selected && control.Focused) ? SystemBrushes.HighlightText :
3001                                 this.ResPool.GetSolidBrush (item.ForeColor);
3002
3003                         // Tile view renders its Text in a different fashion
3004                         if (control.View == View.Tile && Application.VisualStylesEnabled) {
3005                                 // Item.Text is drawn using its first subitem's bounds
3006                                 dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
3007
3008                                 int count = Math.Min (control.Columns.Count, item.SubItems.Count);
3009                                 for (int i = 1; i < count; i++) {
3010                                         ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
3011                                         if (sub_item.Text == null || sub_item.Text.Length == 0)
3012                                                 continue;
3013
3014                                         Brush itemBrush = item.Selected && control.Focused ? 
3015                                                 SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
3016                                         dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
3017                                 }
3018                         } else
3019                         
3020                         if (item.Text != null && item.Text.Length > 0) {
3021                                 Font font = item.Font;
3022
3023                                 if (control.HotTracking && item.Hot)
3024                                         font = item.HotFont;
3025
3026                                 if (item.Selected && control.Focused)
3027                                         dc.DrawString (item.Text, font, textBrush, highlight_rect, format);
3028                                 else
3029                                         dc.DrawString (item.Text, font, textBrush, text_rect, format);
3030                         }
3031
3032                         if (item.Focused && control.Focused) {                          
3033                                 Rectangle focus_rect = highlight_rect;
3034                                 if (control.FullRowSelect && control.View == View.Details) {
3035                                         int width = 0;
3036                                         foreach (ColumnHeader col in control.Columns)
3037                                                 width += col.Width;
3038                                         focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height);
3039                                 }
3040                                 if (control.ShowFocusCues) {
3041                                         if (item.Selected)
3042                                                 CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight);
3043                                         else
3044                                                 CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor);
3045                                 }
3046                         }
3047
3048                         format.Dispose ();
3049                 }
3050
3051                 protected virtual void DrawListViewSubItems (Graphics dc, ListView control, ListViewItem item)
3052                 {
3053                         int columns_count = control.Columns.Count;
3054                         int count = Math.Min (item.SubItems.Count, columns_count);
3055                         // 0th item already done (in this case)
3056                         for (int i = 1; i < count; i++)
3057                                 DrawListViewSubItem (dc, control, item, i);
3058
3059                         // Fill in selection for remaining columns if Column.Count > SubItems.Count
3060                         Rectangle sub_item_rect = item.GetBounds (ItemBoundsPortion.Label);
3061                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3062                                 for (int index = count; index < columns_count; index++) {
3063                                         ColumnHeader col = control.Columns [index];
3064                                         sub_item_rect.X = col.Rect.X - control.h_marker;
3065                                         sub_item_rect.Width = col.Wd;
3066                                         dc.FillRectangle (control.Focused ? SystemBrushes.Highlight : SystemBrushes.Control, 
3067                                                         sub_item_rect);
3068                                 }
3069                         }
3070                 }
3071
3072                 protected virtual void DrawListViewSubItem (Graphics dc, ListView control, ListViewItem item, int index)
3073                 {
3074                         ListViewItem.ListViewSubItem subItem = item.SubItems [index];
3075                         ColumnHeader col = control.Columns [index];
3076                         StringFormat format = new StringFormat ();
3077                         format.Alignment = col.Format.Alignment;
3078                         format.LineAlignment = StringAlignment.Center;
3079                         format.FormatFlags = StringFormatFlags.NoWrap;
3080                         format.Trimming = StringTrimming.EllipsisCharacter;
3081
3082                         Rectangle sub_item_rect = subItem.Bounds;
3083                         Rectangle sub_item_text_rect = sub_item_rect;
3084                         sub_item_text_rect.X += 3;
3085                         sub_item_text_rect.Width -= ListViewItemPaddingWidth;
3086                                                 
3087                         SolidBrush sub_item_back_br = null;
3088                         SolidBrush sub_item_fore_br = null;
3089                         Font sub_item_font = null;
3090                                                 
3091                         if (item.UseItemStyleForSubItems) {
3092                                 sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
3093                                 sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
3094
3095                                 // Hot tracking for subitems only applies when UseStyle is true
3096                                 if (control.HotTracking && item.Hot)
3097                                         sub_item_font = item.HotFont;
3098                                 else
3099                                         sub_item_font = item.Font;
3100                         } else {
3101                                 sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
3102                                 sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
3103                                 sub_item_font = subItem.Font;
3104                         }
3105                                                 
3106                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
3107                                 Brush bg, text;
3108                                 if (control.Focused) {
3109                                         bg = SystemBrushes.Highlight;
3110                                         text = SystemBrushes.HighlightText;
3111                                 } else {
3112                                         bg = SystemBrushes.Control;
3113                                         text = sub_item_fore_br;
3114                                                         
3115                                 }
3116                                                         
3117                                 dc.FillRectangle (bg, sub_item_rect);
3118                                 if (subItem.Text != null && subItem.Text.Length > 0)
3119                                         dc.DrawString (subItem.Text, sub_item_font,
3120                                                         text, sub_item_text_rect, format);
3121                         } else {
3122                                 dc.FillRectangle (sub_item_back_br, sub_item_rect);
3123                                 if (subItem.Text != null && subItem.Text.Length > 0)
3124                                         dc.DrawString (subItem.Text, sub_item_font,
3125                                                         sub_item_fore_br,
3126                                                         sub_item_text_rect, format);
3127                         }
3128
3129                         format.Dispose ();
3130                 }
3131
3132                 protected virtual bool DrawListViewSubItemOwnerDraw (Graphics dc, ListViewItem item, ListViewItemStates state, int index)
3133                 {
3134                         ListView control = item.ListView;
3135                         ListViewItem.ListViewSubItem subitem = item.SubItems [index];
3136
3137                         DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs (dc, subitem.Bounds, item, 
3138                                         subitem, item.Index, index, control.Columns [index], state);
3139                         control.OnDrawSubItem (args);
3140                         
3141                         return !args.DrawDefault;
3142                 }
3143
3144                 protected virtual void DrawListViewGroupHeader (Graphics dc, ListView control, ListViewGroup group)
3145                 {
3146                         Rectangle text_bounds = group.HeaderBounds;
3147                         Rectangle header_bounds = group.HeaderBounds;
3148                         text_bounds.Offset (8, 0);
3149                         text_bounds.Inflate (-8, 0);
3150                         int text_height = control.Font.Height + 2; // add a tiny padding between the text and the group line
3151
3152                         Font font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
3153                         Brush brush = new LinearGradientBrush (new Point (header_bounds.Left, 0), new Point (header_bounds.Left + ListViewGroupLineWidth, 0), 
3154                                         SystemColors.Desktop, Color.White);
3155                         Pen pen = new Pen (brush);
3156
3157                         StringFormat sformat = new StringFormat ();
3158                         switch (group.HeaderAlignment) {
3159                                 case HorizontalAlignment.Left:
3160                                         sformat.Alignment = StringAlignment.Near;
3161                                         break;
3162                                 case HorizontalAlignment.Center:
3163                                         sformat.Alignment = StringAlignment.Center;
3164                                         break;
3165                                 case HorizontalAlignment.Right:
3166                                         sformat.Alignment = StringAlignment.Far;
3167                                         break;
3168                         }
3169
3170                         sformat.LineAlignment = StringAlignment.Near;
3171                         dc.DrawString (group.Header, font, SystemBrushes.ControlText, text_bounds, sformat);
3172                         dc.DrawLine (pen, header_bounds.Left, header_bounds.Top + text_height, header_bounds.Left + ListViewGroupLineWidth, 
3173                                         header_bounds.Top + text_height);
3174
3175                         sformat.Dispose ();
3176                         font.Dispose ();
3177                         pen.Dispose ();
3178                         brush.Dispose ();
3179                 }
3180
3181                 public override bool ListViewHasHotHeaderStyle {
3182                         get {
3183                                 return false;
3184                         }
3185                 }
3186
3187                 // Sizing
3188                 public override int ListViewGetHeaderHeight (ListView listView, Font font)
3189                 {
3190                         return ListViewGetHeaderHeight (font);
3191                 }
3192
3193                 static int ListViewGetHeaderHeight (Font font)
3194                 {
3195                         return font.Height + 5;
3196                 }
3197
3198                 public static int ListViewGetHeaderHeight ()
3199                 {
3200                         return ListViewGetHeaderHeight (ThemeEngine.Current.DefaultFont);
3201                 }
3202
3203                 public override Size ListViewCheckBoxSize {
3204                         get { return new Size (16, 16); }
3205                 }
3206
3207                 public override int ListViewColumnHeaderHeight {
3208                         get { return 16; }
3209                 }
3210
3211                 public override int ListViewDefaultColumnWidth {
3212                         get { return 60; }
3213                 }
3214
3215                 public override int ListViewVerticalSpacing {
3216                         get { return 22; }
3217                 }
3218
3219                 public override int ListViewEmptyColumnWidth {
3220                         get { return 10; }
3221                 }
3222
3223                 public override int ListViewHorizontalSpacing {
3224                         get { return 4; }
3225                 }
3226
3227                 public override int ListViewItemPaddingWidth {
3228                         get { return 6; }
3229                 }
3230
3231                 public override Size ListViewDefaultSize {
3232                         get { return new Size (121, 97); }
3233                 }
3234
3235                 public override int ListViewGroupHeight { 
3236                         get { return 20; }
3237                 }
3238
3239                 public int ListViewGroupLineWidth {
3240                         get { return 200; }
3241                 }
3242
3243                 public override int ListViewTileWidthFactor {
3244                         get { return 22; }
3245                 }
3246
3247                 public override int ListViewTileHeightFactor {
3248                         get { return 3; }
3249                 }
3250                 #endregion      // ListView
3251                 
3252                 #region Menus
3253                 
3254                 public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
3255                 {
3256                         item.X = x;
3257                         item.Y = y;
3258
3259                         if (item.Visible == false) {
3260                                 item.Width = 0;
3261                                 item.Height = 0;
3262                                 return;
3263                         }
3264
3265                         if (item.Separator == true) {
3266                                 item.Height = SEPARATOR_HEIGHT;
3267                                 item.Width = SEPARATOR_MIN_WIDTH;
3268                                 return;
3269                         }
3270                         
3271                         if (item.MeasureEventDefined) {
3272                                 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
3273                                 item.PerformMeasureItem (mi);
3274                                 item.Height = mi.ItemHeight;
3275                                 item.Width = mi.ItemWidth;
3276                                 return;
3277                         } else {                
3278                                 SizeF size;
3279                                 size =  dc.MeasureString (item.Text, MenuFont, int.MaxValue, string_format_menu_text);
3280                                 item.Width = (int) size.Width;
3281                                 item.Height = (int) size.Height;
3282         
3283                                 if (!menuBar) {
3284                                         if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
3285                                                 item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
3286                                                 size =  dc.MeasureString (" " + item.GetShortCutText (), MenuFont);
3287                                                 item.Width += MENU_TAB_SPACE + (int) size.Width;
3288                                         }
3289         
3290                                         item.Width += 4 + (MenuCheckSize.Width * 2);
3291                                 } else {
3292                                         item.Width += MENU_BAR_ITEMS_SPACE;
3293                                         x += item.Width;
3294                                 }
3295         
3296                                 if (item.Height < MenuHeight)
3297                                         item.Height = MenuHeight;
3298                         }
3299                 }
3300                 
3301                 // Updates the menu rect and returns the height
3302                 public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
3303                 {
3304                         int x = 0;
3305                         int y = 0;
3306                         menu.Height = 0;
3307
3308                         foreach (MenuItem item in menu.MenuItems) {
3309
3310                                 CalcItemSize (dc, item, y, x, true);
3311
3312                                 if (x + item.Width > width) {
3313                                         item.X = 0;
3314                                         y += item.Height;
3315                                         item.Y = y;
3316                                         x = 0;
3317                                 }
3318
3319                                 x += item.Width;
3320                                 item.MenuBar = true;                            
3321
3322                                 if (y + item.Height > menu.Height)
3323                                         menu.Height = item.Height + y;
3324                         }
3325
3326                         menu.Width = width;                                             
3327                         return menu.Height;
3328                 }
3329
3330                 public override void CalcPopupMenuSize (Graphics dc, Menu menu)
3331                 {
3332                         int x = 3;
3333                         int start = 0;
3334                         int i, n, y, max;
3335
3336                         menu.Height = 0;
3337
3338                         while (start < menu.MenuItems.Count) {
3339                                 y = 3;
3340                                 max = 0;
3341                                 for (i = start; i < menu.MenuItems.Count; i++) {
3342                                         MenuItem item = menu.MenuItems [i];
3343
3344                                         if ((i != start) && (item.Break || item.BarBreak))
3345                                                 break;
3346
3347                                         CalcItemSize (dc, item, y, x, false);
3348                                         y += item.Height;
3349
3350                                         if (item.Width > max)
3351                                                 max = item.Width;
3352                                 }
3353
3354                                 // Replace the -1 by the menu width (separators)
3355                                 for (n = start; n < i; n++, start++)
3356                                         menu.MenuItems [n].Width = max;
3357
3358                                 if (y > menu.Height)
3359                                         menu.Height = y;
3360
3361                                 x+= max;
3362                         }
3363
3364                         menu.Width = x;
3365                         
3366                         //space for border
3367                         menu.Width += 2;
3368                         menu.Height += 2;
3369
3370                         menu.Width += SM_CXBORDER;
3371                 menu.Height += SM_CYBORDER;
3372                 }
3373                 
3374                 // Draws a menu bar in a window
3375                 public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
3376                 {
3377                         if (menu.Height == 0)
3378                                 CalcMenuBarSize (dc, menu, rect.Width);
3379
3380                         bool keynav = (menu as MainMenu).tracker.hotkey_active;
3381                         HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
3382                         string_format_menu_menubar_text.HotkeyPrefix = hp;
3383                         string_format_menu_text.HotkeyPrefix = hp;
3384
3385                         rect.Height = menu.Height;
3386                         dc.FillRectangle (SystemBrushes.Menu, rect);
3387                         
3388                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3389                                 MenuItem item = menu.MenuItems [i];
3390                                 Rectangle item_rect = item.bounds;
3391                                 item_rect.X += rect.X;
3392                                 item_rect.Y += rect.Y;
3393                                 item.MenuHeight = menu.Height;
3394                                 item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status)); 
3395                         }       
3396                 }               
3397                 
3398                 protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color)
3399                 {
3400                         Color bg_color;
3401                         if (color.R == 0 && color.G == 0 && color.B == 0)
3402                                 bg_color = Color.White;
3403                         else
3404                                 bg_color = Color.Black;
3405                         
3406                         Bitmap  bmp = new Bitmap (size.Width, size.Height);
3407                         Graphics gr = Graphics.FromImage (bmp);
3408                         Rectangle rect = new Rectangle (Point.Empty, size);
3409                         gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
3410                         CPDrawMenuGlyph (gr, rect, glyph, color, Color.Empty);
3411                         bmp.MakeTransparent (bg_color);
3412                         gr.Dispose ();
3413                         
3414                         return bmp;
3415                 }
3416
3417                 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
3418                 {
3419                         StringFormat string_format;
3420                         Rectangle rect_text = e.Bounds;
3421                         
3422                         if (item.Visible == false)
3423                                 return;
3424
3425                         if (item.MenuBar)
3426                                 string_format = string_format_menu_menubar_text;
3427                         else
3428                                 string_format = string_format_menu_text;
3429
3430                         if (item.Separator == true) {
3431                                 int liney = e.Bounds.Y + (e.Bounds.Height / 2);
3432                                 
3433                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3434                                         e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney);
3435
3436                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3437                                         e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1);
3438
3439                                 return;
3440                         }
3441
3442                         if (!item.MenuBar)
3443                                 rect_text.X += MenuCheckSize.Width;
3444
3445                         if (item.BarBreak) { /* Draw vertical break bar*/
3446                                 Rectangle rect = e.Bounds;
3447                                 rect.Y++;
3448                                 rect.Width = 3;
3449                                 rect.Height = item.MenuHeight - 6;
3450
3451                                 e.Graphics.DrawLine (SystemPens.ControlDark,
3452                                         rect.X, rect.Y , rect.X, rect.Y + rect.Height);
3453
3454                                 e.Graphics.DrawLine (SystemPens.ControlLight,
3455                                         rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
3456                         }                       
3457                         
3458                         Color color_text;
3459                         Color color_back;
3460                         Brush brush_text = null;
3461                         Brush brush_back = null;
3462                         
3463                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) {
3464                                 color_text = ColorHighlightText;
3465                                 color_back = ColorHighlight;
3466                                 brush_text = SystemBrushes.HighlightText;
3467                                 brush_back = SystemBrushes.Highlight;
3468                         } else {
3469                                 color_text = ColorMenuText;
3470                                 color_back = ColorMenu;
3471                                 brush_text = ResPool.GetSolidBrush (ColorMenuText);
3472                                 brush_back = SystemBrushes.Menu;
3473                         }
3474
3475                         /* Draw background */
3476                         if (!item.MenuBar)
3477                                 e.Graphics.FillRectangle (brush_back, e.Bounds);
3478                         
3479                         if (item.Enabled) {
3480                                 e.Graphics.DrawString (item.Text, e.Font,
3481                                         brush_text,
3482                                         rect_text, string_format);
3483                                 
3484                                 if (item.MenuBar) {
3485                                         Border3DStyle border_style = Border3DStyle.Adjust;
3486                                         if ((item.Status & DrawItemState.HotLight) != 0)
3487                                                 border_style = Border3DStyle.RaisedInner;
3488                                         else if ((item.Status & DrawItemState.Selected) != 0)
3489                                                 border_style = Border3DStyle.SunkenOuter;
3490                                         
3491                                         if (border_style != Border3DStyle.Adjust)
3492                                                 CPDrawBorder3D(e.Graphics, e.Bounds, border_style,  Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu);
3493                                 }
3494                         } else {
3495                                 if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3496                                         e.Graphics.DrawString (item.Text, e.Font, Brushes.White, 
3497                                                                new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height),
3498                                                                string_format);
3499
3500                                 }
3501                                 
3502                                 e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format);
3503                         }
3504
3505                         if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
3506                                 string str = item.GetShortCutText ();
3507                                 Rectangle rect = rect_text;
3508                                 rect.X = item.XTab;
3509                                 rect.Width -= item.XTab;
3510
3511                                 if (item.Enabled) {
3512                                         e.Graphics.DrawString (str, e.Font, brush_text, rect, string_format_menu_shortcut);
3513                                 } else {
3514                                         if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
3515                                                 e.Graphics.DrawString (str, e.Font, Brushes.White, 
3516                                                                        new RectangleF(rect.X + 1, rect.Y + 1, rect.Width, rect_text.Height),
3517                                                                        string_format_menu_shortcut);
3518
3519                                         }
3520                                         e.Graphics.DrawString (str, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect, string_format_menu_shortcut);
3521                                 }
3522                         }
3523
3524                         /* Draw arrow */
3525                         if (item.MenuBar == false && (item.IsPopup || item.MdiList)) {
3526
3527                                 int cx = MenuCheckSize.Width;
3528                                 int cy = MenuCheckSize.Height;
3529                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text);
3530                                 
3531                                 if (item.Enabled) {
3532                                         e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
3533                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
3534                                 } else {
3535                                         ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
3536                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
3537                                 }
3538  
3539                                 bmp.Dispose ();
3540                         }
3541
3542                         /* Draw checked or radio */
3543                         if (item.MenuBar == false && item.Checked) {
3544
3545                                 Rectangle area = e.Bounds;
3546                                 int cx = MenuCheckSize.Width;
3547                                 int cy = MenuCheckSize.Height;
3548                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text);
3549
3550                                 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
3551
3552                                 bmp.Dispose ();
3553                         }                       
3554                 }               
3555                         
3556                 public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
3557                 {
3558                         // Fill rectangle area
3559                         dc.FillRectangle (SystemBrushes.Menu, cliparea);
3560                         
3561                         // Draw menu borders
3562                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
3563                         
3564                         // Draw menu items
3565                         for (int i = 0; i < menu.MenuItems.Count; i++) {
3566                                 if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
3567                                         MenuItem item = menu.MenuItems [i];
3568                                         item.MenuHeight = menu.Height;
3569                                         item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status));
3570                                 }
3571                         }
3572                 }
3573                 
3574                 #endregion // Menus
3575
3576                 #region MonthCalendar
3577
3578                 // draw the month calendar
3579                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) 
3580                 {
3581                         Rectangle client_rectangle = mc.ClientRectangle;
3582                         Size month_size = mc.SingleMonthSize;
3583                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3584                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
3585                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3586                         
3587                         // draw the singlecalendars
3588                         int x_offset = 1;
3589                         int y_offset = 1;
3590                         // adjust for the position of the specific month
3591                         for (int i=0; i < mc.CalendarDimensions.Height; i++) 
3592                         {
3593                                 if (i > 0) 
3594                                 {
3595                                         y_offset += month_size.Height + calendar_spacing.Height;
3596                                 }
3597                                 // now adjust for x position    
3598                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) 
3599                                 {
3600                                         if (j > 0) 
3601                                         {
3602                                                 x_offset += month_size.Width + calendar_spacing.Width;
3603                                         } 
3604                                         else 
3605                                         {
3606                                                 x_offset = 1;
3607                                         }
3608
3609                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
3610                                         if (month_rect.IntersectsWith (clip_rectangle)) {
3611                                                 DrawSingleMonth (
3612                                                         dc,
3613                                                         clip_rectangle,
3614                                                         month_rect,
3615                                                         mc,
3616                                                         i,
3617                                                         j);
3618                                         }
3619                                 }
3620                         }
3621                         
3622                         Rectangle bottom_rect = new Rectangle (
3623                                                 client_rectangle.X,
3624                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
3625                                                 client_rectangle.Width,
3626                                                 date_cell_size.Height + 2);
3627                         // draw the today date if it's set
3628                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) 
3629                         {
3630                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect);
3631                                 if (mc.ShowToday) {
3632                                         int today_offset = 5;
3633                                         if (mc.ShowTodayCircle) 
3634                                         {
3635                                                 Rectangle today_circle_rect = new Rectangle (
3636                                                         client_rectangle.X + 5,
3637                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
3638                                                         date_cell_size.Width,
3639                                                         date_cell_size.Height);
3640                                                         DrawTodayCircle (dc, today_circle_rect);
3641                                                 today_offset += date_cell_size.Width + 5;
3642                                         }
3643                                         // draw today's date
3644                                         StringFormat text_format = new StringFormat();
3645                                         text_format.LineAlignment = StringAlignment.Center;
3646                                         text_format.Alignment = StringAlignment.Near;
3647                                         Rectangle today_rect = new Rectangle (
3648                                                         today_offset + client_rectangle.X,
3649                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
3650                                                         Math.Max(client_rectangle.Width - today_offset, 0),
3651                                                         date_cell_size.Height);
3652                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format);
3653                                         text_format.Dispose ();
3654                                 }                               
3655                         }
3656                         
3657                         Brush border_brush;
3658                         
3659                         if (mc.owner == null)
3660                                 border_brush = GetControlBackBrush (mc.BackColor);
3661                         else
3662                                 border_brush = SystemBrushes.ControlDarkDark;
3663                                 
3664                         // finally paint the borders of the calendars as required
3665                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
3666                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
3667                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height);
3668                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
3669                                         dc.FillRectangle (border_brush, client_rectangle.Right - 1, client_rectangle.Y, 1, client_rectangle.Height);
3670                                 } else { 
3671                                         Rectangle rect = new Rectangle (
3672                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
3673                                                 client_rectangle.Y,
3674                                                 calendar_spacing.Width,
3675                                                 client_rectangle.Height);
3676                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3677                                                 dc.FillRectangle (border_brush, rect);
3678                                         }
3679                                 }
3680                         }
3681                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
3682                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
3683                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1);
3684                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
3685                                         dc.FillRectangle (border_brush, client_rectangle.X, client_rectangle.Bottom - 1, client_rectangle.Width, 1);
3686                                 } else { 
3687                                         Rectangle rect = new Rectangle (
3688                                                 client_rectangle.X,
3689                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
3690                                                 client_rectangle.Width,
3691                                                 calendar_spacing.Height);
3692                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3693                                                 dc.FillRectangle (border_brush, rect);
3694                                         }
3695                                 }
3696                         }
3697                         
3698                         // draw the drop down border if need
3699                         if (mc.owner != null) {
3700                                 Rectangle bounds = mc.ClientRectangle;
3701                                 if (clip_rectangle.Contains (mc.Location)) {
3702                                         // find out if top or left line to draw
3703                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3704                                         
3705                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
3706                                         }
3707                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3708                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
3709                                         }
3710                                 }
3711                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
3712                                         // find out if bottom or right line to draw
3713                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3714                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
3715                                         }
3716                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3717                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
3718                                         }
3719                                 }
3720                         }
3721                 }
3722
3723                 // darws a single part of the month calendar (with one month)
3724                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) 
3725                 {
3726                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3727                         Size title_size = (Size)((object)mc.title_size);
3728                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3729                         DateTime current_month = (DateTime)((object)mc.current_month);
3730                         DateTime sunday = new DateTime(2006, 10, 1);
3731                         
3732                         // draw the title back ground
3733                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
3734                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
3735                         if (title_rect.IntersectsWith (clip_rectangle)) {
3736                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
3737                                 // draw the title                               
3738                                 string title_text = this_month.ToString ("MMMM yyyy");
3739                                 dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format);
3740
3741                                 if (mc.ShowYearUpDown) {
3742                                         Rectangle year_rect;
3743                                         Rectangle upRect, downRect;
3744                                         ButtonState upState, downState;
3745                                         
3746                                         mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect);
3747                                         dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect);
3748                                         dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format);
3749                                         
3750                                         upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal;
3751                                         downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal;
3752
3753                                         ControlPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState);
3754                                         ControlPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState);
3755                                 }
3756
3757                                 // draw previous and next buttons if it's time
3758                                 if (row == 0 && col == 0) 
3759                                 {
3760                                         // draw previous button
3761                                         DrawMonthCalendarButton (
3762                                                 dc,
3763                                                 rectangle,
3764                                                 mc,
3765                                                 title_size,
3766                                                 mc.button_x_offset,
3767                                                 (System.Drawing.Size)((object)mc.button_size),
3768                                                 true);
3769                                 }
3770                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) 
3771                                 {
3772                                         // draw next button
3773                                         DrawMonthCalendarButton (
3774                                                 dc,
3775                                                 rectangle,
3776                                                 mc,
3777                                                 title_size,
3778                                                 mc.button_x_offset,
3779                                                 (System.Drawing.Size)((object)mc.button_size),
3780                                                 false);
3781                                 }
3782                         }
3783                         
3784                         // set the week offset and draw week nums if needed
3785                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
3786                         Rectangle day_name_rect = new Rectangle(
3787                                 rectangle.X,
3788                                 rectangle.Y + title_size.Height,
3789                                 (7 + col_offset) * date_cell_size.Width,
3790                                 date_cell_size.Height);
3791                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
3792                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect);
3793                                 // draw the day names 
3794                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
3795                                 for (int i=0; i < 7; i++) 
3796                                 {
3797                                         int position = i - (int) first_day_of_week;
3798                                         if (position < 0) 
3799                                         {
3800                                                 position = 7 + position;
3801                                         }
3802                                         // draw it
3803                                         Rectangle day_rect = new Rectangle(
3804                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
3805                                                 day_name_rect.Y,
3806                                                 date_cell_size.Width,
3807                                                 date_cell_size.Height);
3808                                         dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format);
3809                                 }
3810                                 
3811                                 // draw the vertical divider
3812                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
3813                                 dc.DrawLine (
3814                                         ResPool.GetPen (mc.ForeColor),
3815                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
3816                                         rectangle.Y + vert_divider_y,
3817                                         rectangle.Right - mc.divider_line_offset,
3818                                         rectangle.Y + vert_divider_y);
3819                         }
3820
3821
3822                         // draw the actual date items in the grid (including the week numbers)
3823                         Rectangle date_rect = new Rectangle (
3824                                 rectangle.X,
3825                                 rectangle.Y + title_size.Height + date_cell_size.Height,
3826                                 date_cell_size.Width,
3827                                 date_cell_size.Height);
3828                         int month_row_count = 0;
3829                         bool draw_week_num_divider = false;
3830                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
3831                         for (int i=0; i < 6; i++) 
3832                         {
3833                                 // establish if this row is in our clip_area
3834                                 Rectangle row_rect = new Rectangle (
3835                                         rectangle.X,
3836                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
3837                                         date_cell_size.Width * 7,
3838                                         date_cell_size.Height);
3839                                 if (mc.ShowWeekNumbers) {
3840                                         row_rect.Width += date_cell_size.Width;
3841                                 }
3842                 
3843                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
3844                                 if (draw_row) {
3845                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect);
3846                                 }
3847                                 // establish if this is a valid week to draw
3848                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
3849                                         month_row_count = i;
3850                                 }
3851                                 
3852                                 // draw the week number if required
3853                                 if (mc.ShowWeekNumbers && month_row_count == i) {
3854                                         if (!draw_week_num_divider) {
3855                                                 draw_week_num_divider = draw_row;
3856                                         }
3857                                         // get the week for this row
3858                                         int week = mc.GetWeekOfYear (current_date);     
3859
3860                                         if (draw_row) {
3861                                                 dc.DrawString (
3862                                                         week.ToString(),
3863                                                         mc.Font,
3864                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
3865                                                         date_rect,
3866                                                         mc.centered_format);
3867                                         }
3868                                         date_rect.Offset(date_cell_size.Width, 0);
3869                                 }
3870                                                                 
3871                                 // only draw the days if we have to
3872                                 if(month_row_count == i) {
3873                                         for (int j=0; j < 7; j++) 
3874                                         {
3875                                                 if (draw_row) {
3876                                                         DrawMonthCalendarDate (
3877                                                                 dc,
3878                                                                 date_rect,
3879                                                                 mc,
3880                                                                 current_date,
3881                                                                 this_month,
3882                                                                 row,
3883                                                                 col);
3884                                                 }
3885
3886                                                 // move the day on
3887                                                 current_date = current_date.AddDays(1);
3888                                                 date_rect.Offset(date_cell_size.Width, 0);
3889                                         }
3890
3891                                         // shift the rectangle down one row
3892                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
3893                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
3894                                 }
3895                         }
3896
3897                         // month_row_count is zero based, so add one
3898                         month_row_count++;
3899
3900                         // draw week numbers if required
3901                         if (draw_week_num_divider) {
3902                                 col_offset = 1;
3903                                 dc.DrawLine (
3904                                         ResPool.GetPen (mc.ForeColor),
3905                                         rectangle.X + date_cell_size.Width - 1,
3906                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
3907                                         rectangle.X + date_cell_size.Width - 1,
3908                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
3909                         }
3910                 }
3911
3912                 // draws the pervious or next button
3913                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) 
3914                 {
3915                         const int arrow_width = 4;
3916                         const int arrow_height = 7;
3917
3918                         bool is_clicked = false;
3919                         Rectangle button_rect;
3920                         PointF arrow_center;
3921                         PointF [] arrow_path = new PointF [3];
3922                         
3923                         // prepare the button
3924                         if (is_previous) 
3925                         {
3926                                 is_clicked = mc.is_previous_clicked;
3927
3928                                 button_rect = new Rectangle (
3929                                         rectangle.X + 1 + x_offset,
3930                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3931                                         Math.Max(button_size.Width - 1, 0),
3932                                         Math.Max(button_size.Height - 1, 0));
3933
3934                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3935                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3936                                 if (is_clicked) {
3937                                         arrow_center.X += 1;
3938                                         arrow_center.Y += 1;
3939                                 }
3940
3941                                 arrow_path [0].X = arrow_center.X;
3942                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3943                                 arrow_path [1].X = arrow_center.X;
3944                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3945                                 arrow_path [2].X = arrow_center.X - arrow_width;
3946                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3947                         }
3948                         else
3949                         {
3950                                 is_clicked = mc.is_next_clicked;
3951
3952                                 button_rect = new Rectangle (
3953                                         rectangle.Right - 1 - x_offset - button_size.Width,
3954                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3955                                         Math.Max(button_size.Width - 1, 0),
3956                                         Math.Max(button_size.Height - 1, 0));
3957
3958                                 arrow_center = new PointF (button_rect.X + ((button_rect.Width + arrow_width) / 2.0f), 
3959                                                                                         rectangle.Y + ((button_rect.Height + arrow_height) / 2) + 1);
3960                                 if (is_clicked) {
3961                                         arrow_center.X += 1;
3962                                         arrow_center.Y += 1;
3963                                 }
3964
3965                                 arrow_path [0].X = arrow_center.X - arrow_width;
3966                                 arrow_path [0].Y = arrow_center.Y - arrow_height / 2.0f + 0.5f;
3967                                 arrow_path [1].X = arrow_center.X - arrow_width;
3968                                 arrow_path [1].Y = arrow_center.Y + arrow_height / 2.0f + 0.5f;
3969                                 arrow_path [2].X = arrow_center.X;
3970                                 arrow_path [2].Y = arrow_center.Y + 0.5f;
3971                         }
3972
3973                         // fill the background
3974                         dc.FillRectangle (SystemBrushes.Control, button_rect);
3975                         // draw the border
3976                         if (is_clicked) {
3977                                 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
3978                         }
3979                         else {
3980                                 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
3981                         }
3982                         // draw the arrow
3983                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);                 
3984                         //dc.FillPolygon (SystemBrushes.ControlText, arrow_path, FillMode.Winding);
3985                 }
3986                 
3987
3988                 // draws one day in the calendar grid
3989                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
3990                         Color date_color = mc.ForeColor;
3991                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
3992
3993                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
3994                         if (date.Year != month.Year || date.Month != month.Month) {
3995                                 DateTime check_date = month.AddMonths (-1);
3996                                 // check if it's the month before 
3997                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
3998                                         date_color = mc.TrailingForeColor;
3999                                 } else {
4000                                         // check if it's the month after
4001                                         check_date = month.AddMonths (1);
4002                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
4003                                                 date_color = mc.TrailingForeColor;
4004                                         } else {
4005                                                 return;
4006                                         }
4007                                 }
4008                         } else {
4009                                 date_color = mc.ForeColor;
4010                         }
4011
4012                         const int inflate = -1;
4013
4014                         if (date == mc.SelectionStart.Date && date == mc.SelectionEnd.Date) {
4015                                 // see if the date is in the start of selection
4016                                 date_color = mc.BackColor;
4017                                 // draw the left hand of the back ground
4018                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
4019                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360);
4020                         } else if (date == mc.SelectionStart.Date) {
4021                                 // see if the date is in the start of selection
4022                                 date_color = mc.BackColor;
4023                                 // draw the left hand of the back ground
4024                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
4025                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
4026                                 // fill the other side as a straight rect
4027                                 if (date < mc.SelectionEnd.Date) 
4028                                 {
4029                                         // use rectangle instead of rectangle to go all the way to edge of rect
4030                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
4031                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
4032                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4033                                 }
4034                         } else if (date == mc.SelectionEnd.Date) {
4035                                 // see if it is the end of selection
4036                                 date_color = mc.BackColor;
4037                                 // draw the left hand of the back ground
4038                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
4039                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
4040                                 // fill the other side as a straight rect
4041                                 if (date > mc.SelectionStart.Date) {
4042                                         selection_rect.X = rectangle.X;
4043                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
4044                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4045                                 }
4046                         } else if (date > mc.SelectionStart.Date && date < mc.SelectionEnd.Date) {
4047                                 // now see if it's in the middle
4048                                 date_color = mc.BackColor;
4049                                 // draw the left hand of the back ground
4050                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate);
4051                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
4052                         }
4053
4054                         // establish if it's a bolded font
4055                         Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font;
4056
4057                         // just draw the date now
4058                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format);
4059
4060                         // today circle if needed
4061                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
4062                                 DrawTodayCircle (dc, interior);
4063                         }
4064
4065                         // draw the selection grid
4066                         if (mc.is_date_clicked && mc.clicked_date == date) {
4067                                 Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot);
4068                                 dc.DrawRectangle (pen, interior);
4069                         }
4070                 }
4071
4072                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
4073                         Color circle_color = Color.FromArgb (248, 0, 0);
4074                         // draw the left hand of the circle 
4075                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
4076                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
4077                         Point [] curve_points = new Point [3];
4078                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
4079                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
4080                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
4081
4082                         Pen pen = ResPool.GetSizedPen(circle_color, 2);
4083                         dc.DrawArc (pen, lhs_circle_rect, 90, 180);
4084                         dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
4085                         dc.DrawCurve (pen, curve_points);
4086                         dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
4087                 }
4088
4089                 #endregion      // MonthCalendar
4090
4091                 #region Panel
4092                 public override Size PanelDefaultSize {
4093                         get {
4094                                 return new Size (200, 100);
4095                         }
4096                 }
4097                 #endregion      // Panel
4098
4099                 #region PictureBox
4100                 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
4101                         Rectangle client = pb.ClientRectangle;
4102
4103                         client = new Rectangle (client.Left + pb.Padding.Left, client.Top + pb.Padding.Top, client.Width - pb.Padding.Horizontal, client.Height - pb.Padding.Vertical);
4104
4105                         // FIXME - instead of drawing the whole picturebox every time
4106                         // intersect the clip rectangle with the drawn picture and only draw what's needed,
4107                         // Also, we only need a background fill where no image goes
4108                         if (pb.Image != null) {
4109                                 switch (pb.SizeMode) {
4110                                 case PictureBoxSizeMode.StretchImage:
4111                                         dc.DrawImage (pb.Image, client.Left, client.Top, client.Width, client.Height);
4112                                         break;
4113
4114                                 case PictureBoxSizeMode.CenterImage:
4115                                         dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
4116                                         break;
4117
4118                                 case PictureBoxSizeMode.Zoom:
4119                                         Size image_size;
4120                                         
4121                                         if (((float)pb.Image.Width / (float)pb.Image.Height) >= ((float)client.Width / (float)client.Height))
4122                                                 image_size = new Size (client.Width, (pb.Image.Height * client.Width) / pb.Image.Width);
4123                                         else
4124                                                 image_size = new Size ((pb.Image.Width * client.Height) / pb.Image.Height, client.Height);
4125
4126                                         dc.DrawImage (pb.Image, (client.Width / 2) - (image_size.Width / 2), (client.Height / 2) - (image_size.Height / 2), image_size.Width, image_size.Height);
4127                                         break;
4128
4129                                 default:
4130                                         // Normal, AutoSize
4131                                         dc.DrawImage (pb.Image, client.Left, client.Top, pb.Image.Width, pb.Image.Height);
4132                                         break;
4133                                 }
4134
4135                                 return;
4136                         }
4137                 }
4138
4139                 public override Size PictureBoxDefaultSize {
4140                         get {
4141                                 return new Size (100, 50);
4142                         }
4143                 }
4144                 #endregion      // PictureBox
4145
4146                 #region PrintPreviewControl
4147                 public override int PrintPreviewControlPadding {
4148                         get { return 8; }
4149                 }
4150
4151                 public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview)
4152                 {
4153                         int page_width, page_height;
4154                         int padding = PrintPreviewControlPadding;
4155                         PreviewPageInfo[] pis = preview.page_infos;
4156
4157                         if (preview.AutoZoom) {
4158                                 int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding;
4159                                 int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding;
4160
4161                                 float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height;
4162
4163                                 /* try to lay things out using the width to determine the size */
4164                                 page_width = width_available / preview.Columns;
4165                                 page_height = (int)(page_width / image_ratio);
4166
4167                                 /* does the height fit? */
4168                                 if (page_height * (preview.Rows + 1) > height_available) {
4169                                         /* no, lay things out via the height */
4170                                         page_height = height_available / (preview.Rows + 1);
4171                                         page_width = (int)(page_height * image_ratio);
4172                                 }
4173                         }
4174                         else {
4175                                 page_width = (int)(pis[0].Image.Width * preview.Zoom);
4176                                 page_height = (int)(pis[0].Image.Height * preview.Zoom);
4177                         }
4178
4179                         return new Size (page_width, page_height);
4180                 }
4181
4182                 public override void PrintPreviewControlPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size)
4183                 {
4184                         int padding = 8;
4185                         PreviewPageInfo[] pis = preview.page_infos;
4186                         if (pis == null)
4187                                 return;
4188
4189                         int page_x, page_y;
4190
4191                         int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding;
4192                         int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding;
4193
4194                         Rectangle viewport = preview.ViewPort;
4195
4196                         pe.Graphics.Clip = new Region (viewport);
4197
4198                         /* center things if we can */
4199                         int off_x = viewport.Width / 2 - width / 2;
4200                         if (off_x < 0) off_x = 0;
4201                         int off_y = viewport.Height / 2 - height / 2;
4202                         if (off_y < 0) off_y = 0;
4203
4204                         page_y = off_y + padding - preview.vbar_value;
4205
4206                         if (preview.StartPage > 0) {
4207                                 int p = preview.StartPage - 1;
4208                                 for (int py = 0; py < preview.Rows + 1; py ++) {
4209                                         page_x = off_x + padding - preview.hbar_value;
4210                                         for (int px = 0; px < preview.Columns; px ++) {
4211                                                 if (p >= pis.Length)
4212                                                         continue;
4213                                                 Image image = preview.image_cache[p];
4214                                                 if (image == null)
4215                                                         image = pis[p].Image;
4216                                                 Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size);
4217
4218                                                 pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
4219
4220                                                 page_x += padding + page_size.Width;
4221                                                 p++;
4222                                         }
4223                                         page_y += padding + page_size.Height;
4224                                 }
4225                         }
4226                 }
4227                 #endregion      // PrintPreviewControl
4228
4229                 #region ProgressBar
4230                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) 
4231                 {
4232                         Rectangle client_area = ctrl.client_area;
4233                         
4234                         /* Draw border */
4235                         CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl);
4236                         
4237                         /* Draw Blocks */
4238                         int draw_mode = 0;
4239                         int max_blocks = int.MaxValue;
4240                         int start_pixel = client_area.X;
4241                         draw_mode = (int) ctrl.Style;
4242
4243                         switch (draw_mode) {
4244                         case 1: { // Continuous
4245                                 int pixels_to_draw;
4246                                 pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max(ctrl.Maximum - ctrl.Minimum, 1))));
4247                                 dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
4248                                 break;
4249                         }
4250                         case 2: // Marquee
4251                                 if (XplatUI.ThemesEnabled) {
4252                                         int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds;
4253                                         double percent_done = (double) ms_diff / ProgressBarMarqueeSpeedScaling 
4254                                                 % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
4255                                         max_blocks = 5;
4256                                         start_pixel = client_area.X + (int) (client_area.Width * percent_done);
4257                                 }
4258                                 
4259                                 goto case 0;
4260                         case 0:
4261                         default:  // Blocks
4262                                 Rectangle block_rect;
4263                                 int space_betweenblocks = ProgressBarChunkSpacing;
4264                                 int block_width;
4265                                 int increment;
4266                                 int barpos_pixels;
4267                                 int block_count = 0;
4268                                 
4269                                 block_width = ProgressBarGetChunkSize (client_area.Height);
4270                                 block_width = Math.Max (block_width, 0); // block_width is used to break out the loop below, it must be >= 0!
4271                                 barpos_pixels = (int)(((double)(ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)));
4272                                 increment = block_width + space_betweenblocks;
4273                                 
4274                                 block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
4275                                 while (true) {
4276                                         if (max_blocks != int.MaxValue) {
4277                                                 if (block_count >= max_blocks)
4278                                                         break;
4279                                                 if (block_rect.X > client_area.Width)
4280                                                         block_rect.X -= client_area.Width;
4281                                         } else {
4282                                                 if ((block_rect.X - client_area.X) >= barpos_pixels)
4283                                                         break;
4284                                         }
4285                                         
4286                                         if (clip_rect.IntersectsWith (block_rect) == true) {                            
4287                                                 dc.FillRectangle (ResPool.GetSolidBrush (ctrl.ForeColor), block_rect);
4288                                         }                               
4289                                         
4290                                         block_rect.X  += increment;
4291                                         block_count++;
4292                                 }
4293                                 break;
4294                         
4295                         }
4296                 }
4297                 
4298                 public const int ProgressBarChunkSpacing = 2;
4299
4300                 public static int ProgressBarGetChunkSize ()
4301                 {
4302                         return ProgressBarGetChunkSize (ProgressBarDefaultHeight);
4303                 }
4304                 
4305                 static int ProgressBarGetChunkSize (int progressBarClientAreaHeight)
4306                 {
4307                         int size = (progressBarClientAreaHeight * 2) / 3;
4308                         return size;
4309                 }
4310
4311                 const int ProgressBarDefaultHeight = 23;
4312
4313                 public override Size ProgressBarDefaultSize {
4314                         get {
4315                                 return new Size (100, ProgressBarDefaultHeight);
4316                         }
4317                 }
4318
4319                 public const double ProgressBarMarqueeSpeedScaling = 15;
4320
4321                 #endregion      // ProgressBar
4322
4323                 #region RadioButton
4324                 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
4325                         StringFormat    text_format;
4326                         Rectangle       client_rectangle;
4327                         Rectangle       text_rectangle;
4328                         Rectangle       radiobutton_rectangle;
4329                         int             radiobutton_size = 13;
4330                         int     radiobutton_space = 4;
4331
4332                         client_rectangle = radio_button.ClientRectangle;
4333                         text_rectangle = client_rectangle;
4334                         radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
4335
4336                         text_format = new StringFormat();
4337                         text_format.Alignment = StringAlignment.Near;
4338                         text_format.LineAlignment = StringAlignment.Center;
4339                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
4340
4341                         /* Calculate the position of text and checkbox rectangle */
4342                         if (radio_button.appearance!=Appearance.Button) {
4343                                 switch(radio_button.radiobutton_alignment) {
4344                                 case ContentAlignment.BottomCenter: {
4345                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4346                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4347                                         text_rectangle.X=client_rectangle.X;
4348                                         text_rectangle.Width=client_rectangle.Width;
4349                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4350                                         break;
4351                                 }
4352
4353                                 case ContentAlignment.BottomLeft: {
4354                                         radiobutton_rectangle.X=client_rectangle.Left;
4355                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4356                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4357                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;                                 
4358                                         break;
4359                                 }
4360
4361                                 case ContentAlignment.BottomRight: {
4362                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4363                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
4364                                         text_rectangle.X=client_rectangle.X;
4365                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4366                                         break;
4367                                 }
4368
4369                                 case ContentAlignment.MiddleCenter: {
4370                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4371                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4372                                         text_rectangle.X=client_rectangle.X;
4373                                         text_rectangle.Width=client_rectangle.Width;
4374                                         break;
4375                                 }
4376
4377                                 default:
4378                                 case ContentAlignment.MiddleLeft: {
4379                                         radiobutton_rectangle.X=client_rectangle.Left;
4380                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4381                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4382                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4383                                         break;
4384                                 }
4385
4386                                 case ContentAlignment.MiddleRight: {
4387                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4388                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
4389                                         text_rectangle.X=client_rectangle.X;
4390                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4391                                         break;
4392                                 }
4393
4394                                 case ContentAlignment.TopCenter: {
4395                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
4396                                         radiobutton_rectangle.Y=client_rectangle.Top;
4397                                         text_rectangle.X=client_rectangle.X;
4398                                         text_rectangle.Y=radiobutton_size+radiobutton_space;
4399                                         text_rectangle.Width=client_rectangle.Width;
4400                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
4401                                         break;
4402                                 }
4403
4404                                 case ContentAlignment.TopLeft: {
4405                                         radiobutton_rectangle.X=client_rectangle.Left;
4406                                         radiobutton_rectangle.Y=client_rectangle.Top;
4407                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
4408                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4409                                         break;
4410                                 }
4411
4412                                 case ContentAlignment.TopRight: {
4413                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
4414                                         radiobutton_rectangle.Y=client_rectangle.Top;
4415                                         text_rectangle.X=client_rectangle.X;
4416                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
4417                                         break;
4418                                 }
4419                                 }
4420                         } else {
4421                                 text_rectangle.X=client_rectangle.X;
4422                                 text_rectangle.Width=client_rectangle.Width;
4423                         }
4424                         
4425                         /* Set the horizontal alignment of our text */
4426                         switch(radio_button.text_alignment) {
4427                                 case ContentAlignment.BottomLeft:
4428                                 case ContentAlignment.MiddleLeft:
4429                                 case ContentAlignment.TopLeft: {
4430                                         text_format.Alignment=StringAlignment.Near;
4431                                         break;
4432                                 }
4433
4434                                 case ContentAlignment.BottomCenter:
4435                                 case ContentAlignment.MiddleCenter:
4436                                 case ContentAlignment.TopCenter: {
4437                                         text_format.Alignment=StringAlignment.Center;
4438                                         break;
4439                                 }
4440
4441                                 case ContentAlignment.BottomRight:
4442                                 case ContentAlignment.MiddleRight:
4443                                 case ContentAlignment.TopRight: {
4444                                         text_format.Alignment=StringAlignment.Far;
4445                                         break;
4446                                 }
4447                         }
4448
4449                         /* Set the vertical alignment of our text */
4450                         switch(radio_button.text_alignment) {
4451                                 case ContentAlignment.TopLeft: 
4452                                 case ContentAlignment.TopCenter: 
4453                                 case ContentAlignment.TopRight: {
4454                                         text_format.LineAlignment=StringAlignment.Near;
4455                                         break;
4456                                 }
4457
4458                                 case ContentAlignment.BottomLeft:
4459                                 case ContentAlignment.BottomCenter:
4460                                 case ContentAlignment.BottomRight: {
4461                                         text_format.LineAlignment=StringAlignment.Far;
4462                                         break;
4463                                 }
4464
4465                                 case ContentAlignment.MiddleLeft:
4466                                 case ContentAlignment.MiddleCenter:
4467                                 case ContentAlignment.MiddleRight: {
4468                                         text_format.LineAlignment=StringAlignment.Center;
4469                                         break;
4470                                 }
4471                         }
4472
4473                         ButtonState state = ButtonState.Normal;
4474                         if (radio_button.FlatStyle == FlatStyle.Flat) {
4475                                 state |= ButtonState.Flat;
4476                         }
4477                         
4478                         if (radio_button.Checked) {
4479                                 state |= ButtonState.Checked;
4480                         }
4481                         
4482                         if (!radio_button.Enabled) {
4483                                 state |= ButtonState.Inactive;
4484                         }
4485
4486                         // Start drawing
4487                         RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
4488                         
4489                         if ((radio_button.image != null) || (radio_button.image_list != null))
4490                                 ButtonBase_DrawImage(radio_button, dc);
4491                         
4492                         RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
4493
4494                         if (radio_button.Focused && radio_button.Enabled && radio_button.appearance != Appearance.Button && radio_button.Text != String.Empty && radio_button.ShowFocusCues) {
4495                                 SizeF text_size = dc.MeasureString (radio_button.Text, radio_button.Font);
4496                                 
4497                                 Rectangle focus_rect = Rectangle.Empty;
4498                                 focus_rect.X = text_rectangle.X;
4499                                 focus_rect.Y = (int)((text_rectangle.Height - text_size.Height) / 2);
4500                                 focus_rect.Size = text_size.ToSize ();
4501
4502                                 RadioButton_DrawFocus (radio_button, dc, focus_rect);
4503                         }
4504                         
4505                         text_format.Dispose ();
4506                 }
4507
4508                 protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
4509                 {
4510                         dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle);
4511                         
4512                         if (radio_button.appearance==Appearance.Button) {
4513                                 ButtonBase_DrawButton (radio_button, dc);
4514                                 
4515                                 if ((radio_button.Focused) && radio_button.Enabled)
4516                                         ButtonBase_DrawFocus(radio_button, dc);
4517                         } else {
4518                                 // establish if we are rendering a flat style of some sort
4519                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
4520                                         DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
4521                                 } else {
4522                                         CPDrawRadioButton(dc, radiobutton_rectangle, state);
4523                                 }
4524                         }
4525                 }
4526                 
4527                 protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
4528                 {
4529                         DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc, 
4530                                                           text_format, radio_button.Appearance, radio_button.Checked);
4531                 }
4532                 
4533                 protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
4534                 {
4535                         DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
4536                 }
4537                 
4538                 
4539                 // renders a radio button with the Flat and Popup FlatStyle
4540                 protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
4541                 {
4542                         int     lineWidth;
4543                         
4544                         if (radio_button.Enabled) {
4545                                 
4546                                 // draw the outer flatstyle arcs
4547                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
4548                                         graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359);
4549                                         
4550                                         // fill in the area depending on whether or not the mouse is hovering
4551                                         if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) {
4552                                                 graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4553                                         } else {
4554                                                 graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4555                                         }
4556                                 } else {
4557                                         // must be a popup radio button
4558                                         // fill the control
4559                                         graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359);
4560
4561                                         if (radio_button.is_entered || radio_button.Capture) {
4562                                                 // draw the popup 3d button knob
4563                                                 graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
4564
4565                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180);
4566                                                 graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180);
4567                                                 
4568                                         } else {
4569                                                 // just draw lighter flatstyle outer circle
4570                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);                                           
4571                                         }                                                                               
4572                                 }
4573                         } else {
4574                                 // disabled
4575                                 // fill control background color regardless of actual backcolor
4576                                 graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
4577                                 // draw the ark as control dark
4578                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
4579                         }
4580
4581                         // draw the check
4582                         if (radio_button.Checked) {
4583                                 lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
4584                                 
4585                                 Pen dot_pen = SystemPens.ControlDarkDark;
4586                                 Brush dot_brush = SystemBrushes.ControlDarkDark;
4587
4588                                 if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) {
4589                                         dot_pen = SystemPens.ControlDark;
4590                                         dot_brush = SystemBrushes.ControlDark;
4591                                 } 
4592                                 
4593                                 if (rectangle.Height >  13) {
4594                                         graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
4595                                 } else {
4596                                         int x_half_pos = (rectangle.Width / 2) + rectangle.X;
4597                                         int y_half_pos = (rectangle.Height / 2) + rectangle.Y;
4598                                         
4599                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
4600                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
4601                                         
4602                                         graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
4603                                         graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
4604                                 }
4605                         }
4606                 }
4607
4608                 public override Size RadioButtonDefaultSize {
4609                         get {
4610                                 return new Size (104,24);
4611                         }
4612                 }
4613
4614                 public override void DrawRadioButton (Graphics g, RadioButton rb, Rectangle glyphArea, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
4615                 {
4616                         // Draw Button Background
4617                         if (rb.FlatStyle == FlatStyle.Flat || rb.FlatStyle == FlatStyle.Popup) {
4618                                 glyphArea.Height -= 2;
4619                                 glyphArea.Width -= 2;
4620                         }
4621                         
4622                         DrawRadioButtonGlyph (g, rb, glyphArea);
4623
4624                         // If we have an image, draw it
4625                         if (imageBounds.Size != Size.Empty)
4626                                 DrawRadioButtonImage (g, rb, imageBounds);
4627
4628                         if (rb.Focused && rb.Enabled && rb.ShowFocusCues && textBounds.Size != Size.Empty)
4629                                 DrawRadioButtonFocus (g, rb, textBounds);
4630
4631                         // If we have text, draw it
4632                         if (textBounds != Rectangle.Empty)
4633                                 DrawRadioButtonText (g, rb, textBounds);
4634                 }
4635
4636                 public virtual void DrawRadioButtonGlyph (Graphics g, RadioButton rb, Rectangle glyphArea)
4637                 {
4638                         if (rb.Pressed)
4639                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Pressed, rb.FlatStyle, rb.Checked);
4640                         else if (rb.InternalSelected)
4641                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4642                         else if (rb.Entered)
4643                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Hot, rb.FlatStyle, rb.Checked);
4644                         else if (!rb.Enabled)
4645                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Disabled, rb.FlatStyle, rb.Checked);
4646                         else
4647                                 ThemeElements.CurrentTheme.RadioButtonPainter.PaintRadioButton (g, glyphArea, rb.BackColor, rb.ForeColor, ElementState.Normal, rb.FlatStyle, rb.Checked);
4648                 }
4649
4650                 public virtual void DrawRadioButtonFocus (Graphics g, RadioButton rb, Rectangle focusArea)
4651                 {
4652                         ControlPaint.DrawFocusRectangle (g, focusArea);
4653                 }
4654
4655                 public virtual void DrawRadioButtonImage (Graphics g, RadioButton rb, Rectangle imageBounds)
4656                 {
4657                         if (rb.Enabled)
4658                                 g.DrawImage (rb.Image, imageBounds);
4659                         else
4660                                 CPDrawImageDisabled (g, rb.Image, imageBounds.Left, imageBounds.Top, ColorControl);
4661                 }
4662
4663                 public virtual void DrawRadioButtonText (Graphics g, RadioButton rb, Rectangle textBounds)
4664                 {
4665                         if (rb.Enabled)
4666                                 TextRenderer.DrawTextInternal (g, rb.Text, rb.Font, textBounds, rb.ForeColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4667                         else
4668                                 DrawStringDisabled20 (g, rb.Text, rb.Font, textBounds, rb.BackColor, rb.TextFormatFlags, rb.UseCompatibleTextRendering);
4669                 }
4670
4671                 public override Size CalculateRadioButtonAutoSize (RadioButton rb)
4672                 {
4673                         Size ret_size = Size.Empty;
4674                         Size text_size = TextRenderer.MeasureTextInternal (rb.Text, rb.Font, rb.UseCompatibleTextRendering);
4675                         Size image_size = rb.Image == null ? Size.Empty : rb.Image.Size;
4676
4677                         // Pad the text size
4678                         if (rb.Text.Length != 0) {
4679                                 text_size.Height += 4;
4680                                 text_size.Width += 4;
4681                         }
4682
4683                         switch (rb.TextImageRelation) {
4684                                 case TextImageRelation.Overlay:
4685                                         ret_size.Height = Math.Max (rb.Text.Length == 0 ? 0 : text_size.Height, image_size.Height);
4686                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4687                                         break;
4688                                 case TextImageRelation.ImageAboveText:
4689                                 case TextImageRelation.TextAboveImage:
4690                                         ret_size.Height = text_size.Height + image_size.Height;
4691                                         ret_size.Width = Math.Max (text_size.Width, image_size.Width);
4692                                         break;
4693                                 case TextImageRelation.ImageBeforeText:
4694                                 case TextImageRelation.TextBeforeImage:
4695                                         ret_size.Height = Math.Max (text_size.Height, image_size.Height);
4696                                         ret_size.Width = text_size.Width + image_size.Width;
4697                                         break;
4698                         }
4699
4700                         // Pad the result
4701                         ret_size.Height += (rb.Padding.Vertical);
4702                         ret_size.Width += (rb.Padding.Horizontal) + 15;
4703
4704                         // There seems to be a minimum height
4705                         if (ret_size.Height == rb.Padding.Vertical)
4706                                 ret_size.Height += 14;
4707
4708                         return ret_size;
4709                 }
4710
4711                 public override void CalculateRadioButtonTextAndImageLayout (ButtonBase b, Point offset, out Rectangle glyphArea, out Rectangle textRectangle, out Rectangle imageRectangle)
4712                 {
4713                         CalculateCheckBoxTextAndImageLayout (b, offset, out glyphArea, out textRectangle, out imageRectangle);
4714                 }
4715                 #endregion      // RadioButton
4716
4717                 #region ScrollBar
4718                 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
4719                 {
4720                         int             scrollbutton_width = bar.scrollbutton_width;
4721                         int             scrollbutton_height = bar.scrollbutton_height;
4722                         Rectangle       first_arrow_area;
4723                         Rectangle       second_arrow_area;                      
4724                         Rectangle       thumb_pos;
4725                         
4726                         thumb_pos = bar.ThumbPos;
4727
4728                         if (bar.vert) {
4729                                 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
4730                                 bar.FirstArrowArea = first_arrow_area;
4731
4732                                 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
4733                                 bar.SecondArrowArea = second_arrow_area;
4734
4735                                 thumb_pos.Width = bar.Width;
4736                                 bar.ThumbPos = thumb_pos;
4737
4738                                 Brush VerticalBrush;
4739                                 /* Background, upper track */
4740                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4741                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4742                                 else
4743                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4744                                 Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Bottom);
4745                                 if (clip.IntersectsWith (UpperTrack))
4746                                         dc.FillRectangle (VerticalBrush, UpperTrack);
4747
4748                                 /* Background, lower track */
4749                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4750                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4751                                 else
4752                                         VerticalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4753                                 Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom);
4754                                 if (clip.IntersectsWith (LowerTrack))
4755                                         dc.FillRectangle (VerticalBrush, LowerTrack);
4756
4757                                 /* Buttons */
4758                                 if (clip.IntersectsWith (first_arrow_area))
4759                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
4760                                 if (clip.IntersectsWith (second_arrow_area))
4761                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
4762                         } else {
4763                                 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
4764                                 bar.FirstArrowArea = first_arrow_area;
4765
4766                                 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
4767                                 bar.SecondArrowArea = second_arrow_area;
4768
4769                                 thumb_pos.Height = bar.Height;
4770                                 bar.ThumbPos = thumb_pos;
4771
4772                                 Brush HorizontalBrush;
4773                                 //Background, left track
4774                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Backwards)
4775                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4776                                 else
4777                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4778                                 Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Right, bar.ClientRectangle.Height);
4779                                 if (clip.IntersectsWith (LeftTrack))
4780                                         dc.FillRectangle (HorizontalBrush, LeftTrack);
4781
4782                                 //Background, right track
4783                                 if (bar.thumb_moving == ScrollBar.ThumbMoving.Forward)
4784                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63, 63, 63), Color.Black);
4785                                 else
4786                                         HorizontalBrush = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, Color.White);
4787                                 Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height);
4788                                 if (clip.IntersectsWith (RightTrack))
4789                                         dc.FillRectangle (HorizontalBrush, RightTrack);
4790
4791                                 /* Buttons */
4792                                 if (clip.IntersectsWith (first_arrow_area))
4793                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
4794                                 if (clip.IntersectsWith (second_arrow_area))
4795                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
4796                         }
4797
4798                         /* Thumb */
4799                         ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);                          
4800                 }
4801
4802                 protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
4803                 {
4804                         if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
4805                                 DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
4806                 }
4807
4808                 public override int ScrollBarButtonSize {
4809                         get { return 16; }
4810                 }
4811
4812                 public override bool ScrollBarHasHotElementStyles {
4813                         get {
4814                                 return false;
4815                         }
4816                 }
4817
4818                 public override bool ScrollBarHasPressedThumbStyle {
4819                         get { 
4820                                 return false;
4821                         }
4822                 }
4823
4824                 public override bool ScrollBarHasHoverArrowButtonStyle {
4825                         get {
4826                                 return false;
4827                         }
4828                 }
4829                 #endregion      // ScrollBar
4830
4831                 #region StatusBar
4832                 public  override void DrawStatusBar (Graphics real_dc, Rectangle clip, StatusBar sb) {
4833                         Rectangle area = sb.ClientRectangle;
4834                         int horz_border = 2;
4835                         int vert_border = 2;
4836
4837                         Image backbuffer = new Bitmap (sb.ClientSize.Width, sb.ClientSize.Height, real_dc);
4838                         Graphics dc = Graphics.FromImage (backbuffer);
4839                         
4840                         DrawStatusBarBackground (dc, clip, sb);
4841                         
4842                         if (!sb.ShowPanels && sb.Text != String.Empty) {
4843                                 string text = sb.Text;
4844                                 StringFormat string_format = new StringFormat ();
4845                                 string_format.Trimming = StringTrimming.Character;
4846                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
4847                                 
4848                                 if (text.Length > 127)
4849                                         text = text.Substring (0, 127);
4850
4851                                 if (text [0] == '\t') {
4852                                         string_format.Alignment = StringAlignment.Center;
4853                                         text = text.Substring (1);
4854                                         if (text [0] == '\t') {
4855                                                 string_format.Alignment = StringAlignment.Far;
4856                                                 text = text.Substring (1);
4857                                         }
4858                                 }
4859                 
4860                                 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
4861                                                 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
4862                                 string_format.Dispose ();
4863                         } else if (sb.ShowPanels) {
4864                                 Brush br_forecolor = GetControlForeBrush (sb.ForeColor);
4865                                 int prev_x = area.X + horz_border;
4866                                 int y = area.Y + vert_border;
4867                                 for (int i = 0; i < sb.Panels.Count; i++) {
4868                                         Rectangle pr = new Rectangle (prev_x, y,
4869                                                 sb.Panels [i].Width, area.Height);
4870                                         prev_x += pr.Width + StatusBarHorzGapWidth;
4871                                         if (pr.IntersectsWith (clip))
4872                                                 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
4873                                 }
4874                         }
4875
4876                         if (sb.SizingGrip)
4877                                 DrawStatusBarSizingGrip (dc, clip, sb, area);
4878                         
4879                         real_dc.DrawImage (backbuffer, 0, 0);
4880                         dc.Dispose ();
4881                         backbuffer.Dispose ();
4882
4883                 }
4884
4885                 protected virtual void DrawStatusBarBackground (Graphics dc, Rectangle clip, StatusBar sb)
4886                 {
4887                         bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
4888
4889                         Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
4890                         dc.FillRectangle (brush, clip);
4891                 }
4892
4893                 protected virtual void DrawStatusBarSizingGrip (Graphics dc, Rectangle clip, StatusBar sb, Rectangle area)
4894                 {
4895                         area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16);
4896                         CPDrawSizeGrip (dc, ColorControl, area);
4897                 }
4898
4899                 protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
4900                         Brush br_forecolor, StatusBarPanel panel) {
4901                         int border_size = 3; // this is actually const, even if the border style is none
4902                         int icon_width = 16;
4903                         
4904                         area.Height -= border_size;
4905
4906                         DrawStatusBarPanelBackground (dc, area, panel);
4907
4908                         if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
4909                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
4910                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
4911                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor);
4912                                 panel.Parent.OnDrawItemInternal (e);
4913                                 return;
4914                         }
4915
4916                         string text = panel.Text;
4917                         StringFormat string_format = new StringFormat ();
4918                         string_format.Trimming = StringTrimming.Character;
4919                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4920
4921                         
4922                         if (text != null && text.Length > 0 && text [0] == '\t') {
4923                                 string_format.Alignment = StringAlignment.Center;
4924                                 text = text.Substring (1);
4925                                 if (text [0] == '\t') {
4926                                         string_format.Alignment = StringAlignment.Far;
4927                                         text = text.Substring (1);
4928                                 }
4929                         }
4930
4931                         Rectangle string_rect = Rectangle.Empty;
4932                         int x;
4933                         int len;
4934                         int icon_x = 0;
4935                         int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1;
4936
4937                         switch (panel.Alignment) {
4938                         case HorizontalAlignment.Right:
4939                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4940                                 x = area.Right - len - 4;
4941                                 string_rect = new Rectangle (x, y, 
4942                                                 area.Right - x - border_size,
4943                                                 area.Bottom - y - border_size);
4944                                 if (panel.Icon != null) {
4945                                         icon_x = x - icon_width - 2;
4946                                 }
4947                                 break;
4948                         case HorizontalAlignment.Center:
4949                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4950                                 x = area.Left + ((panel.Width - len) / 2);
4951                                 
4952                                 string_rect = new Rectangle (x, y, 
4953                                                 area.Right - x - border_size,
4954                                                 area.Bottom - y - border_size);
4955
4956                                 if (panel.Icon != null) {
4957                                         icon_x = x - icon_width - 2;
4958                                 }
4959                                 break;
4960
4961                                 
4962                         default:
4963                                 int left = area.Left + border_size;;
4964                                 if (panel.Icon != null) {
4965                                         icon_x = area.Left + 2;
4966                                         left = icon_x + icon_width + 2;
4967                                 }
4968
4969                                 x = left;
4970                                 string_rect = new Rectangle (x, y, 
4971                                                 area.Right - x - border_size,
4972                                                 area.Bottom - y - border_size);
4973                                 break;
4974                         }
4975
4976                         RectangleF clip_bounds = dc.ClipBounds;
4977                         dc.SetClip (area);
4978                         dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format);                      
4979                         dc.SetClip (clip_bounds);
4980
4981                         if (panel.Icon != null) {
4982                                 dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width));
4983                         }
4984                 }
4985
4986                 protected virtual void DrawStatusBarPanelBackground (Graphics dc, Rectangle area, StatusBarPanel panel)
4987                 {
4988                         if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
4989                                 Border3DStyle border_style = Border3DStyle.SunkenOuter;
4990                                 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
4991                                         border_style = Border3DStyle.RaisedInner;
4992                                         
4993                                 CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor);
4994                         }
4995                 }
4996
4997                 public override int StatusBarSizeGripWidth {
4998                         get { return 15; }
4999                 }
5000
5001                 public override int StatusBarHorzGapWidth {
5002                         get { return 3; }
5003                 }
5004
5005                 public override Size StatusBarDefaultSize {
5006                         get {
5007                                 return new Size (100, 22);
5008                         }
5009                 }
5010                 #endregion      // StatusBar
5011
5012                 #region TabControl
5013
5014                 #region TabControl settings
5015
5016                 public override Size TabControlDefaultItemSize {
5017                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultItemSize; }
5018                 }
5019
5020                 public override Point TabControlDefaultPadding {
5021                         get { return ThemeElements.CurrentTheme.TabControlPainter.DefaultPadding; }
5022                 }
5023
5024                 public override int TabControlMinimumTabWidth {
5025                         get { return ThemeElements.CurrentTheme.TabControlPainter.MinimumTabWidth; }
5026                 }
5027
5028                 public override Rectangle TabControlSelectedDelta {
5029                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedTabDelta; }
5030                 }
5031
5032                 public override int TabControlSelectedSpacing {
5033                         get { return ThemeElements.CurrentTheme.TabControlPainter.SelectedSpacing; }
5034                 }
5035                 
5036                 public override int TabPanelOffsetX {
5037                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.X; }
5038                 }
5039                 
5040                 public override int TabPanelOffsetY {
5041                         get { return ThemeElements.CurrentTheme.TabControlPainter.TabPanelOffset.Y; }
5042                 }
5043
5044                 public override int TabControlColSpacing {
5045                         get { return ThemeElements.CurrentTheme.TabControlPainter.ColSpacing; }
5046                 }
5047
5048                 public override Point TabControlImagePadding {
5049                         get { return ThemeElements.CurrentTheme.TabControlPainter.ImagePadding; }
5050                 }
5051
5052                 public override int TabControlScrollerWidth {
5053                         get {return ThemeElements.CurrentTheme.TabControlPainter.ScrollerWidth; }
5054                 }
5055
5056
5057                 public override Size TabControlGetSpacing (TabControl tab) 
5058                 {
5059                         try {
5060                                 return ThemeElements.CurrentTheme.TabControlPainter.RowSpacing (tab);
5061                         } catch {
5062                                 throw new Exception ("Invalid Appearance value: " + tab.Appearance);
5063                         }
5064                 }
5065                 #endregion
5066
5067                 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
5068                 {
5069                         ThemeElements.CurrentTheme.TabControlPainter.Draw (dc, area, tab);
5070                 }
5071
5072                 public override Rectangle TabControlGetDisplayRectangle (TabControl tab)
5073                 {
5074                         return ThemeElements.CurrentTheme.TabControlPainter.GetDisplayRectangle (tab);
5075                 }
5076
5077                 public override Rectangle TabControlGetPanelRect (TabControl tab)
5078                 {
5079                         return ThemeElements.CurrentTheme.TabControlPainter.GetTabPanelRect (tab);
5080                 }
5081
5082                 #endregion
5083
5084                 #region TextBox
5085                 public override void TextBoxBaseFillBackground (TextBoxBase textBoxBase, Graphics g, Rectangle clippingArea)
5086                 {
5087                         if (textBoxBase.backcolor_set || (textBoxBase.Enabled && !textBoxBase.read_only)) {
5088                                 g.FillRectangle(ResPool.GetSolidBrush(textBoxBase.BackColor), clippingArea);
5089                         } else {
5090                                 g.FillRectangle(ResPool.GetSolidBrush(ColorControl), clippingArea);
5091                         }
5092                 }
5093
5094                 public override bool TextBoxBaseHandleWmNcPaint (TextBoxBase textBoxBase, ref Message m)
5095                 {
5096                         return false;
5097                 }
5098
5099                 public override bool TextBoxBaseShouldPaintBackground (TextBoxBase textBoxBase)
5100                 {
5101                         return true;
5102                 }
5103                 #endregion
5104
5105                 #region ToolBar
5106                 public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) 
5107                 {
5108                         StringFormat format = new StringFormat ();
5109                         format.Trimming = StringTrimming.EllipsisCharacter;
5110                         format.LineAlignment = StringAlignment.Center;
5111                         if (control.ShowKeyboardCuesInternal)
5112                                 format.HotkeyPrefix = HotkeyPrefix.Show;
5113                         else
5114                                 format.HotkeyPrefix = HotkeyPrefix.Hide;
5115
5116                         if (control.TextAlign == ToolBarTextAlign.Underneath)
5117                                 format.Alignment = StringAlignment.Center;
5118                         else
5119                                 format.Alignment = StringAlignment.Near;
5120
5121                         if (control.Appearance != ToolBarAppearance.Flat || control.Parent == null) {
5122                                 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5123                         }
5124
5125                         if (control.Divider && clip_rectangle.Y < 2) {
5126                                 if (clip_rectangle.Y < 1) {
5127                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
5128                                 }
5129                                 dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
5130                         }
5131
5132                         foreach (ToolBarItem item in control.items)
5133                                 if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
5134                                         DrawToolBarButton (dc, control, item, format);
5135
5136                         format.Dispose ();
5137                 }
5138
5139                 protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5140                 {
5141                         bool is_flat = (control.Appearance == ToolBarAppearance.Flat);
5142                         
5143                         DrawToolBarButtonBorder (dc, item, is_flat);
5144
5145                         switch (item.Button.Style) {
5146                         case ToolBarButtonStyle.DropDownButton:
5147                                 if (control.DropDownArrows)
5148                                         DrawToolBarDropDownArrow (dc, item, is_flat);
5149                                 DrawToolBarButtonContents (dc, control, item, format);
5150                                 break;
5151
5152                         case ToolBarButtonStyle.Separator:
5153                                 if (is_flat)
5154                                         DrawToolBarSeparator (dc, item);
5155                                 break;
5156
5157                         case ToolBarButtonStyle.ToggleButton:
5158                                 DrawToolBarToggleButtonBackground (dc, item);
5159                                 DrawToolBarButtonContents (dc, control, item, format);
5160                                 break;
5161
5162                         default:
5163                                 DrawToolBarButtonContents (dc, control, item, format);
5164                                 break;
5165                         }
5166                 }
5167
5168                 const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom;
5169
5170                 protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat)
5171                 {
5172                         if (item.Button.Style == ToolBarButtonStyle.Separator)
5173                                 return;
5174
5175                         Border3DStyle style;
5176
5177                         if (is_flat) {
5178                                 if (item.Button.Pushed || item.Pressed)
5179                                         style = Border3DStyle.SunkenOuter;
5180                                 else if (item.Hilight)
5181                                         style = Border3DStyle.RaisedInner;
5182                                 else
5183                                         return;
5184
5185                         } else {
5186                                 if (item.Button.Pushed || item.Pressed)
5187                                         style = Border3DStyle.Sunken;
5188                                 else 
5189                                         style = Border3DStyle.Raised;
5190                         }
5191                         
5192                         Rectangle rect = item.Rectangle;
5193                         if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat)
5194                                 rect.Width -= ToolBarDropDownWidth;
5195
5196                         CPDrawBorder3D (dc, rect, style, all_sides);
5197                 }
5198
5199                 protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item)
5200                 {
5201                         Rectangle area = item.Rectangle;
5202                         int offset = (int) SystemPens.Control.Width + 1;
5203                         dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom);
5204                         dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom);
5205                 }
5206
5207                 protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item)
5208                 {
5209                         Brush brush;
5210                         Rectangle area = item.Rectangle;
5211                         area.X += ToolBarImageGripWidth;
5212                         area.Y += ToolBarImageGripWidth;
5213                         area.Width -= 2 * ToolBarImageGripWidth;
5214                         area.Height -= 2 * ToolBarImageGripWidth;
5215                         
5216                         if (item.Button.Pushed)
5217                                 brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight);
5218                         else if (item.Button.PartialPush)
5219                                 brush = SystemBrushes.ControlLight;
5220                         else
5221                                 brush = SystemBrushes.Control;
5222                          
5223                         dc.FillRectangle (brush, area);
5224                 }
5225
5226                 protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat)
5227                 {
5228                         Rectangle rect = item.Rectangle;
5229                         rect.X = item.Rectangle.Right - ToolBarDropDownWidth;
5230                         rect.Width = ToolBarDropDownWidth;
5231                         
5232                         if (is_flat) {
5233                                 if (item.DDPressed)
5234                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5235                                 else if (item.Button.Pushed || item.Pressed)
5236                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
5237                                 else if (item.Hilight)
5238                                         CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides);
5239                         } else {
5240                                 if (item.DDPressed)
5241                                         CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides);
5242                                 else if (item.Button.Pushed || item.Pressed)
5243                                         CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides);
5244                                 else
5245                                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
5246                         }
5247                         
5248                         PointF [] vertices = new PointF [3];
5249                         PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2));
5250                         
5251                         // Increase vertical and horizontal position by 1 when button is pressed
5252                         if (item.Pressed || item.Button.Pushed || item.DDPressed) {
5253                             ddCenter.X += 1;
5254                             ddCenter.Y += 1;
5255                         }
5256                         
5257                         vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5258                         vertices [0].Y = ddCenter.Y;
5259                         vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f;
5260                         vertices [1].Y = ddCenter.Y;
5261                         vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
5262                         vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight;
5263                         dc.FillPolygon (SystemBrushes.ControlText, vertices);
5264                 }
5265
5266                 protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
5267                 {
5268                         if (item.Button.Image != null) {
5269                                 int x = item.ImageRectangle.X + ToolBarImageGripWidth;
5270                                 int y = item.ImageRectangle.Y + ToolBarImageGripWidth;
5271                                 
5272                                 // Increase vertical and horizontal position by 1 when button is pressed
5273                                 if (item.Pressed || item.Button.Pushed) {
5274                                     x += 1;
5275                                     y += 1;
5276                                 }
5277                                 
5278                                 if (item.Button.Enabled)
5279                                         dc.DrawImage (item.Button.Image, x, y);
5280                                 else 
5281                                         CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl);
5282                         }
5283
5284                         Rectangle text_rect = item.TextRectangle;
5285                         if (text_rect.Width <= 0 || text_rect.Height <= 0)
5286                                 return;
5287
5288                         if (item.Pressed || item.Button.Pushed) {
5289                                 text_rect.X += 1;
5290                                 text_rect.Y += 1;
5291                         }
5292                         
5293                         if (item.Button.Enabled)
5294                                 dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
5295                         else
5296                                 CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format);
5297                 }
5298
5299                 // Grip width for the ToolBar
5300                 public override int ToolBarGripWidth {
5301                         get { return 2;}
5302                 }
5303
5304                 // Grip width for the Image on the ToolBarButton
5305                 public override int ToolBarImageGripWidth {
5306                         get { return 2;}
5307                 }
5308
5309                 // width of the separator
5310                 public override int ToolBarSeparatorWidth {
5311                         get { return 4; }
5312                 }
5313
5314                 // width of the dropdown arrow rect
5315                 public override int ToolBarDropDownWidth {
5316                         get { return 13; }
5317                 }
5318
5319                 // width for the dropdown arrow on the ToolBarButton
5320                 public override int ToolBarDropDownArrowWidth {
5321                         get { return 5;}
5322                 }
5323
5324                 // height for the dropdown arrow on the ToolBarButton
5325                 public override int ToolBarDropDownArrowHeight {
5326                         get { return 3;}
5327                 }
5328
5329                 public override Size ToolBarDefaultSize {
5330                         get {
5331                                 return new Size (100, 42);
5332                         }
5333                 }
5334
5335                 public override bool ToolBarHasHotElementStyles (ToolBar toolBar)
5336                 {
5337                         return toolBar.Appearance == ToolBarAppearance.Flat;
5338                 }
5339
5340                 public override bool ToolBarHasHotCheckedElementStyles {
5341                         get {
5342                                 return false;
5343                         }
5344                 }
5345                 #endregion      // ToolBar
5346
5347                 #region ToolTip
5348                 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5349                 {
5350                         ToolTipDrawBackground (dc, clip_rectangle, control);
5351
5352                         TextFormatFlags flags = TextFormatFlags.HidePrefix;
5353
5354                         Color foreground = control.ForeColor;
5355                         if (control.title.Length > 0) {
5356                                 Font bold_font = new Font (control.Font, control.Font.Style | FontStyle.Bold);
5357                                 TextRenderer.DrawTextInternal (dc, control.title, bold_font, control.title_rect,
5358                                                 foreground, flags, false);
5359                                 bold_font.Dispose ();
5360                         }
5361
5362                         if (control.icon != null)
5363                                 dc.DrawIcon (control.icon, control.icon_rect);
5364
5365                         TextRenderer.DrawTextInternal (dc, control.Text, control.Font, control.text_rect, foreground, flags, false);
5366                 }
5367
5368                 protected virtual void ToolTipDrawBackground (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
5369                 {
5370                         Brush back_brush = ResPool.GetSolidBrush (control.BackColor);
5371                         dc.FillRectangle (back_brush, control.ClientRectangle);
5372                         dc.DrawRectangle (SystemPens.WindowFrame, 0, 0, control.Width - 1, control.Height - 1);
5373                 }
5374
5375                 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text)
5376                 {
5377                         Size size = TextRenderer.MeasureTextInternal (text, tt.Font, false);
5378                         size.Width += 4;
5379                         size.Height += 3;
5380                         Rectangle text_rect = new Rectangle (Point.Empty, size);
5381                         text_rect.Inflate (-2, -1);
5382                         tt.text_rect = text_rect;
5383                         tt.icon_rect = tt.title_rect = Rectangle.Empty;
5384
5385                         Size title_size = Size.Empty;
5386                         if (tt.title.Length > 0) {
5387                                 Font bold_font = new Font (tt.Font, tt.Font.Style | FontStyle.Bold);
5388                                 title_size = TextRenderer.MeasureTextInternal (tt.title, bold_font, false);
5389                                 bold_font.Dispose ();
5390                         }
5391
5392                         Size icon_size = Size.Empty;
5393                         if (tt.icon != null)
5394                                 icon_size = new Size (size.Height, size.Height);
5395
5396                         if (icon_size != Size.Empty || title_size != Size.Empty) {
5397                                 int padding = 8;
5398                                 int top_area_width = 0;
5399                                 int top_area_height = icon_size.Height > title_size.Height ? icon_size.Height : title_size.Height;
5400                                 Size text_size = size;
5401                                 Point location = new Point (padding, padding);
5402
5403                                 if (icon_size != Size.Empty) {
5404                                         tt.icon_rect = new Rectangle (location, icon_size);
5405                                         top_area_width = icon_size.Width + padding;
5406                                 }
5407
5408                                 if (title_size != Size.Empty) {
5409                                         Rectangle title_rect = new Rectangle (location, new Size (title_size.Width, top_area_height));
5410                                         if (icon_size != Size.Empty)
5411                                                 title_rect.X += icon_size.Width + padding;
5412
5413                                         tt.title_rect = title_rect;
5414                                         top_area_width += title_size.Width;
5415                                 }
5416
5417                                 tt.text_rect = new Rectangle (new Point (location.X, location.Y + top_area_height + padding),
5418                                                 text_size);
5419
5420                                 size.Height += padding + top_area_height;
5421                                 if (top_area_width > size.Width)
5422                                         size.Width = top_area_width;
5423
5424                                 // margins
5425                                 size.Width += padding * 2;
5426                                 size.Height += padding * 2;
5427                         }
5428
5429                         return size;
5430                 }
5431                 
5432                 public override bool ToolTipTransparentBackground {
5433                         get {
5434                                 return false;
5435                         }
5436                 }
5437                 #endregion      // ToolTip
5438
5439                 #region BalloonWindow
5440                 NotifyIcon.BalloonWindow balloon_window;
5441                 
5442                 public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
5443                 {
5444                         Control control = Control.FromHandle(handle);
5445                         
5446                         if (control == null)
5447                                 return;
5448
5449                         if (balloon_window != null) {
5450                                 balloon_window.Close ();
5451                                 balloon_window.Dispose ();
5452                         }
5453
5454                         balloon_window = new NotifyIcon.BalloonWindow (handle);
5455                         balloon_window.Title = title;
5456                         balloon_window.Text = text;
5457                         balloon_window.Icon = icon;
5458                         balloon_window.Timeout = timeout;
5459                         balloon_window.Show ();
5460                 }
5461
5462                 public override void HideBalloonWindow (IntPtr handle)
5463                 {
5464                         if (balloon_window == null || balloon_window.OwnerHandle != handle)
5465                                 return;
5466
5467                         balloon_window.Close ();
5468                         balloon_window.Dispose ();
5469                         balloon_window = null;
5470                 }
5471
5472                 private const int balloon_iconsize = 16;
5473                 private const int balloon_bordersize = 8; 
5474                 
5475                 public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) 
5476                 {
5477                         Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText);
5478                         Rectangle rect = control.ClientRectangle;
5479                         int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
5480                         
5481                         // Rectangle borders and background.
5482                         dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
5483                         dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1);
5484
5485                         // Icon
5486                         Image image;
5487                         switch (control.Icon) {
5488                                 case ToolTipIcon.Info: {
5489                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
5490                                         break;
5491                                 }
5492
5493                                 case ToolTipIcon.Warning: {
5494                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
5495                                         break;
5496                                 }
5497
5498                                 case ToolTipIcon.Error: {
5499                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
5500                                         break;
5501                                 }
5502                                 
5503                                 default: {
5504                                         image = null;
5505                                         break;
5506                                 }
5507                         }
5508
5509                         if (control.Icon != ToolTipIcon.None)
5510                                 dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize));
5511                         
5512                         // Title
5513                         Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0), 
5514                                                                                                 rect.Y + balloon_bordersize, 
5515                                                                                                 rect.Width - ((3 * balloon_bordersize) + iconsize), 
5516                                                                                                 rect.Height - (2 * balloon_bordersize));
5517                         
5518                         Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
5519                         dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
5520                         
5521                         // Text
5522                         Rectangle textrect = new Rectangle (rect.X + balloon_bordersize, 
5523                                                                                                 rect.Y + balloon_bordersize, 
5524                                                                                                 rect.Width - (2 * balloon_bordersize), 
5525                                                                                                 rect.Height - (2 * balloon_bordersize));
5526
5527                         StringFormat textformat = control.Format;
5528                         textformat.LineAlignment = StringAlignment.Far;
5529                         dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
5530                 }
5531
5532                 public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
5533                 {
5534                         Rectangle deskrect = Screen.GetWorkingArea (control);
5535                         SizeF maxsize = new SizeF (250, 200);
5536
5537                         SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
5538                         SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
5539                         
5540                         if (titlesize.Height < balloon_iconsize)
5541                                 titlesize.Height = balloon_iconsize;
5542                         
5543                         Rectangle rect = new Rectangle ();
5544                         rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
5545                         rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize);
5546                         rect.X = deskrect.Width - rect.Width - 2;
5547                         rect.Y = deskrect.Height - rect.Height - 2;
5548                         
5549                         return rect;
5550                 }
5551                 #endregion      // BalloonWindow
5552
5553                 #region TrackBar
5554                 public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb)
5555                 {
5556                         int result = tb.Value;
5557                         int value_pos = tb.Value;
5558                         float pixels_betweenticks;
5559                         Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty;
5560                         Point channel_startpoint = Point.Empty, na_point = Point.Empty;
5561                         
5562                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point);
5563                         
5564                         /* Convert thumb position from mouse position to value*/
5565                         if (tb.Orientation == Orientation.Vertical) {
5566                                 value_pos = (int)Math.Round (((thumb_area.Bottom - y - (float)thumb_pos.Height / 2) / (float)pixels_betweenticks), 0);
5567
5568                                 if (value_pos + tb.Minimum > tb.Maximum)
5569                                         value_pos = tb.Maximum - tb.Minimum;
5570                                 else if (value_pos + tb.Minimum < tb.Minimum)
5571                                         value_pos = 0;
5572
5573                                 result = value_pos + tb.Minimum;
5574                         } else {
5575                                 value_pos = (int)Math.Round (((x - channel_startpoint.X - (float)thumb_pos.Width / 2) / (float) pixels_betweenticks), 0);
5576
5577                                 if (value_pos + tb.Minimum > tb.Maximum)
5578                                         value_pos = tb.Maximum - tb.Minimum;
5579                                 else if (value_pos + tb.Minimum < tb.Minimum)
5580                                         value_pos = 0;
5581
5582                                 result = value_pos + tb.Minimum;
5583                         }
5584                         
5585                         return result;
5586                 }
5587                 
5588                 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)
5589                 {
5590                         thumb_area = Rectangle.Empty;
5591                         thumb_pos = Rectangle.Empty;
5592                         
5593                         if (tb.Orientation == Orientation.Vertical) {
5594                                 toptick_startpoint = new Point ();
5595                                 bottomtick_startpoint = new Point ();
5596                                 channel_startpoint = new Point ();
5597                                 float pixel_len;
5598                                 const int space_from_right = 8;
5599                                 const int space_from_left = 8;
5600                                 const int space_from_bottom = 11;
5601                                 Rectangle area = tb.ClientRectangle;
5602
5603                                 switch (tb.TickStyle) {
5604                                 case TickStyle.BottomRight:
5605                                 case TickStyle.None:
5606                                         channel_startpoint.Y = 8;
5607                                         channel_startpoint.X = 9;
5608                                         bottomtick_startpoint.Y = 13;
5609                                         bottomtick_startpoint.X = 24;
5610                                         break;
5611                                 case TickStyle.TopLeft:
5612                                         channel_startpoint.Y = 8;
5613                                         channel_startpoint.X = 19;
5614                                         toptick_startpoint.Y = 13;
5615                                         toptick_startpoint.X = 8;
5616                                         break;
5617                                 case TickStyle.Both:
5618                                         channel_startpoint.Y = 8;
5619                                         channel_startpoint.X = 18;
5620                                         bottomtick_startpoint.Y = 13;
5621                                         bottomtick_startpoint.X = 32;
5622                                         toptick_startpoint.Y = 13;
5623                                         toptick_startpoint.X = 8;
5624                                         break;
5625                                 default:
5626                                         break;
5627                                 }
5628
5629                                 thumb_area.X = area.X + channel_startpoint.X;
5630                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5631                                 thumb_area.Height = area.Height - space_from_right - space_from_left;
5632                                 thumb_area.Width = TrackBarVerticalTrackWidth;
5633
5634                                 pixel_len = thumb_area.Height - 11;
5635                                 if (tb.Maximum == tb.Minimum) {
5636                                         pixels_betweenticks = 0;
5637                                 } else {
5638                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5639                                 }
5640
5641                                 thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum));
5642                         } else {        
5643                                 toptick_startpoint = new Point ();
5644                                 bottomtick_startpoint = new Point ();
5645                                 channel_startpoint = new Point ();
5646                                 float pixel_len;
5647                                 const int space_from_right = 8;
5648                                 const int space_from_left = 8;
5649                                 Rectangle area = tb.ClientRectangle;
5650                                                         
5651                                 switch (tb.TickStyle) {
5652                                 case TickStyle.BottomRight:
5653                                 case TickStyle.None:
5654                                         channel_startpoint.X = 8;
5655                                         channel_startpoint.Y = 9;
5656                                         bottomtick_startpoint.X = 13;
5657                                         bottomtick_startpoint.Y = 24;                           
5658                                         break;
5659                                 case TickStyle.TopLeft:
5660                                         channel_startpoint.X = 8;
5661                                         channel_startpoint.Y = 19;
5662                                         toptick_startpoint.X = 13;
5663                                         toptick_startpoint.Y = 8;
5664                                         break;
5665                                 case TickStyle.Both:
5666                                         channel_startpoint.X = 8;
5667                                         channel_startpoint.Y = 18;      
5668                                         bottomtick_startpoint.X = 13;
5669                                         bottomtick_startpoint.Y = 32;                           
5670                                         toptick_startpoint.X = 13;
5671                                         toptick_startpoint.Y = 8;                               
5672                                         break;
5673                                 default:
5674                                         break;
5675                                 }
5676                                                         
5677                                 thumb_area.X = area.X + channel_startpoint.X;
5678                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5679                                 thumb_area.Width = area.Width - space_from_right - space_from_left;
5680                                 thumb_area.Height = TrackBarHorizontalTrackHeight;
5681
5682                                 pixel_len = thumb_area.Width - 11;
5683                                 if (tb.Maximum == tb.Minimum) {
5684                                         pixels_betweenticks = 0;
5685                                 } else {
5686                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5687                                 }
5688
5689                                 thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum));
5690                         }
5691
5692                         thumb_pos.Size = TrackBarGetThumbSize (tb);
5693                 }
5694
5695                 protected virtual Size TrackBarGetThumbSize (TrackBar trackBar)
5696                 {
5697                         return TrackBarGetThumbSize ();
5698                 }
5699
5700                 public static Size TrackBarGetThumbSize ()
5701                 {
5702                         /* Draw thumb fixed 10x22 size */
5703                         return new Size (10, 22);
5704                 }
5705
5706                 public const int TrackBarVerticalTrackWidth = 4;
5707
5708                 public const int TrackBarHorizontalTrackHeight = 4;
5709
5710                 #region Ticks
5711                 protected interface ITrackBarTickPainter
5712                 {
5713                         void Paint (float x1, float y1, float x2, float y2);
5714                 }
5715
5716                 class TrackBarTickPainter : ITrackBarTickPainter
5717                 {
5718                         readonly Graphics g;
5719                         readonly Pen pen;
5720                         public TrackBarTickPainter (Graphics g, Pen pen)
5721                         {
5722                                 this.g = g;
5723                                 this.pen = pen;
5724                         }
5725                         public void Paint (float x1, float y1, float x2, float y2)
5726                         {
5727                                 g.DrawLine (pen, x1, y1, x2, y2);
5728                         }
5729                 }
5730                 protected virtual ITrackBarTickPainter GetTrackBarTickPainter (Graphics g)
5731                 {
5732                         return new TrackBarTickPainter (g, ResPool.GetPen (pen_ticks_color));
5733                 }
5734                 #endregion
5735
5736                 #region DrawTrackBar_Vertical
5737                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5738                         ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
5739                         float ticks, int value_pos, bool mouse_value) {                 
5740
5741                         Point toptick_startpoint = new Point ();
5742                         Point bottomtick_startpoint = new Point ();
5743                         Point channel_startpoint = new Point ();
5744                         float pixel_len;
5745                         float pixels_betweenticks;
5746                         Rectangle area = tb.ClientRectangle;
5747                         
5748                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5749
5750                         #region Track
5751                         TrackBarDrawVerticalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5752                         #endregion
5753
5754                         #region Thumb
5755                         switch (tb.TickStyle)   {
5756                         case TickStyle.BottomRight:
5757                         case TickStyle.None:
5758                                 thumb_pos.X = channel_startpoint.X - 8;
5759                                 TrackBarDrawVerticalThumbRight (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5760                                 break;
5761                         case TickStyle.TopLeft:
5762                                 thumb_pos.X = channel_startpoint.X - 10;
5763                                 TrackBarDrawVerticalThumbLeft (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5764                                 break;
5765                         default:
5766                                 thumb_pos.X = area.X + 10;
5767                                 TrackBarDrawVerticalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5768                                 break;
5769                         }
5770                         #endregion
5771
5772                         pixel_len = thumb_area.Height - 11;
5773                         pixels_betweenticks = pixel_len / ticks;
5774                         
5775                         thumb_area.X = thumb_pos.X;
5776                         thumb_area.Y = channel_startpoint.Y;
5777                         thumb_area.Width = thumb_pos.Height;
5778
5779                         #region Ticks
5780                         if (pixels_betweenticks <= 0)
5781                                 return;
5782                         if (tb.TickStyle == TickStyle.None)
5783                                 return;
5784                         Region outside = new Region (area);
5785                         outside.Exclude (thumb_area);                   
5786                         
5787                         if (outside.IsVisible (clip_rectangle)) {
5788                                 ITrackBarTickPainter tick_painter = TrackBarGetVerticalTickPainter (dc);
5789
5790                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5791                                         float x = area.X + bottomtick_startpoint.X;
5792                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks)    {
5793                                                 float y = area.Y + bottomtick_startpoint.Y + inc;
5794                                                 tick_painter.Paint (
5795                                                         x, y,
5796                                                         x + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y);
5797                                         }
5798                                 }
5799
5800                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5801                                         float x = area.X + toptick_startpoint.X; 
5802                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
5803                                                 float y = area.Y + toptick_startpoint.Y + inc;
5804                                                 tick_painter.Paint (
5805                                                         x - (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2), y,
5806                                                         x, y);
5807                                         }                       
5808                                 }
5809                         }
5810                         
5811                         outside.Dispose ();
5812                         #endregion
5813                 }
5814
5815                 #region Track
5816                 protected virtual void TrackBarDrawVerticalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5817                 {
5818                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5819                                 1, thumb_area.Height);
5820
5821                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y,
5822                                 1, thumb_area.Height);
5823
5824                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y,
5825                                 1, thumb_area.Height);
5826                 }
5827                 #endregion
5828
5829                 #region Thumb
5830                 protected virtual void TrackBarDrawVerticalThumbRight (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5831                 {
5832                         Pen pen = SystemPens.ControlLightLight;
5833                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 10);
5834                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
5835                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
5836
5837                         pen = SystemPens.ControlDark;
5838                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 15, thumb_pos.Y + 9);
5839                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X + 16 + 4, thumb_pos.Y + 9 - 4);
5840
5841                         pen = SystemPens.ControlDarkDark;
5842                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 16, thumb_pos.Y + 10);
5843                         dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 10, thumb_pos.X + 16 + 5, thumb_pos.Y + 10 - 5);
5844
5845                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
5846                         dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
5847                         dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
5848                         dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
5849                 }
5850
5851                 protected virtual void TrackBarDrawVerticalThumbLeft (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5852                 {
5853                         Pen pen = SystemPens.ControlLightLight;
5854                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
5855                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
5856
5857                         pen = SystemPens.ControlDark;
5858                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16, thumb_pos.Y + 9);
5859                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 9, thumb_pos.X, thumb_pos.Y + 5);
5860                         dc.DrawLine (pen, thumb_pos.X + 19, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 1);
5861
5862                         pen = SystemPens.ControlDarkDark;
5863                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X + 4 + 16, thumb_pos.Y + 10);
5864                         dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y + 10, thumb_pos.X - 1, thumb_pos.Y + 5);
5865                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 10);
5866
5867                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
5868                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
5869                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
5870                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
5871                 }
5872
5873                 protected virtual void TrackBarDrawVerticalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
5874                 {
5875                         Pen pen = SystemPens.ControlLightLight;
5876                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
5877                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
5878
5879                         pen = SystemPens.ControlDark;
5880                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X + 19, thumb_pos.Y + 9);
5881                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 1, thumb_pos.X + 19, thumb_pos.Y + 8);
5882
5883                         pen = SystemPens.ControlDarkDark;
5884                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X + 20, thumb_pos.Y + 10);
5885                         dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X + 20, thumb_pos.Y + 9);
5886
5887                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
5888                 }
5889                 #endregion
5890
5891                 #region Ticks
5892                 protected virtual ITrackBarTickPainter TrackBarGetVerticalTickPainter (Graphics g)
5893                 {
5894                         return GetTrackBarTickPainter (g);
5895                 }
5896                 #endregion
5897                 #endregion
5898
5899                 #region DrawTrackBar_Horizontal
5900                 /* 
5901                         Horizontal trackbar 
5902                   
5903                         Does not matter the size of the control, Win32 always draws:
5904                                 - Ticks starting from pixel 13, 8
5905                                 - Channel starting at pos 8, 19 and ends at Width - 8
5906                                 - Autosize makes always the control 45 pixels high
5907                                 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
5908                                 
5909                 */
5910                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5911                         ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5912                         float ticks, int value_pos, bool mouse_value) {                 
5913                         Point toptick_startpoint = new Point ();
5914                         Point bottomtick_startpoint = new Point ();
5915                         Point channel_startpoint = new Point ();
5916                         float pixel_len;
5917                         float pixels_betweenticks;
5918                         Rectangle area = tb.ClientRectangle;
5919                         
5920                         GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5921
5922                         #region Track
5923                         TrackBarDrawHorizontalTrack (dc, thumb_area, channel_startpoint, clip_rectangle);
5924                         #endregion
5925
5926                         #region Thumb
5927                         switch (tb.TickStyle) {
5928                         case TickStyle.BottomRight:
5929                         case TickStyle.None:
5930                                 thumb_pos.Y = channel_startpoint.Y - 8;
5931                                 TrackBarDrawHorizontalThumbBottom (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5932                                 break;
5933                         case TickStyle.TopLeft:
5934                                 thumb_pos.Y = channel_startpoint.Y - 10;
5935                                 TrackBarDrawHorizontalThumbTop (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5936                                 break;
5937                         default:
5938                                 thumb_pos.Y = area.Y + 10;
5939                                 TrackBarDrawHorizontalThumb (dc, thumb_pos, br_thumb, clip_rectangle, tb);
5940                                 break;
5941                         }
5942                         #endregion
5943
5944                         pixel_len = thumb_area.Width - 11;
5945                         pixels_betweenticks = pixel_len / ticks;
5946
5947                         thumb_area.Y = thumb_pos.Y;
5948                         thumb_area.X = channel_startpoint.X;
5949                         thumb_area.Height = thumb_pos.Height;
5950                         #region Ticks
5951                         if (pixels_betweenticks <= 0)
5952                                 return;
5953                         if (tb.TickStyle == TickStyle.None)
5954                                 return;
5955                         Region outside = new Region (area);
5956                         outside.Exclude (thumb_area);
5957
5958                         if (outside.IsVisible (clip_rectangle)) {
5959                                 ITrackBarTickPainter tick_painter = TrackBarGetHorizontalTickPainter (dc);
5960
5961                                 if ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight) {
5962                                         float y = area.Y + bottomtick_startpoint.Y;
5963                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5964                                                 float x = area.X + bottomtick_startpoint.X + inc;
5965                                                 tick_painter.Paint (
5966                                                         x, y, 
5967                                                         x, y + (inc == 0 || inc + pixels_betweenticks >= pixel_len + 1 ? 3 : 2));
5968                                         }
5969                                 }
5970
5971                                 if ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft) {
5972                                         float y = area.Y + toptick_startpoint.Y;
5973                                         for (float inc = 0; inc < pixel_len + 1; inc += pixels_betweenticks) {                                  
5974                                                 float x = area.X + toptick_startpoint.X + inc;
5975                                                 tick_painter.Paint (
5976                                                         x, y - (inc == 0 || (inc + pixels_betweenticks) >= pixel_len + 1 ? 3 : 2), 
5977                                                         x, y);
5978                                         }                       
5979                                 }
5980                         }
5981                         
5982                         outside.Dispose ();
5983                         #endregion
5984                 }
5985
5986                 #region Track
5987                 protected virtual void TrackBarDrawHorizontalTrack (Graphics dc, Rectangle thumb_area, Point channel_startpoint, Rectangle clippingArea)
5988                 {
5989                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5990                                 thumb_area.Width, 1);
5991
5992                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1,
5993                                 thumb_area.Width, 1);
5994
5995                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y + 3,
5996                                 thumb_area.Width, 1);
5997                 }
5998                 #endregion
5999
6000                 #region Thumb
6001                 protected virtual void TrackBarDrawHorizontalThumbBottom (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6002                 {
6003                         Pen pen = SystemPens.ControlLightLight;
6004                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
6005                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
6006                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
6007
6008                         pen = SystemPens.ControlDark;
6009                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 15);
6010                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X + 9 - 4, thumb_pos.Y + 16 + 4);
6011
6012                         pen = SystemPens.ControlDarkDark;
6013                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 16);
6014                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X + 10 - 5, thumb_pos.Y + 16 + 5);
6015
6016                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
6017                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
6018                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
6019                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
6020                 }
6021
6022                 protected virtual void TrackBarDrawHorizontalThumbTop (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6023                 {
6024                         Pen pen = SystemPens.ControlLightLight;
6025                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
6026                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
6027
6028                         pen = SystemPens.ControlDark;
6029                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
6030                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
6031                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1, thumb_pos.Y + 19);
6032
6033                         pen = SystemPens.ControlDarkDark;
6034                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
6035                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y - 1);
6036                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
6037
6038                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
6039                         dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
6040                         dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
6041                         dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
6042                 }
6043
6044                 protected virtual void TrackBarDrawHorizontalThumb (Graphics dc, Rectangle thumb_pos, Brush br_thumb, Rectangle clippingArea, TrackBar trackBar)
6045                 {
6046                         Pen pen = SystemPens.ControlLightLight;
6047                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
6048                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
6049
6050                         pen = SystemPens.ControlDark;
6051                         dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
6052                         dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
6053
6054                         pen = SystemPens.ControlDarkDark;
6055                         dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y + 20);
6056                         dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
6057
6058                         dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
6059                 }
6060                 #endregion
6061
6062                 #region Ticks
6063                 protected virtual ITrackBarTickPainter TrackBarGetHorizontalTickPainter (Graphics g)
6064                 {
6065                         return GetTrackBarTickPainter (g);
6066                 }
6067                 #endregion
6068                 #endregion
6069
6070                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) 
6071                 {
6072                         Brush           br_thumb;
6073                         int             value_pos;
6074                         bool            mouse_value;
6075                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
6076                         Rectangle       area;
6077                         Rectangle       thumb_pos = tb.ThumbPos;
6078                         Rectangle       thumb_area = tb.ThumbArea;
6079                         
6080                         if (tb.thumb_pressed) {
6081                                 value_pos = tb.thumb_mouseclick;
6082                                 mouse_value = true;
6083                         } else {
6084                                 value_pos = tb.Value - tb.Minimum;
6085                                 mouse_value = false;
6086                         }
6087
6088                         area = tb.ClientRectangle;
6089
6090                         if (!tb.Enabled) {
6091                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
6092                         } else if (tb.thumb_pressed == true) {
6093                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
6094                         } else {
6095                                 br_thumb = SystemBrushes.Control;
6096                         }
6097
6098                         
6099                         /* Control Background */
6100                         if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
6101                                 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
6102                         } else {
6103                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
6104                         }
6105                         
6106                         if (tb.Focused) {
6107                                 CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor);
6108                         }
6109
6110                         if (tb.Orientation == Orientation.Vertical) {
6111                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6112                                         br_thumb, ticks, value_pos, mouse_value);
6113                         
6114                         } else {
6115                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
6116                                         br_thumb, ticks, value_pos, mouse_value);
6117                         }
6118
6119                         tb.ThumbPos = thumb_pos;
6120                         tb.ThumbArea = thumb_area;
6121                 }
6122
6123                 public override Size TrackBarDefaultSize {
6124                         get {
6125                                 return new Size (104, 42);
6126                         }
6127                 }
6128
6129                 public override bool TrackBarHasHotThumbStyle {
6130                         get {
6131                                 return false;
6132                         }
6133                 }
6134                 #endregion      // TrackBar
6135
6136                 #region UpDownBase
6137                 public override void UpDownBaseDrawButton (Graphics g, Rectangle bounds, bool top, VisualStyles.PushButtonState state)
6138                 {
6139                         ControlPaint.DrawScrollButton (g, bounds, top ? ScrollButton.Up : ScrollButton.Down, state == VisualStyles.PushButtonState.Pressed ? ButtonState.Pushed : ButtonState.Normal);
6140                 }
6141
6142                 public override bool UpDownBaseHasHotButtonStyle {
6143                         get {
6144                                 return false;
6145                         }
6146                 }
6147                 #endregion
6148
6149                 #region VScrollBar
6150                 public override Size VScrollBarDefaultSize {
6151                         get {
6152                                 return new Size (this.ScrollBarButtonSize, 80);
6153                         }
6154                 }
6155                 #endregion      // VScrollBar
6156
6157                 #region TreeView
6158                 public override Size TreeViewDefaultSize {
6159                         get {
6160                                 return new Size (121, 97);
6161                         }
6162                 }
6163
6164                 public override void TreeViewDrawNodePlusMinus (TreeView treeView, TreeNode node, Graphics dc, int x, int middle)
6165                 {
6166                         int height = treeView.ActualItemHeight - 2;
6167                         dc.FillRectangle (ResPool.GetSolidBrush (treeView.BackColor), (x + 4) - (height / 2), node.GetY() + 1, height, height);
6168                         
6169                         dc.DrawRectangle (SystemPens.ControlDarkDark, x, middle - 4, 8, 8);
6170
6171                         if (node.IsExpanded) {
6172                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle); 
6173                         } else {
6174                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 2, middle, x + 6, middle);
6175                                 dc.DrawLine (SystemPens.ControlDarkDark, x + 4, middle - 2, x + 4, middle + 2);
6176                         }
6177                 }
6178                 #endregion
6179
6180                 #region Managed window
6181                 public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
6182                 {
6183                         if (wm.IsToolWindow && !wm.IsMinimized)
6184                                 return SystemInformation.ToolWindowCaptionHeight;
6185                         if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6186                                 return 0;
6187                         return SystemInformation.CaptionHeight;
6188                 }
6189
6190                 public override int ManagedWindowBorderWidth (InternalWindowManager wm)
6191                 {
6192                         if ((wm.IsToolWindow && wm.form.FormBorderStyle == FormBorderStyle.FixedToolWindow) ||
6193                                 wm.IsMinimized)
6194                                 return 3;
6195                         else
6196                                 return 4;
6197                 }
6198
6199                 public override int ManagedWindowIconWidth (InternalWindowManager wm)
6200                 {
6201                         return ManagedWindowTitleBarHeight (wm) - 5;
6202                 }
6203
6204                 public override void ManagedWindowSetButtonLocations (InternalWindowManager wm)
6205                 {
6206                         TitleButtons buttons = wm.TitleButtons;
6207                         Form form = wm.form;
6208                         
6209                         buttons.HelpButton.Visible = form.HelpButton;
6210                         
6211                         foreach (TitleButton button in buttons) {
6212                                 button.Visible = false;
6213                         }
6214                         
6215                         switch (form.FormBorderStyle) {
6216                         case FormBorderStyle.None:
6217                                 if (form.WindowState != FormWindowState.Normal)
6218                                         goto case FormBorderStyle.Sizable;
6219                                 break;
6220                         case FormBorderStyle.FixedToolWindow:
6221                         case FormBorderStyle.SizableToolWindow:
6222                                 buttons.CloseButton.Visible = true;
6223                                 if (form.WindowState != FormWindowState.Normal)
6224                                         goto case FormBorderStyle.Sizable;
6225                                 break;
6226                         case FormBorderStyle.FixedSingle:
6227                         case FormBorderStyle.Fixed3D:
6228                         case FormBorderStyle.FixedDialog:
6229                         case FormBorderStyle.Sizable:
6230                                 switch (form.WindowState) {
6231                                         case FormWindowState.Normal:
6232                                                 buttons.MinimizeButton.Visible = true;
6233                                                 buttons.MaximizeButton.Visible = true;
6234                                                 buttons.RestoreButton.Visible = false;
6235                                                 break;
6236                                         case FormWindowState.Maximized:
6237                                                 buttons.MinimizeButton.Visible = true;
6238                                                 buttons.MaximizeButton.Visible = false;
6239                                                 buttons.RestoreButton.Visible = true;
6240                                                 break;
6241                                         case FormWindowState.Minimized:
6242                                                 buttons.MinimizeButton.Visible = false;
6243                                                 buttons.MaximizeButton.Visible = true;
6244                                                 buttons.RestoreButton.Visible = true;
6245                                                 break;
6246                                 }
6247                                 buttons.CloseButton.Visible = true;
6248                                 break;
6249                         }
6250
6251                         // Respect MinimizeBox/MaximizeBox
6252                         if (form.MinimizeBox == false && form.MaximizeBox == false) {
6253                                 buttons.MinimizeButton.Visible = false;
6254                                 buttons.MaximizeButton.Visible = false;
6255                         } else if (form.MinimizeBox == false)
6256                                 buttons.MinimizeButton.State = ButtonState.Inactive;
6257                         else if (form.MaximizeBox == false)
6258                                 buttons.MaximizeButton.State = ButtonState.Inactive;
6259
6260                         int bw = ManagedWindowBorderWidth (wm);
6261                         Size btsize = ManagedWindowButtonSize (wm);
6262                         int btw = btsize.Width;
6263                         int bth = btsize.Height;
6264                         int top = bw + 2;
6265                         int left = form.Width - bw - btw - ManagedWindowSpacingAfterLastTitleButton;
6266                         
6267                         if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
6268                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6269                                 left -= 2 + btw;
6270                                 
6271                                 if (buttons.MaximizeButton.Visible) {
6272                                         buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6273                                         left -= 2 + btw;
6274                                 } 
6275                                 if (buttons.RestoreButton.Visible) {
6276                                         buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth);
6277                                         left -= 2 + btw;
6278                                 }
6279
6280                                 buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth);
6281                                 left -= 2 + btw;
6282                         } else if (wm.IsToolWindow) {
6283                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
6284                                 left -= 2 + btw;
6285                         }
6286                 }
6287
6288                 protected virtual Rectangle ManagedWindowDrawTitleBarAndBorders (Graphics dc, Rectangle clip, InternalWindowManager wm)
6289                 {
6290                         Form form = wm.Form;
6291                         int tbheight = ManagedWindowTitleBarHeight (wm);
6292                         int bdwidth = ManagedWindowBorderWidth (wm);
6293                         Color titlebar_color = Color.FromArgb (255, 10, 36, 106);
6294                         Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240);
6295                         Color color = ThemeEngine.Current.ColorControlDark;
6296                         Color color2 = Color.FromArgb (255, 192, 192, 192);
6297
6298                         Pen pen = ResPool.GetPen (ColorControl);
6299                         Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
6300                         ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
6301                         // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves
6302                         borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5);
6303                         for (int i = 2; i < bdwidth; i++) {
6304                                 dc.DrawRectangle (pen, borders);
6305                                 borders.Inflate (-1, -1);
6306                         }                               
6307
6308
6309                         bool draw_titlebar_enabled = false;
6310                         if (wm.Form.Parent != null && wm.Form.Parent is Form) {
6311                                 draw_titlebar_enabled = false;
6312                         } else if (wm.IsActive && !wm.IsMaximized) {
6313                                 draw_titlebar_enabled = true;
6314                         }
6315                         if (draw_titlebar_enabled) {
6316                                 color = titlebar_color;
6317                                 color2 = titlebar_color2;
6318                         }
6319
6320                         Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1);
6321
6322                         // HACK: For now always draw the titlebar until we get updates better
6323                         if (tb.Width > 0 && tb.Height > 0) {
6324                                 using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal))
6325                                 {
6326                                         dc.FillRectangle (gradient, tb);
6327                                 }       
6328                         }
6329                         
6330                         if (!wm.IsMinimized)
6331                                 // Draw the line just beneath the title bar
6332                                 dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth,
6333                                                 tbheight + bdwidth - 1, form.Width - bdwidth - 1,
6334                                                 tbheight + bdwidth - 1);
6335                         return tb;
6336                 }
6337
6338                 public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
6339                 {
6340 #if debug
6341                         Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations");
6342                         dc.FillRectangle (Brushes.Black, clip);
6343 #endif
6344                         Rectangle tb = ManagedWindowDrawTitleBarAndBorders (dc, clip, wm);
6345
6346                         Form form = wm.Form;
6347                         if (wm.ShowIcon) {
6348                                 Rectangle icon = ManagedWindowGetTitleBarIconArea (wm);
6349                                 if (icon.IntersectsWith (clip))
6350                                         dc.DrawIcon (form.Icon, icon);
6351                                 const int SpacingBetweenIconAndCaption = 2;
6352                                 tb.Width -= icon.Right + SpacingBetweenIconAndCaption - tb.X ;
6353                                 tb.X = icon.Right + SpacingBetweenIconAndCaption;
6354                         }
6355                         
6356                         foreach (TitleButton button in wm.TitleButtons.AllButtons) {
6357                                 tb.Width -= Math.Max (0, tb.Right - DrawTitleButton (dc, button, clip, form));
6358                         }
6359                         const int SpacingBetweenCaptionAndLeftMostButton = 3;
6360                         tb.Width -= SpacingBetweenCaptionAndLeftMostButton;
6361
6362                         string window_caption = form.Text;
6363                         window_caption = window_caption.Replace (Environment.NewLine, string.Empty);
6364
6365                         if (window_caption != null && window_caption != string.Empty) {
6366                                 StringFormat format = new StringFormat ();
6367                                 format.FormatFlags = StringFormatFlags.NoWrap;
6368                                 format.Trimming = StringTrimming.EllipsisCharacter;
6369                                 format.LineAlignment = StringAlignment.Center;
6370
6371                                 if (tb.IntersectsWith (clip))
6372                                         dc.DrawString (window_caption, WindowBorderFont,
6373                                                 ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
6374                                                 tb, format);
6375                         }
6376                 }
6377
6378                 public override Size ManagedWindowButtonSize (InternalWindowManager wm)
6379                 {
6380                         int height = ManagedWindowTitleBarHeight (wm);
6381                         if (!wm.IsMaximized && !wm.IsMinimized) {
6382                                 if (wm.IsToolWindow)
6383                                         return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
6384                                                         height - 5);
6385                                 if (wm.Form.FormBorderStyle == FormBorderStyle.None)
6386                                         return Size.Empty;
6387                         } else
6388                                 height = SystemInformation.CaptionHeight;
6389
6390                         return new Size (SystemInformation.CaptionButtonSize.Width - 2,
6391                                         height - 5);
6392                 }
6393
6394                 private int DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6395                 {
6396                         if (!button.Visible) {
6397                                 return int.MaxValue;
6398                         }
6399                         
6400                         if (button.Rectangle.IntersectsWith (clip)) {
6401                                 ManagedWindowDrawTitleButton (dc, button, clip, form);
6402                         }
6403                         return button.Rectangle.Left;
6404                 }
6405
6406                 protected virtual void ManagedWindowDrawTitleButton (Graphics dc, TitleButton button, Rectangle clip, Form form)
6407                 {
6408                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6409
6410                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6411                                         button.Caption, button.State);
6412                 }
6413
6414                 public override Rectangle ManagedWindowGetTitleBarIconArea (InternalWindowManager wm)
6415                 {
6416                         int bw = ManagedWindowBorderWidth (wm);
6417                         return new Rectangle (bw + 3, bw + 2, wm.IconWidth, wm.IconWidth);
6418                 }
6419
6420                 public override Size ManagedWindowGetMenuButtonSize (InternalWindowManager wm)
6421                 {
6422                         Size result = SystemInformation.MenuButtonSize;
6423                         result.Width -= 2;
6424                         result.Height -= 4;
6425                         return result;
6426                 }
6427
6428                 public override bool ManagedWindowTitleButtonHasHotElementStyle (TitleButton button, Form form)
6429                 {
6430                         return false;
6431                 }
6432
6433                 public override void ManagedWindowDrawMenuButton (Graphics dc, TitleButton button, Rectangle clip, InternalWindowManager wm)
6434                 {
6435                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
6436                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
6437                                         button.Caption, button.State);
6438                 }
6439
6440                 public override void ManagedWindowOnSizeInitializedOrChanged (Form form)
6441                 {
6442                 }
6443                 #endregion
6444
6445                 #region ControlPaint
6446                 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
6447                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6448                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6449                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6450                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6451                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6452                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6453                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6454                 }
6455
6456                 public override void CPDrawBorder (Graphics graphics, RectangleF bounds, Color leftColor, int leftWidth,
6457                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
6458                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
6459                         int bottomWidth, ButtonBorderStyle bottomStyle) {
6460                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
6461                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
6462                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
6463                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
6464                 }
6465
6466                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
6467                         CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
6468                 }
6469
6470                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)
6471                 {
6472                         Pen             penTopLeft;
6473                         Pen             penTopLeftInner;
6474                         Pen             penBottomRight;
6475                         Pen             penBottomRightInner;
6476                         Rectangle       rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6477                         bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
6478                         
6479                         if ((style & Border3DStyle.Adjust) != 0) {
6480                                 rect.Y -= 2;
6481                                 rect.X -= 2;
6482                                 rect.Width += 4;
6483                                 rect.Height += 4;
6484                         }
6485                         
6486                         penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color);
6487                         
6488                         CPColor cpcolor = CPColor.Empty;
6489                         
6490                         if (!is_ColorControl)
6491                                 cpcolor = ResPool.GetCPColor (control_color);
6492                         
6493                         switch (style) {
6494                         case Border3DStyle.Raised:
6495                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6496                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6497                                 penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6498                                 break;
6499                         case Border3DStyle.Sunken:
6500                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6501                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6502                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6503                                 break;
6504                         case Border3DStyle.Etched:
6505                                 penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6506                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6507                                 break;
6508                         case Border3DStyle.RaisedOuter:
6509                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6510                                 break;
6511                         case Border3DStyle.SunkenOuter:
6512                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6513                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6514                                 break;
6515                         case Border3DStyle.RaisedInner:
6516                                 penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
6517                                 penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6518                                 break;
6519                         case Border3DStyle.SunkenInner:
6520                                 penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6521                                 break;
6522                         case Border3DStyle.Flat:
6523                                 penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
6524                                 break;
6525                         case Border3DStyle.Bump:
6526                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
6527                                 break;
6528                         default:
6529                                 break;
6530                         }
6531                         
6532                         bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter));
6533                         
6534                         if ((sides & Border3DSide.Middle) != 0) {
6535                                 Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color);
6536                                 graphics.FillRectangle (brush, rect);
6537                         }
6538                         
6539                         if ((sides & Border3DSide.Left) != 0) {
6540                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top);
6541                                 if ((rect.Width > 2) && inner)
6542                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top);
6543                         }
6544                         
6545                         if ((sides & Border3DSide.Top) != 0) {
6546                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top);
6547                                 if ((rect.Height > 2) && inner)
6548                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1);
6549                         }
6550                         
6551                         if ((sides & Border3DSide.Right) != 0) {
6552                                 graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
6553                                 if ((rect.Width > 3) && inner)
6554                                         graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2);
6555                         }
6556                         
6557                         if ((sides & Border3DSide.Bottom) != 0) {
6558                                 graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6559                                 if ((rect.Height > 3) && inner)
6560                                         graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
6561                         }
6562                 }
6563
6564                 public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
6565                 {
6566                         CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight);
6567                 }
6568
6569                 private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)
6570                 {
6571                         // sadly enough, the rectangle gets always filled with a hatchbrush
6572                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6573                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6574                                                                                  ColorControl.G, ColorControl.B),
6575                                                                  ColorControl),
6576                                           rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2);
6577                         
6578                         if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) {
6579                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6580                                 
6581                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6582                         } else
6583                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6584                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
6585                         } else
6586                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6587                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
6588                                 
6589                                 Pen pen = DarkPen;
6590                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6591                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6592                                 
6593                                 pen = NormalPen;
6594                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6595                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6596                                 
6597                                 pen = LightPen;
6598                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6599                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6600                         } else
6601                         if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) {
6602                                 Pen pen = DarkPen;
6603                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6604                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6605                                 
6606                                 pen = NormalPen;
6607                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
6608                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
6609                                 
6610                                 pen = LightPen;
6611                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
6612                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
6613                         } else
6614                         if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) {
6615                                 Pen pen = LightPen;
6616                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y);
6617                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
6618                                 
6619                                 pen = NormalPen;
6620                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2);
6621                                 dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3);
6622                                 
6623                                 pen = DarkPen;
6624                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1);
6625                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2);
6626                         }
6627                 }
6628
6629
6630                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
6631                         Rectangle       captionRect;
6632                         int                     lineWidth;
6633
6634                         CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight);
6635
6636                         if (rectangle.Width<rectangle.Height) {
6637                                 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
6638                         } else {
6639                                 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
6640                         }
6641
6642                         if ((state & ButtonState.Pushed)!=0) {
6643                                 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
6644                         }
6645
6646                         /* Make sure we've got at least a line width of 1 */
6647                         lineWidth=Math.Max(1, captionRect.Width/7);
6648
6649                         switch(button) {
6650                         case CaptionButton.Close: {
6651                                 Pen     pen;
6652
6653                                 if ((state & ButtonState.Inactive)!=0) {
6654                                         pen = ResPool.GetSizedPen (ColorControlLight, lineWidth);
6655                                         DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
6656
6657                                         pen = ResPool.GetSizedPen (ColorControlDark, lineWidth);
6658                                         DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
6659                                         return;
6660                                 } else {
6661                                         pen = ResPool.GetSizedPen (ColorControlText, lineWidth);
6662                                         DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
6663                                         return;
6664                                 }
6665                         }
6666
6667                         case CaptionButton.Help:
6668                         case CaptionButton.Maximize:
6669                         case CaptionButton.Minimize:
6670                         case CaptionButton.Restore: {
6671                                 if ((state & ButtonState.Inactive)!=0) {
6672                                         DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
6673
6674                                         DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
6675                                         return;
6676                                 } else {
6677                                         DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
6678                                         return;
6679                                 }
6680                         }
6681                         }
6682                 }
6683
6684                 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
6685                 {
6686                         CPDrawCheckBoxInternal (dc, rectangle, state, false /* mixed */);
6687                 }
6688
6689                 private void CPDrawCheckBoxInternal (Graphics dc, Rectangle rectangle, ButtonState state, bool mixed)
6690                 {
6691                         Pen check_pen = (mixed) ? Pens.Gray : Pens.Black;
6692                         
6693                         Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
6694                         
6695                         if ((state & ButtonState.All) == ButtonState.All) {
6696                                 cb_rect.Width -= 2;
6697                                 cb_rect.Height -= 2;
6698                                 
6699                                 dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6700                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6701                                 
6702                                 check_pen = SystemPens.ControlDark;
6703                         } else
6704                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6705                                 cb_rect.Width -= 2;
6706                                 cb_rect.Height -= 2;
6707                                 
6708                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6709                                         dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6710                                 else
6711                                         dc.FillRectangle (Brushes.White, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6712                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
6713                         } else {
6714                                 cb_rect.Width -= 1;
6715                                 cb_rect.Height -= 1;
6716                                 
6717                                 int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height;
6718                                 
6719                                 int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2);
6720                                 int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2);
6721                                 
6722                                 Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
6723                                 
6724                                 if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) {
6725                                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
6726                                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6727                                                                                                  ColorControl.G, ColorControl.B),
6728                                                                                  ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6729                                 } else
6730                                         dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
6731                                 
6732                                 Pen pen = SystemPens.ControlDark;
6733                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1);
6734                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y);
6735                                 
6736                                 pen = SystemPens.ControlDarkDark;
6737                                 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2);
6738                                 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1);
6739                                 
6740                                 pen = SystemPens.ControlLightLight;
6741                                 dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom);
6742                                 dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom);
6743                                 
6744                                 // oh boy, matching ms is like fighting against windmills
6745                                 using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
6746                                                                                    Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6747                                                                                                    ColorControl.G, ColorControl.B), ColorControl))) {
6748                                         dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
6749                                         dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1);
6750                                 }
6751                                 
6752                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6753                                         check_pen = SystemPens.ControlDark;
6754                         }
6755                         
6756                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6757                                 int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2;
6758                                 
6759                                 if (check_size < 7) {
6760                                         int lineWidth = Math.Max (3, check_size / 3);
6761                                         int Scale = Math.Max (1, check_size / 9);
6762                                         
6763                                         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, 
6764                                                                         check_size, check_size);
6765                                         
6766                                         for (int i = 0; i < lineWidth; i++) {
6767                                                 dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
6768                                                 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);
6769                                         }
6770                                 } else {
6771                                         int lineWidth = Math.Max (3, check_size / 3) + 1;
6772                                         
6773                                         int x_half = cb_rect.Width / 2;
6774                                         int y_half = cb_rect.Height / 2;
6775                                         
6776                                         Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2), 
6777                                                                         check_size, check_size);
6778                                         
6779                                         int gradient_left = check_size / 3;
6780                                         int gradient_right = check_size - gradient_left - 1;
6781                                         
6782                                         
6783                                         for (int i = 0; i < lineWidth; i++) {
6784                                                 dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
6785                                                 dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i  - 1 - gradient_right);
6786                                         }
6787                                 }
6788                         }
6789                 }
6790
6791                 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
6792                         Point[]                 arrow = new Point[3];
6793                         Point                           P1;
6794                         Point                           P2;
6795                         Point                           P3;
6796                         int                             centerX;
6797                         int                             centerY;
6798                         int                             shiftX;
6799                         int                             shiftY;
6800                         Rectangle               rect;
6801
6802                         if ((state & ButtonState.Checked)!=0) {
6803                                 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);                              
6804                         }
6805
6806                         if ((state & ButtonState.Flat)!=0) {
6807                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
6808                         } else {
6809                                 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
6810                                         // this needs to render like a pushed button - jba
6811                                         // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6812                                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6813                                         graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle);
6814                                 } else {
6815                                         CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6816                                 }
6817                         }
6818
6819                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
6820                         centerX=rect.Left+rect.Width/2;
6821                         centerY=rect.Top+rect.Height/2;
6822                         shiftX=Math.Max(1, rect.Width/8);
6823                         shiftY=Math.Max(1, rect.Height/8);
6824
6825                         if ((state & ButtonState.Pushed)!=0) {
6826                                 shiftX++;
6827                                 shiftY++;
6828                         }
6829
6830                         rect.Y-=shiftY;
6831                         centerY-=shiftY;
6832                         P1=new Point(rect.Left, centerY);
6833                         P2=new Point(rect.Right, centerY);
6834                         P3=new Point(centerX, rect.Bottom);
6835
6836                         arrow[0]=P1;
6837                         arrow[1]=P2;
6838                         arrow[2]=P3;
6839                         
6840                         /* Draw the arrow */
6841                         if ((state & ButtonState.Inactive)!=0) {
6842                                 /* Move away from the shadow */
6843                                 arrow[0].X += 1;        arrow[0].Y += 1;
6844                                 arrow[1].X += 1;        arrow[1].Y += 1;
6845                                 arrow[2].X += 1;        arrow[2].Y += 1;
6846                                 
6847                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
6848
6849                                 arrow[0]=P1;
6850                                 arrow[1]=P2;
6851                                 arrow[2]=P3;
6852
6853                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
6854                         } else {
6855                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
6856                         }
6857                 }
6858
6859
6860                 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds)
6861                 {
6862                         Pen                     pen     = Pens.Black;
6863                         Rectangle       rect    = new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);      // Dunno why, but MS does it that way, too
6864                         int                     X;
6865                         int                     Y;
6866                         
6867                         graphics.FillRectangle (SystemBrushes.ControlLightLight, rect);
6868                         graphics.DrawRectangle (pen, rect);
6869                         
6870                         X = rect.X + rect.Width / 2;
6871                         Y = rect.Y + rect.Height / 2;
6872                         
6873                         /* Draw the cross */
6874                         graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2);
6875                         graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y);
6876                         
6877                         /* Draw 'arrows' for vertical lines */
6878                         graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3);
6879                         graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3);
6880                         
6881                         /* Draw 'arrows' for horizontal lines */
6882                         graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1);
6883                         graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1);
6884                 }
6885
6886                 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
6887                         // make a rectange to trace around border of the button
6888                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6889                         
6890                         Color outerColor = foreColor;
6891                         // adjust focus color according to the flatstyle
6892                         if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
6893                                 outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;                              
6894                         }
6895                         
6896                         // draw the outer rectangle
6897                         graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);                  
6898                         
6899                         // draw the inner rectangle                                             
6900                         if (button.FlatStyle == FlatStyle.Popup) {
6901                                 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
6902                         } else {
6903                                 // draw a flat inner rectangle
6904                                 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
6905                                 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));                               
6906                         }
6907                 }
6908                 
6909                 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
6910                 {       
6911                         // make a rectange to trace around border of the button
6912                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6913                         
6914 #if NotUntilCairoIsFixed
6915                         Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6916                         DashStyle oldStyle; // used for caching old penstyle
6917                         Pen pen = ResPool.GetPen (colorBackInverted);
6918
6919                         oldStyle = pen.DashStyle; 
6920                         pen.DashStyle = DashStyle.Dot;
6921
6922                         graphics.DrawRectangle (pen, trace_rectangle);
6923                         pen.DashStyle = oldStyle;
6924 #else
6925                         CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
6926 #endif
6927                 }
6928                                 
6929
6930                 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) 
6931                 {                       
6932                         Rectangle rect = rectangle;
6933                         Pen pen;
6934                         HatchBrush brush;
6935                                 
6936                         if (backColor.GetBrightness () >= 0.5) {
6937                                 foreColor = Color.Transparent;
6938                                 backColor = Color.Black;
6939                                 
6940                         } else {
6941                                 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6942                                 foreColor = Color.Black;
6943                         }
6944                                                 
6945                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
6946                         pen = new Pen (brush, 1);
6947                                                 
6948                         rect.Width--;
6949                         rect.Height--;                  
6950                         
6951                         graphics.DrawRectangle (pen, rect);
6952                         pen.Dispose ();
6953                 }
6954                 
6955                 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled)
6956                 {
6957                         Brush   sb;
6958                         Pen pen;
6959                         
6960                         if (primary == true) {
6961                                 pen = Pens.Black;
6962                                 if (enabled == true) {
6963                                         sb = Brushes.White;
6964                                 } else {
6965                                         sb = SystemBrushes.Control;
6966                                 }
6967                         } else {
6968                                 pen = Pens.White;
6969                                 if (enabled == true) {
6970                                         sb = Brushes.Black;
6971                                 } else {
6972                                         sb = SystemBrushes.Control;
6973                                 }
6974                         }
6975                         graphics.FillRectangle (sb, rectangle);
6976                         graphics.DrawRectangle (pen, rectangle);                        
6977                 }
6978
6979
6980                 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
6981                         Color   foreColor;
6982                         int     h;
6983                         int     b;
6984                         int     s;
6985
6986                         ControlPaint.Color2HBS(backColor, out h, out b, out s);
6987                         
6988                         if (b>127) {
6989                                 foreColor=Color.Black;
6990                         } else {
6991                                 foreColor=Color.White;
6992                         }
6993
6994                         // still not perfect. it seems that ms calculates the position of the first dot or line
6995
6996                         using (Pen pen = new Pen (foreColor)) {
6997                                 pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
6998                                 
6999                                 for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
7000                                         graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
7001                         }
7002                 }
7003
7004                 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
7005                         /*
7006                                 Microsoft seems to ignore the background and simply make
7007                                 the image grayscale. At least when having > 256 colors on
7008                                 the display.
7009                         */
7010                         
7011                         if (imagedisabled_attributes == null) {                         
7012                                 imagedisabled_attributes = new ImageAttributes ();
7013                                 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
7014                                           // This table would create a perfect grayscale image, based on luminance
7015                                           //                            new float[]{0.3f,0.3f,0.3f,0,0},
7016                                           //                            new float[]{0.59f,0.59f,0.59f,0,0},
7017                                           //                            new float[]{0.11f,0.11f,0.11f,0,0},
7018                                           //                            new float[]{0,0,0,1,0,0},
7019                                           //                            new float[]{0,0,0,0,1,0},
7020                                           //                            new float[]{0,0,0,0,0,1}
7021                 
7022                                           // This table generates a image that is grayscaled and then
7023                                           // brightened up. Seems to match MS close enough.
7024                                           new float[]{0.2f,0.2f,0.2f,0,0},
7025                                           new float[]{0.41f,0.41f,0.41f,0,0},
7026                                           new float[]{0.11f,0.11f,0.11f,0,0},
7027                                           new float[]{0.15f,0.15f,0.15f,1,0,0},
7028                                           new float[]{0.15f,0.15f,0.15f,0,1,0},
7029                                           new float[]{0.15f,0.15f,0.15f,0,0,1}
7030                                   });
7031                                   
7032                                  imagedisabled_attributes.SetColorMatrix (colorMatrix);
7033                         }
7034                         
7035                         graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
7036                         
7037                 }
7038
7039
7040                 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
7041                         Pen     penBorder;
7042                         Pen     penInside;
7043
7044                         if (primary) {
7045                                 penBorder = ResPool.GetSizedPen (Color.White, 2);
7046                                 penInside = ResPool.GetPen (Color.Black);
7047                         } else {
7048                                 penBorder = ResPool.GetSizedPen (Color.Black, 2);
7049                                 penInside = ResPool.GetPen (Color.White);
7050                         }
7051                         penBorder.Alignment=PenAlignment.Inset;
7052                         penInside.Alignment=PenAlignment.Inset;
7053
7054                         graphics.DrawRectangle(penBorder, rectangle);
7055                         graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
7056                 }
7057
7058
7059                 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color, Color backColor) {
7060                         Rectangle       rect;
7061                         int                     lineWidth;
7062
7063                         if (backColor != Color.Empty)
7064                                 graphics.FillRectangle (ResPool.GetSolidBrush (backColor), rectangle);
7065                                 
7066                         Brush brush = ResPool.GetSolidBrush (color);
7067
7068                         switch(glyph) {
7069                         case MenuGlyph.Arrow: {
7070                                 float height = rectangle.Height * 0.7f;
7071                                 float width  = height / 2.0f;
7072                                 
7073                                 PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f));
7074
7075                                 PointF [] vertices = new PointF [3];
7076                                 vertices [0].X = ddCenter.X;
7077                                 vertices [0].Y = ddCenter.Y - (height / 2.0f);
7078                                 vertices [1].X = ddCenter.X;
7079                                 vertices [1].Y = ddCenter.Y + (height / 2.0f);
7080                                 vertices [2].X = ddCenter.X + width + 0.1f;
7081                                 vertices [2].Y = ddCenter.Y;
7082                                 
7083                                 graphics.FillPolygon (brush, vertices);
7084
7085                                 return;
7086                         }
7087
7088                         case MenuGlyph.Bullet: {
7089                                 
7090                                 lineWidth=Math.Max(2, rectangle.Width/3);
7091                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
7092                                 
7093                                 graphics.FillEllipse(brush, rect);
7094                                 
7095                                 return;
7096                         }
7097
7098                         case MenuGlyph.Checkmark: {
7099                                 
7100                                 Pen pen = ResPool.GetPen (color);
7101                                 lineWidth = Math.Max (2, rectangle.Width / 6);
7102                                 rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2);
7103
7104                                 int Scale = Math.Max (1, rectangle.Width / 12);
7105                                 int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2));
7106
7107                                 for (int i=0; i<lineWidth; i++) {
7108                                         graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i);
7109                                         graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i);
7110                                 }
7111                                 return;
7112                         }
7113                         }
7114
7115                 }
7116
7117                 public override void CPDrawMixedCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state)
7118                 {
7119                         CPDrawCheckBoxInternal (graphics, rectangle, state, true /* mixed */);
7120                 }
7121
7122                 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
7123                 {
7124                         CPColor cpcolor = ResPool.GetCPColor (ColorControl);
7125                         
7126                         Color dot_color = Color.Black;
7127                         
7128                         Color top_left_outer = Color.Black;
7129                         Color top_left_inner = Color.Black;
7130                         Color bottom_right_outer = Color.Black;
7131                         Color bottom_right_inner = Color.Black;
7132                         
7133                         int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height  * 0.9f) : (int)(rectangle.Width * 0.9f);
7134                         int radius = ellipse_diameter / 2;
7135                         
7136                         Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter);
7137                         
7138                         Brush brush = null;
7139                         
7140                         if ((state & ButtonState.All) == ButtonState.All) {
7141                                 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
7142                                                                                                      ColorControl.G, ColorControl.B), ColorControl);
7143                                 dot_color = cpcolor.Dark;
7144                         } else
7145                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
7146                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7147                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7148                                 else
7149                                         brush = SystemBrushes.ControlLightLight;
7150                         } else {
7151                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
7152                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
7153                                 else
7154                                         brush = SystemBrushes.ControlLightLight;
7155                                 
7156                                 top_left_outer = cpcolor.Dark;
7157                                 top_left_inner = cpcolor.DarkDark;
7158                                 bottom_right_outer = cpcolor.Light;
7159                                 bottom_right_inner = Color.Transparent;
7160                                 
7161                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
7162                                         dot_color = cpcolor.Dark;
7163                         }
7164                         
7165                         dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1);
7166                         
7167                         int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f));
7168                         
7169                         dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f);
7170                         dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f);
7171                         dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f);
7172                         
7173                         if (bottom_right_inner != Color.Transparent)
7174                                 dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7175                         else
7176                                 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)) {
7177                                         dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
7178                                 }
7179                         
7180                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
7181                                 int inflate = line_width * 4;
7182                                 Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate);
7183                                 if (rectangle.Height >  13) {
7184                                         tmp.X += 1;
7185                                         tmp.Y += 1;
7186                                         tmp.Height -= 1;
7187                                         dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp);
7188                                 } else {
7189                                         Pen pen = ResPool.GetPen (dot_color);
7190                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2));
7191                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1);
7192                                         
7193                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom);
7194                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom);
7195                                 }
7196                         }
7197                 }
7198
7199                 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
7200
7201                 }
7202
7203
7204                 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
7205
7206                 }
7207
7208
7209                 /* Scroll button: regular button + direction arrow */
7210                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
7211                 {
7212                         DrawScrollButtonPrimitive (dc, area, state);
7213                         
7214                         bool fill_rect = true;
7215                         int offset = 0;
7216                         
7217                         if ((state & ButtonState.Pushed) != 0)
7218                                 offset = 1;
7219                         
7220                         // skip the border
7221                         Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
7222                         
7223                         Point [] arrow = new Point [3];
7224                         for (int i = 0; i < 3; i++)
7225                                 arrow [i] = new Point ();
7226                         
7227                         Pen pen = SystemPens.ControlText;
7228                         
7229                         if ((state & ButtonState.Inactive) != 0) {
7230                                 pen = SystemPens.ControlDark;
7231                         }
7232                         
7233                         switch (type) {
7234                                 default:
7235                                 case ScrollButton.Down:
7236                                         int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7237                                         int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7238                                         if (x_middle == 1)
7239                                                 x_middle = 2;
7240                                         
7241                                         int triangle_height;
7242                                         
7243                                         if (rect.Height < 8) {
7244                                                 triangle_height = 2;
7245                                                 fill_rect = false;
7246                                         } else if (rect.Height == 11) {
7247                                                 triangle_height = 3;
7248                                         } else {
7249                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7250                                         }
7251                                         
7252                                         arrow [0].X = rect.X + x_middle;
7253                                         arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
7254                                         
7255                                         arrow [1].X = arrow [0].X + triangle_height - 1;
7256                                         arrow [1].Y = arrow [0].Y - triangle_height + 1;
7257                                         arrow [2].X = arrow [0].X - triangle_height + 1;
7258                                         arrow [2].Y = arrow [1].Y;
7259                                         
7260                                         dc.DrawPolygon (pen, arrow);
7261                                         
7262                                         if ((state & ButtonState.Inactive) != 0) {
7263                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
7264                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
7265                                         }
7266                                         
7267                                         if (fill_rect) {
7268                                                 for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
7269                                                         dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
7270                                                         arrow [1].X -= 1;
7271                                                         arrow [2].X += 1;
7272                                                 }
7273                                         }
7274                                         break;
7275                                         
7276                                 case ScrollButton.Up:
7277                                         x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
7278                                         y_middle = (int)Math.Round (rect.Height / 2.0f);
7279                                         if (x_middle == 1)
7280                                                 x_middle = 2;
7281                                         
7282                                         if (y_middle == 1)
7283                                                 y_middle = 2;
7284                                         
7285                                         if (rect.Height < 8) {
7286                                                 triangle_height = 2;
7287                                                 fill_rect = false;
7288                                         } else if (rect.Height == 11) {
7289                                                 triangle_height = 3;
7290                                         } else {
7291                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
7292                                         }
7293                                         
7294                                         arrow [0].X = rect.X + x_middle;
7295                                         arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
7296                                         
7297                                         arrow [1].X = arrow [0].X + triangle_height - 1;
7298                                         arrow [1].Y = arrow [0].Y + triangle_height - 1;
7299                                         arrow [2].X = arrow [0].X - triangle_height + 1;
7300                                         arrow [2].Y = arrow [1].Y;
7301                                         
7302                                         dc.DrawPolygon (pen, arrow);
7303                                         
7304                                         if ((state & ButtonState.Inactive) != 0) {
7305                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
7306                                         }
7307                                         
7308                                         if (fill_rect) {
7309                                                 for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
7310                                                         dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
7311                                                         arrow [1].X -= 1;
7312                                                         arrow [2].X += 1;
7313                                                 }
7314                                         }
7315                                         break;
7316                                         
7317                                 case ScrollButton.Left:
7318                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7319                                         if (y_middle == 1)
7320                                                 y_middle = 2;
7321                                         
7322                                         int triangle_width;
7323                                         
7324                                         if (rect.Width < 8) {
7325                                                 triangle_width = 2;
7326                                                 fill_rect = false;
7327                                         } else if (rect.Width == 11) {
7328                                                 triangle_width = 3;
7329                                         } else {
7330                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7331                                         }
7332                                         
7333                                         arrow [0].X = rect.Left + triangle_width - 1;
7334                                         arrow [0].Y = rect.Y + y_middle;
7335                                         
7336                                         if (arrow [0].X - 1 == rect.X)
7337                                                 arrow [0].X += 1;
7338                                         
7339                                         arrow [1].X = arrow [0].X + triangle_width - 1;
7340                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7341                                         arrow [2].X = arrow [1].X;
7342                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7343                                         
7344                                         dc.DrawPolygon (pen, arrow);
7345                                         
7346                                         if ((state & ButtonState.Inactive) != 0) {
7347                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7348                                         }
7349                                         
7350                                         if (fill_rect) {
7351                                                 for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
7352                                                         dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
7353                                                         arrow [1].Y += 1;
7354                                                         arrow [2].Y -= 1;
7355                                                 }
7356                                         }
7357                                         break;
7358                                         
7359                                 case ScrollButton.Right:
7360                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
7361                                         if (y_middle == 1)
7362                                                 y_middle = 2;
7363                                         
7364                                         if (rect.Width < 8) {
7365                                                 triangle_width = 2;
7366                                                 fill_rect = false;
7367                                         } else if (rect.Width == 11) {
7368                                                 triangle_width = 3;
7369                                         } else {
7370                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
7371                                         }
7372                                         
7373                                         arrow [0].X = rect.Right - triangle_width - 1;
7374                                         arrow [0].Y = rect.Y + y_middle;
7375                                         
7376                                         if (arrow [0].X - 1 == rect.X)
7377                                                 arrow [0].X += 1;
7378                                         
7379                                         arrow [1].X = arrow [0].X - triangle_width + 1;
7380                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
7381                                         arrow [2].X = arrow [1].X;
7382                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
7383                                         
7384                                         dc.DrawPolygon (pen, arrow);
7385                                         
7386                                         if ((state & ButtonState.Inactive) != 0) {
7387                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
7388                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
7389                                         }
7390                                         
7391                                         if (fill_rect) {
7392                                                 for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
7393                                                         dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
7394                                                         arrow [1].Y += 1;
7395                                                         arrow [2].Y -= 1;
7396                                                 }
7397                                         }
7398                                         break;
7399                         }
7400                 }
7401
7402                 public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
7403                         Color backColor) {
7404
7405                 }
7406
7407
7408                 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds)
7409                 {
7410                         Pen pen_dark = ResPool.GetPen(ControlPaint.Dark(backColor));
7411                         Pen pen_light_light = ResPool.GetPen(ControlPaint.LightLight(backColor));
7412                         
7413                         for (int i = 2; i < bounds.Width - 2; i += 4) {
7414                                 dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1);
7415                                 dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i);
7416                                 dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1);
7417                         }
7418                 }
7419
7420                 private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)
7421                 {
7422                         CPColor cpcolor = ResPool.GetCPColor (color);
7423
7424                         layoutRectangle.Offset (1, 1);
7425                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString);
7426
7427                         layoutRectangle.Offset (-1, -1);
7428                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString);
7429                 }
7430
7431                 public  override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)
7432                 {
7433                         CPColor cpcolor = ResPool.GetCPColor (color);
7434                         
7435                         dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight), 
7436                                        new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height),
7437                                        format);
7438                         dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
7439                 }
7440
7441                 public override void CPDrawStringDisabled (IDeviceContext dc, string s, Font font, Color color, Rectangle layoutRectangle, TextFormatFlags format)
7442                 {
7443                         CPColor cpcolor = ResPool.GetCPColor (color);
7444
7445                         layoutRectangle.Offset (1, 1);
7446                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.LightLight, format);
7447
7448                         layoutRectangle.Offset (-1, -1);
7449                         TextRenderer.DrawText (dc, s, font, layoutRectangle, cpcolor.Dark, format);
7450                 }
7451
7452                 public override void CPDrawVisualStyleBorder (Graphics graphics, Rectangle bounds)
7453                 {
7454                         graphics.DrawRectangle (SystemPens.ControlDarkDark, bounds);
7455                 }
7456
7457                 private static void DrawBorderInternal (Graphics graphics, int startX, int startY, int endX, int endY,
7458                         int width, Color color, ButtonBorderStyle style, Border3DSide side) 
7459                 {
7460                         DrawBorderInternal (graphics, (float) startX, (float) startY, (float) endX, (float) endY, 
7461                                 width, color, style, side);
7462                 }
7463
7464                 private static void DrawBorderInternal (Graphics graphics, float startX, float startY, float endX, float endY,
7465                         int width, Color color, ButtonBorderStyle style, Border3DSide side) {
7466
7467                         Pen pen = null;
7468
7469                         switch (style) {
7470                         case ButtonBorderStyle.Solid:
7471                         case ButtonBorderStyle.Inset:
7472                         case ButtonBorderStyle.Outset:
7473                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid);
7474                                         break;
7475                         case ButtonBorderStyle.Dashed:
7476                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash);
7477                                         break;
7478                         case ButtonBorderStyle.Dotted:
7479                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot);
7480                                         break;
7481                         default:
7482                         case ButtonBorderStyle.None:
7483                                         return;
7484                         }
7485
7486                         switch(style) {
7487                         case ButtonBorderStyle.Outset: {
7488                                 Color           colorGrade;
7489                                 int             hue, brightness, saturation;
7490                                 int             brightnessSteps;
7491                                 int             brightnessDownSteps;
7492
7493                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7494
7495                                 brightnessDownSteps=brightness/width;
7496                                 if (brightness>127) {
7497                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7498                                 } else {
7499                                         brightnessSteps=(127-brightness)/width;
7500                                 }
7501
7502                                 for (int i=0; i<width; i++) {
7503                                         switch(side) {
7504                                         case Border3DSide.Left: {
7505                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
7506                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7507                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7508                                                 break;
7509                                         }
7510
7511                                         case Border3DSide.Right: {
7512                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(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.Top: {
7519                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(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.Bottom: {
7526                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(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                                 }
7533                                 break;
7534                         }
7535
7536                         case ButtonBorderStyle.Inset: {
7537                                 Color           colorGrade;
7538                                 int             hue, brightness, saturation;
7539                                 int             brightnessSteps;
7540                                 int             brightnessDownSteps;
7541
7542                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
7543
7544                                 brightnessDownSteps=brightness/width;
7545                                 if (brightness>127) {
7546                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
7547                                 } else {
7548                                         brightnessSteps=(127-brightness)/width;
7549                                 }
7550
7551                                 for (int i=0; i<width; i++) {
7552                                         switch(side) {
7553                                         case Border3DSide.Left: {
7554                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
7555                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
7556                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7557                                                 break;
7558                                         }
7559
7560                                         case Border3DSide.Right: {
7561                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(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.Top: {
7568                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(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.Bottom: {
7575                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(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                                 }
7582                                 break;
7583                         }
7584
7585                                 /*
7586                                         I decided to have the for-loop duplicated for speed reasons;
7587                                         that way we only have to switch once (as opposed to have the
7588                                         for-loop around the switch)
7589                                 */
7590                         default: {
7591                                 switch(side) {
7592                                 case Border3DSide.Left: {
7593                                         for (int i=0; i<width; i++) {
7594                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
7595                                         }
7596                                         break;
7597                                 }
7598
7599                                 case Border3DSide.Right: {
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.Top: {
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.Bottom: {
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                                 break;
7621                         }
7622                         }
7623                 }
7624
7625                 /*
7626                         This function actually draws the various caption elements.
7627                         This way we can scale them nicely, no matter what size, and they
7628                         still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
7629                 */
7630
7631                 private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
7632                         switch(button) {
7633                         case CaptionButton.Close: {
7634                                 if (lineWidth<2) {
7635                                         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);
7636                                         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);
7637                                 }
7638
7639                                 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7640                                 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
7641                                 return;
7642                         }
7643
7644                         case CaptionButton.Help: {
7645                                 StringFormat    sf = new StringFormat();                                
7646                                 Font                            font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
7647
7648                                 sf.Alignment=StringAlignment.Center;
7649                                 sf.LineAlignment=StringAlignment.Center;
7650
7651
7652                                 graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
7653
7654                                 sf.Dispose();                           
7655                                 font.Dispose();
7656
7657                                 return;
7658                         }
7659
7660                         case CaptionButton.Maximize: {
7661                                 /* Top 'caption bar' line */
7662                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7663                                         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);
7664                                 }
7665
7666                                 /* Left side line */
7667                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7668                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7669                                 }
7670
7671                                 /* Right side line */
7672                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7673                                         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);
7674                                 }
7675
7676                                 /* Bottom line */
7677                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7678                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7679                                 }
7680                                 return;
7681                         }
7682
7683                         case CaptionButton.Minimize: {
7684                                 /* Bottom line */
7685                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7686                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
7687                                 }
7688                                 return;
7689                         }
7690
7691                         case CaptionButton.Restore: {
7692                                 /** First 'window' **/
7693                                 /* Top 'caption bar' line */
7694                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7695                                         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);
7696                                 }
7697
7698                                 /* Left side line */
7699                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7700                                         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);
7701                                 }
7702
7703                                 /* Right side line */
7704                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7705                                         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);
7706                                 }
7707
7708                                 /* Bottom line */
7709                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7710                                         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);
7711                                 }
7712
7713                                 /** Second 'window' **/
7714                                 /* Top 'caption bar' line */
7715                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
7716                                         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);
7717                                 }
7718
7719                                 /* Left side line */
7720                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7721                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
7722                                 }
7723
7724                                 /* Right side line */
7725                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7726                                         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);
7727                                 }
7728
7729                                 /* Bottom line */
7730                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
7731                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
7732                                 }
7733
7734                                 return;
7735                         }
7736
7737                         }
7738                 }
7739
7740                 /* Generic scroll button */
7741                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
7742                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
7743                                 dc.FillRectangle (SystemBrushes.Control, area.X + 1,
7744                                         area.Y + 1, area.Width - 2 , area.Height - 2);
7745
7746                                 dc.DrawRectangle (SystemPens.ControlDark, area.X,
7747                                         area.Y, area.Width, area.Height);
7748
7749                                 return;
7750                         }                       
7751         
7752                         Brush sb_control = SystemBrushes.Control;
7753                         Brush sb_lightlight = SystemBrushes.ControlLightLight;
7754                         Brush sb_dark = SystemBrushes.ControlDark;
7755                         Brush sb_darkdark = SystemBrushes.ControlDarkDark;
7756                         
7757                         dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1);
7758                         dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height);
7759
7760                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1);
7761                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1,
7762                                 area.Height - 4);
7763                         
7764                         dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2,
7765                                 area.Width - 2, 1);
7766
7767                         dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1,
7768                                 area.Width , 1);
7769
7770                         dc.FillRectangle (sb_dark, area.X + area.Width - 2,
7771                                 area.Y + 1, 1, area.Height -3);
7772
7773                         dc.FillRectangle (sb_darkdark, area.X + area.Width -1,
7774                                 area.Y, 1, area.Height - 1);
7775
7776                         dc.FillRectangle (sb_control, area.X + 2,
7777                                 area.Y + 2, area.Width - 4, area.Height - 4);
7778                         
7779                 }
7780                 
7781                 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
7782                         switch (border_style){
7783                         case BorderStyle.Fixed3D:
7784                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
7785                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
7786                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width , 
7787                                         area.Y + area.Height - 1);
7788                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, 
7789                                         area.Y + area.Height);
7790
7791                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
7792                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
7793                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
7794                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
7795                                 break;
7796                         case BorderStyle.FixedSingle:
7797                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
7798                                 break;
7799                         case BorderStyle.None:
7800                         default:
7801                                 break;
7802                         }
7803                         
7804                 }
7805                 #endregion      // ControlPaint
7806
7807
7808         } //class
7809 }