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