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