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