2007-03-29 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 tab
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.Pressed)
201                                 textBounds.Offset (1, 1);
202                                                         
203                         if (button.Enabled)
204                                 TextRenderer.DrawTextInternal (g, button.Text, button.Font, textBounds, button.ForeColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
205                         else
206                                 DrawStringDisabled20 (g, button.Text, button.Font, textBounds, button.BackColor, button.TextFormatFlags, button.UseCompatibleTextRendering);
207                 }
208                 #endregion
209
210                 #region FlatStyle Button Style
211                 public override void DrawFlatButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
212                 {
213                         // Draw Button Background
214                         DrawFlatButtonBackground (g, b, clipRectangle);
215
216                         // If we have an image, draw it
217                         if (imageBounds.Size != Size.Empty)
218                                 DrawFlatButtonImage (g, b, imageBounds);
219
220                         // If we're focused, draw a focus rectangle
221                         if (b.Focused && b.Enabled)
222                                 DrawFlatButtonFocus (g, b);
223
224                         // If we have text, draw it
225                         if (textBounds != Rectangle.Empty)
226                                 DrawFlatButtonText (g, b, textBounds);
227                 }
228
229                 public virtual void DrawFlatButtonBackground (Graphics g, Button button, Rectangle clipArea)
230                 {
231                         if (button.Pressed)
232                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor, button.FlatAppearance);
233                         else if (button.InternalSelected)
234                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor, button.FlatAppearance);
235                         else if (button.Entered)
236                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor, button.FlatAppearance);
237                         else if (!button.Enabled)
238                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor, button.FlatAppearance);
239                         else
240                                 ThemeElements.DrawFlatButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor, button.FlatAppearance);
241                 }
242
243                 public virtual void DrawFlatButtonFocus (Graphics g, Button button)
244                 {
245                         if (!button.Pressed) {
246                                 Color focus_color = ControlPaint.Light(button.BackColor);
247                                 g.DrawRectangle (ResPool.GetPen (focus_color), new Rectangle (button.ClientRectangle.Left + 4, button.ClientRectangle.Top + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9));
248                         }
249                 }
250
251                 public virtual void DrawFlatButtonImage (Graphics g, Button button, Rectangle imageBounds)
252                 {
253                         // No changes from Standard for image for this theme
254                         DrawButtonImage (g, button, imageBounds);
255                 }
256
257                 public virtual void DrawFlatButtonText (Graphics g, Button button, Rectangle textBounds)
258                 {
259                         // No changes from Standard for image for this theme
260                         DrawButtonText (g, button, textBounds);
261                 }
262                 #endregion
263
264                 #region Popup Button Style
265                 public override void DrawPopupButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle)
266                 {
267                         // Draw Button Background
268                         DrawPopupButtonBackground (g, b, clipRectangle);
269
270                         // If we have an image, draw it
271                         if (imageBounds.Size != Size.Empty)
272                                 DrawPopupButtonImage (g, b, imageBounds);
273
274                         // If we're focused, draw a focus rectangle
275                         if (b.Focused && b.Enabled)
276                                 DrawPopupButtonFocus (g, b);
277
278                         // If we have text, draw it
279                         if (textBounds != Rectangle.Empty)
280                                 DrawPopupButtonText (g, b, textBounds);
281                 }
282
283                 public virtual void DrawPopupButtonBackground (Graphics g, Button button, Rectangle clipArea)
284                 {
285                         if (button.Pressed)
286                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Pressed, button.BackColor, button.ForeColor);
287                         else if (button.Entered)
288                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Entered, button.BackColor, button.ForeColor);
289                         else if (button.InternalSelected)
290                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Default, button.BackColor, button.ForeColor);
291                         else if (!button.Enabled)
292                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Disabled, button.BackColor, button.ForeColor);
293                         else
294                                 ThemeElements.DrawPopupButton (g, button.ClientRectangle, ButtonThemeState.Normal, button.BackColor, button.ForeColor);
295                 }
296
297                 public virtual void DrawPopupButtonFocus (Graphics g, Button button)
298                 {
299                         // No changes from Standard for image for this theme
300                         DrawButtonFocus (g, button);
301                 }
302
303                 public virtual void DrawPopupButtonImage (Graphics g, Button button, Rectangle imageBounds)
304                 {
305                         // No changes from Standard for image for this theme
306                         DrawButtonImage (g, button, imageBounds);
307                 }
308
309                 public virtual void DrawPopupButtonText (Graphics g, Button button, Rectangle textBounds)
310                 {
311                         // No changes from Standard for image for this theme
312                         DrawButtonText (g, button, textBounds);
313                 }
314                 #endregion
315
316                 #region Button Layout Calculations
317                 public override void CalculateButtonTextAndImageLayout (Button button, out Rectangle textRectangle, out Rectangle imageRectangle)
318                 {
319                         Image image = button.Image;
320                         string text = button.Text;
321                         Rectangle content_rect = button.ClientRectangle;
322                         Size text_size = TextRenderer.MeasureTextInternal (text, button.Font, content_rect.Size, button.TextFormatFlags, button.UseCompatibleTextRendering);
323                         Size image_size = image == null ? Size.Empty : image.Size;
324
325                         textRectangle = Rectangle.Empty;
326                         imageRectangle = Rectangle.Empty;
327                         
328                         switch (button.TextImageRelation) {
329                                 case TextImageRelation.Overlay:
330                                         // Overlay is easy, text always goes here
331                                         textRectangle = Rectangle.Inflate (content_rect, -4, -4);
332
333                                         if (button.Pressed)
334                                                 textRectangle.Offset (1, 1);
335                                                 
336                                         // Image is dependent on ImageAlign
337                                         if (image == null)
338                                                 return;
339                                                 
340                                         int image_x = 0;
341                                         int image_y = 0;
342                                         int image_height = image.Height;
343                                         int image_width = image.Width;
344                                         
345                                         switch (button.ImageAlign) {
346                                                 case System.Drawing.ContentAlignment.TopLeft:
347                                                         image_x = 5;
348                                                         image_y = 5;
349                                                         break;
350                                                 case System.Drawing.ContentAlignment.TopCenter:
351                                                         image_x = (content_rect.Width - image_width) / 2;
352                                                         image_y = 5;
353                                                         break;
354                                                 case System.Drawing.ContentAlignment.TopRight:
355                                                         image_x = content_rect.Width - image_width - 5;
356                                                         image_y = 5;
357                                                         break;
358                                                 case System.Drawing.ContentAlignment.MiddleLeft:
359                                                         image_x = 5;
360                                                         image_y = (content_rect.Height - image_height) / 2;
361                                                         break;
362                                                 case System.Drawing.ContentAlignment.MiddleCenter:
363                                                         image_x = (content_rect.Width - image_width) / 2;
364                                                         image_y = (content_rect.Height - image_height) / 2;
365                                                         break;
366                                                 case System.Drawing.ContentAlignment.MiddleRight:
367                                                         image_x = content_rect.Width - image_width - 4;
368                                                         image_y = (content_rect.Height - image_height) / 2;
369                                                         break;
370                                                 case System.Drawing.ContentAlignment.BottomLeft:
371                                                         image_x = 5;
372                                                         image_y = content_rect.Height - image_height - 4;
373                                                         break;
374                                                 case System.Drawing.ContentAlignment.BottomCenter:
375                                                         image_x = (content_rect.Width - image_width) / 2;
376                                                         image_y = content_rect.Height - image_height - 4;
377                                                         break;
378                                                 case System.Drawing.ContentAlignment.BottomRight:
379                                                         image_x = content_rect.Width - image_width - 4;
380                                                         image_y = content_rect.Height - image_height - 4;
381                                                         break;
382                                                 default:
383                                                         image_x = 5;
384                                                         image_y = 5;
385                                                         break;
386                                         }
387                                         
388                                         imageRectangle = new Rectangle (image_x, image_y, image_width, image_height);
389                                         break;
390                                 case TextImageRelation.ImageAboveText:
391                                         content_rect.Inflate (-4, -4);
392                                         LayoutTextAboveOrBelowImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
393                                         break;
394                                 case TextImageRelation.TextAboveImage:
395                                         content_rect.Inflate (-4, -4);
396                                         LayoutTextAboveOrBelowImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
397                                         break;
398                                 case TextImageRelation.ImageBeforeText:
399                                         content_rect.Inflate (-4, -4);
400                                         LayoutTextBeforeOrAfterImage (content_rect, false, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
401                                         break;
402                                 case TextImageRelation.TextBeforeImage:
403                                         content_rect.Inflate (-4, -4);
404                                         LayoutTextBeforeOrAfterImage (content_rect, true, text_size, image_size, button.TextAlign, button.ImageAlign, out textRectangle, out imageRectangle);
405                                         break;
406                         }
407                 }
408
409                 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)
410                 {
411                         int element_spacing = 0;        // Spacing between the Text and the Image
412                         int total_width = textSize.Width + element_spacing + imageSize.Width;
413                         
414                         if (!textFirst)
415                                 element_spacing += 2;
416                                 
417                         // If the text is too big, chop it down to the size we have available to it
418                         if (total_width > totalArea.Width) {
419                                 textSize.Width = totalArea.Width - element_spacing - imageSize.Width;
420                                 total_width = totalArea.Width;
421                         }
422                         
423                         int excess_width = totalArea.Width - total_width;
424                         int offset = 0;
425
426                         Rectangle final_text_rect;
427                         Rectangle final_image_rect;
428
429                         HorizontalAlignment h_text = GetHorizontalAlignment (textAlign);
430                         HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign);
431
432                         if (h_image == HorizontalAlignment.Left)
433                                 offset = 0;
434                         else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right)
435                                 offset = excess_width;
436                         else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center))
437                                 offset += (int)(excess_width / 3);
438                         else
439                                 offset += (int)(2 * (excess_width / 3));
440
441                         if (textFirst) {
442                                 final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
443                                 final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
444                         }
445                         else {
446                                 final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
447                                 final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
448                         }
449
450                         textRect = final_text_rect;
451                         imageRect = final_image_rect;
452                 }
453
454                 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)
455                 {
456                         int element_spacing = 0;        // Spacing between the Text and the Image
457                         int total_height = textSize.Height + element_spacing + imageSize.Height;
458
459                         if (textFirst)
460                                 element_spacing += 2;
461
462                         if (textSize.Width > totalArea.Width)
463                                 textSize.Width = totalArea.Width;
464                                 
465                         // If the there isn't enough room and we're text first, cut out the image
466                         if (total_height > totalArea.Height && textFirst) {
467                                 imageSize = Size.Empty;
468                                 total_height = totalArea.Height;
469                         }
470
471                         int excess_height = totalArea.Height - total_height;
472                         int offset = 0;
473
474                         Rectangle final_text_rect;
475                         Rectangle final_image_rect;
476
477                         VerticalAlignment v_text = GetVerticalAlignment (textAlign);
478                         VerticalAlignment v_image = GetVerticalAlignment (imageAlign);
479
480                         if (v_image == VerticalAlignment.Top)
481                                 offset = 0;
482                         else if (v_image == VerticalAlignment.Bottom && v_text == VerticalAlignment.Bottom)
483                                 offset = excess_height;
484                         else if (v_image == VerticalAlignment.Center && (v_text == VerticalAlignment.Top || v_text == VerticalAlignment.Center))
485                                 offset += (int)(excess_height / 3);
486                         else
487                                 offset += (int)(2 * (excess_height / 3));
488
489                         if (textFirst) {
490                                 final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, totalArea.Top + offset, textSize.Width, textSize.Height);
491                                 final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, final_text_rect.Bottom + element_spacing, imageSize.Width, imageSize.Height);
492                         }
493                         else {
494                                 final_image_rect = new Rectangle (AlignInRectangle (totalArea, imageSize, imageAlign).Left, totalArea.Top + offset, imageSize.Width, imageSize.Height);
495                                 final_text_rect = new Rectangle (AlignInRectangle (totalArea, textSize, textAlign).Left, final_image_rect.Bottom + element_spacing, textSize.Width, textSize.Height);
496                                 
497                                 if (final_text_rect.Bottom > totalArea.Bottom)
498                                         final_text_rect.Y = totalArea.Top;
499                         }
500
501                         textRect = final_text_rect;
502                         imageRect = final_image_rect;
503                 }
504                 
505                 private HorizontalAlignment GetHorizontalAlignment (System.Drawing.ContentAlignment align)
506                 {
507                         switch (align) {
508                                 case System.Drawing.ContentAlignment.BottomLeft:
509                                 case System.Drawing.ContentAlignment.MiddleLeft:
510                                 case System.Drawing.ContentAlignment.TopLeft:
511                                         return HorizontalAlignment.Left;
512                                 case System.Drawing.ContentAlignment.BottomCenter:
513                                 case System.Drawing.ContentAlignment.MiddleCenter:
514                                 case System.Drawing.ContentAlignment.TopCenter:
515                                         return HorizontalAlignment.Center;
516                                 case System.Drawing.ContentAlignment.BottomRight:
517                                 case System.Drawing.ContentAlignment.MiddleRight:
518                                 case System.Drawing.ContentAlignment.TopRight:
519                                         return HorizontalAlignment.Right;
520                         }
521
522                         return HorizontalAlignment.Left;
523                 }
524
525                 private enum VerticalAlignment
526                 {
527                         Top = 0,
528                         Center = 1,
529                         Bottom = 2
530                 }
531                 
532                 private VerticalAlignment GetVerticalAlignment (System.Drawing.ContentAlignment align)
533                 {
534                         switch (align) {
535                                 case System.Drawing.ContentAlignment.TopLeft:
536                                 case System.Drawing.ContentAlignment.TopCenter:
537                                 case System.Drawing.ContentAlignment.TopRight:
538                                         return VerticalAlignment.Top;
539                                 case System.Drawing.ContentAlignment.MiddleLeft:
540                                 case System.Drawing.ContentAlignment.MiddleCenter:
541                                 case System.Drawing.ContentAlignment.MiddleRight:
542                                         return VerticalAlignment.Center;
543                                 case System.Drawing.ContentAlignment.BottomLeft:
544                                 case System.Drawing.ContentAlignment.BottomCenter:
545                                 case System.Drawing.ContentAlignment.BottomRight:
546                                         return VerticalAlignment.Bottom;
547                         }
548
549                         return VerticalAlignment.Top;
550                 }
551
552                 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, System.Drawing.ContentAlignment align)
553                 {
554                         int x = 0;
555                         int y = 0;
556
557                         if (align == System.Drawing.ContentAlignment.BottomLeft || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.TopLeft)
558                                 x = outer.X;
559                         else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.TopCenter)
560                                 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
561                         else if (align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.MiddleRight || align == System.Drawing.ContentAlignment.TopRight)
562                                 x = outer.Right - inner.Width;
563                         if (align == System.Drawing.ContentAlignment.TopCenter || align == System.Drawing.ContentAlignment.TopLeft || align == System.Drawing.ContentAlignment.TopRight)
564                                 y = outer.Y;
565                         else if (align == System.Drawing.ContentAlignment.MiddleCenter || align == System.Drawing.ContentAlignment.MiddleLeft || align == System.Drawing.ContentAlignment.MiddleRight)
566                                 y = outer.Y + (outer.Height - inner.Height) / 2;
567                         else if (align == System.Drawing.ContentAlignment.BottomCenter || align == System.Drawing.ContentAlignment.BottomRight || align == System.Drawing.ContentAlignment.BottomLeft)
568                                 y = outer.Bottom - inner.Height;
569
570                         return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
571                 }
572                 #endregion
573                 #endregion
574
575                 #region ButtonBase
576                 public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button)
577                 {
578                         // Draw the button: Draw border, etc.
579                         ButtonBase_DrawButton(button, dc);
580
581                         // Draw the image
582                         if (button.FlatStyle != FlatStyle.System && ((button.image != null) || (button.image_list != null)))
583                                 ButtonBase_DrawImage(button, dc);
584                         
585                         // Draw the focus rectangle
586                         if ((button.Focused || button.paint_as_acceptbutton) && button.Enabled)
587                                 ButtonBase_DrawFocus(button, dc);
588                         
589                         // Now the text
590                         if (button.Text != null && button.Text != String.Empty)
591                                 ButtonBase_DrawText(button, dc);
592                 }
593
594                 protected virtual void ButtonBase_DrawButton (ButtonBase button, Graphics dc)
595                 {
596                         Rectangle borderRectangle;
597                         bool check_or_radio = false;
598                         bool check_or_radio_checked = false;
599                         
600                         bool is_ColorControl = button.BackColor.ToArgb () == ColorControl.ToArgb () ? true : false;
601                         
602                         CPColor cpcolor = is_ColorControl ? CPColor.Empty : ResPool.GetCPColor (button.BackColor);
603                         
604                         if (button is CheckBox) {
605                                 check_or_radio = true;
606                                 check_or_radio_checked = ((CheckBox)button).Checked;
607                         } else if (button is RadioButton) {
608                                 check_or_radio = true;
609                                 check_or_radio_checked = ((RadioButton)button).Checked;
610                         }
611                         
612                         if ((button.Focused || button.paint_as_acceptbutton) && button.Enabled && !check_or_radio) {
613                                 // shrink the rectangle for the normal button drawing inside the focus rectangle
614                                 borderRectangle = Rectangle.Inflate (button.ClientRectangle, -1, -1);
615                         } else {
616                                 borderRectangle = button.ClientRectangle;
617                         }
618                         
619                         if (button.FlatStyle == FlatStyle.Popup) {
620                                 if (!button.is_pressed && !button.is_entered && !check_or_radio_checked)
621                                         Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
622                                 else if (!button.is_pressed && button.is_entered &&!check_or_radio_checked)
623                                         Internal_DrawButton (dc, borderRectangle, 2, cpcolor, is_ColorControl, button.BackColor);
624                                 else if (button.is_pressed || check_or_radio_checked)
625                                         Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
626                         } else if (button.FlatStyle == FlatStyle.Flat) {
627                                 if (button.is_entered && !button.is_pressed && !check_or_radio_checked) {
628                                         if ((button.image == null) && (button.image_list == null)) {
629                                                 Brush brush = is_ColorControl ? SystemBrushes.ControlDark : ResPool.GetSolidBrush (cpcolor.Dark);
630                                                 dc.FillRectangle (brush, borderRectangle);
631                                         }
632                                 } else if (button.is_pressed || check_or_radio_checked) {
633                                         if ((button.image == null) && (button.image_list == null)) {
634                                                 Brush brush = is_ColorControl ? SystemBrushes.ControlLightLight : ResPool.GetSolidBrush (cpcolor.LightLight);
635                                                 dc.FillRectangle (brush, borderRectangle);
636                                         }
637                                         
638                                         Pen pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
639                                         dc.DrawRectangle (pen, borderRectangle.X + 4, borderRectangle.Y + 4,
640                                                           borderRectangle.Width - 9, borderRectangle.Height - 9);
641                                 }
642                                 
643                                 Internal_DrawButton (dc, borderRectangle, 3, cpcolor, is_ColorControl, button.BackColor);
644                         } else {
645                                 if ((!button.is_pressed || !button.Enabled) && !check_or_radio_checked)
646                                         Internal_DrawButton (dc, borderRectangle, 0, cpcolor, is_ColorControl, button.BackColor);
647                                 else
648                                         Internal_DrawButton (dc, borderRectangle, 1, cpcolor, is_ColorControl, button.BackColor);
649                         }
650                 }
651                 
652                 private void Internal_DrawButton (Graphics dc, Rectangle rect, int state, CPColor cpcolor, bool is_ColorControl, Color backcolor)
653                 {
654                         switch (state) {
655                         case 0: // normal or normal disabled button
656                                 Pen pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
657                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
658                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
659                                 
660                                 pen = is_ColorControl ? SystemPens.Control : ResPool.GetPen (backcolor);
661                                 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 3);
662                                 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 3, rect.Y + 1);
663                                 
664                                 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
665                                 dc.DrawLine (pen, rect.X + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
666                                 dc.DrawLine (pen, rect.Right - 2, rect.Y + 1, rect.Right - 2, rect.Bottom - 3);
667                                 
668                                 pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
669                                 dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
670                                 dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
671                                 break;
672                         case 1: // popup button normal (or pressed normal or popup button)
673                                 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
674                                 dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
675                                 break;
676                         case 2: // popup button poped up
677                                 pen = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
678                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 2);
679                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 2, rect.Y);
680                                 
681                                 pen = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
682                                 dc.DrawLine (pen, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
683                                 dc.DrawLine (pen, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 2);
684                                 break;
685                         case 3: // flat button not entered
686                                 pen = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
687                                 dc.DrawRectangle (pen, rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
688                                 break;
689                         default:
690                                 break;
691                         }
692                 }
693                 
694                 protected virtual void ButtonBase_DrawImage(ButtonBase button, Graphics dc)
695                 {
696                         // Need to draw a picture
697                         Image   i;
698                         int     image_x;
699                         int     image_y;
700                         int     image_width;
701                         int     image_height;
702                         
703                         int width = button.ClientSize.Width;
704                         int height = button.ClientSize.Height;
705
706                         if (button.ImageIndex != -1) {   // We use ImageIndex instead of image_index since it will return -1 if image_list is null
707                                 i = button.image_list.Images[button.ImageIndex];
708                         } else {
709                                 i = button.image;
710                         }
711
712                         image_width = i.Width;
713                         image_height = i.Height;
714                         
715                         switch (button.ImageAlign) {
716                                 case ContentAlignment.TopLeft: {
717                                         image_x = 5;
718                                         image_y = 5;
719                                         break;
720                                 }
721                                         
722                                 case ContentAlignment.TopCenter: {
723                                         image_x = (width - image_width) / 2;
724                                         image_y = 5;
725                                         break;
726                                 }
727                                         
728                                 case ContentAlignment.TopRight: {
729                                         image_x = width - image_width - 5;
730                                         image_y = 5;
731                                         break;
732                                 }
733                                         
734                                 case ContentAlignment.MiddleLeft: {
735                                         image_x = 5;
736                                         image_y = (height - image_height) / 2;
737                                         break;
738                                 }
739                                         
740                                 case ContentAlignment.MiddleCenter: {
741                                         image_x = (width - image_width) / 2;
742                                         image_y = (height - image_height) / 2;
743                                         break;
744                                 }
745                                         
746                                 case ContentAlignment.MiddleRight: {
747                                         image_x = width - image_width - 4;
748                                         image_y = (height - image_height) / 2;
749                                         break;
750                                 }
751                                         
752                                 case ContentAlignment.BottomLeft: {
753                                         image_x = 5;
754                                         image_y = height - image_height - 4;
755                                         break;
756                                 }
757                                         
758                                 case ContentAlignment.BottomCenter: {
759                                         image_x = (width - image_width) / 2;
760                                         image_y = height - image_height - 4;
761                                         break;
762                                 }
763                                         
764                                 case ContentAlignment.BottomRight: {
765                                         image_x = width - image_width - 4;
766                                         image_y = height - image_height - 4;
767                                         break;
768                                 }
769                                         
770                                 default: {
771                                         image_x = 5;
772                                         image_y = 5;
773                                         break;
774                                 }
775                         }
776                         
777                         dc.SetClip (new Rectangle(3, 3, width - 5, height - 5));
778
779                         if (button.Enabled)
780                                 dc.DrawImage (i, image_x, image_y, image_width, image_height);
781                         else
782                                 CPDrawImageDisabled (dc, i, image_x, image_y, ColorControl);
783
784                         dc.ResetClip ();
785                 }
786                 
787                 protected virtual void ButtonBase_DrawFocus(ButtonBase button, Graphics dc)
788                 {
789                         Color focus_color = button.ForeColor;
790                         
791                         int inflate_value = -3;
792                         
793                         if (!(button is CheckBox) && !(button is RadioButton)) {
794                                 inflate_value = -4;
795                                 
796                                 if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed)
797                                         focus_color = ControlPaint.Dark(button.BackColor);
798                                 
799                                 dc.DrawRectangle (ResPool.GetPen (focus_color), button.ClientRectangle.X, button.ClientRectangle.Y, 
800                                                   button.ClientRectangle.Width - 1, button.ClientRectangle.Height - 1);
801                         }
802                         
803                         if (button.Focused) {
804                                 Rectangle rect = Rectangle.Inflate (button.ClientRectangle, inflate_value, inflate_value);
805                                 ControlPaint.DrawFocusRectangle (dc, rect);
806                         }
807                 }
808                 
809                 protected virtual void ButtonBase_DrawText(ButtonBase button, Graphics dc)
810                 {
811                         Rectangle buttonRectangle = button.ClientRectangle;
812                         Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4);
813                         
814                         if (button.is_pressed) {
815                                 text_rect.X++;
816                                 text_rect.Y++;
817                         }
818                         
819                         if (button.Enabled) {                                   
820                                 dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format);
821                         } else {
822                                 if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
823                                         dc.DrawString(button.Text, button.Font, ResPool.GetSolidBrush (ColorGrayText), text_rect, button.text_format);
824                                 } else {
825                                         CPDrawStringDisabled (dc, button.Text, button.Font, button.BackColor, text_rect, button.text_format);
826                                 }
827                         }
828                 }
829                 
830                 public override Size ButtonBaseDefaultSize {
831                         get {
832                                 return new Size (75, 23);
833                         }
834                 }
835                 #endregion      // ButtonBase
836
837                 #region CheckBox
838                 public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) {
839                         StringFormat            text_format;
840                         Rectangle               client_rectangle;
841                         Rectangle               text_rectangle;
842                         Rectangle               checkbox_rectangle;
843                         int                     checkmark_size=13;
844                         int                     checkmark_space = 4;
845
846                         client_rectangle = checkbox.ClientRectangle;
847                         text_rectangle = client_rectangle;
848                         checkbox_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, checkmark_size, checkmark_size);
849
850                         text_format = new StringFormat();
851                         text_format.Alignment=StringAlignment.Near;
852                         text_format.LineAlignment=StringAlignment.Center;
853                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
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                         int col_offset;
2333                         if (control.View == View.Details && control.Columns.Count > 0)
2334                                 col_offset = control.Columns [0].Rect.X;
2335                         else
2336                                 col_offset = 0;
2337                         
2338                         Rectangle rect_checkrect = item.CheckRectReal;
2339                         rect_checkrect.X += col_offset;
2340                         Rectangle icon_rect = item.GetBounds (ItemBoundsPortion.Icon);
2341                         icon_rect.X += col_offset;
2342                         Rectangle full_rect = item.GetBounds (ItemBoundsPortion.Entire);
2343                         full_rect.X += col_offset;
2344                         Rectangle text_rect = item.GetBounds (ItemBoundsPortion.Label);                 
2345                         text_rect.X += col_offset;
2346
2347 #if NET_2_0
2348                         // Tile view doesn't support CheckBoxes
2349                         if (control.CheckBoxes && control.View != View.Tile) {
2350 #else
2351                         if (control.CheckBoxes) {
2352 #endif
2353                                 if (control.StateImageList == null) {
2354                                         // Make sure we've got at least a line width of 1
2355                                         int check_wd = Math.Max (3, rect_checkrect.Width / 6);
2356                                         int scale = Math.Max (1, rect_checkrect.Width / 12);
2357
2358                                         // set the checkbox background
2359                                         dc.FillRectangle (SystemBrushes.Window,
2360                                                           rect_checkrect);
2361                                         // define a rectangle inside the border area
2362                                         Rectangle rect = new Rectangle (rect_checkrect.X + 2,
2363                                                                         rect_checkrect.Y + 2,
2364                                                                         rect_checkrect.Width - 4,
2365                                                                         rect_checkrect.Height - 4);
2366                                         Pen pen = ResPool.GetSizedPen (this.ColorWindowText, 2);
2367                                         dc.DrawRectangle (pen, rect);
2368
2369                                         // Need to draw a check-mark
2370                                         if (item.Checked) {
2371                                                 Pen check_pen = ResPool.GetSizedPen (this.ColorWindowText, 1);
2372                                                 // adjustments to get the check-mark at the right place
2373                                                 rect.X ++; rect.Y ++;
2374                                                 // following logic is taken from DrawFrameControl method
2375                                                 for (int i = 0; i < check_wd; i++) {
2376                                                         dc.DrawLine (check_pen, rect.Left + check_wd / 2,
2377                                                                      rect.Top + check_wd + i,
2378                                                                      rect.Left + check_wd / 2 + 2 * scale,
2379                                                                      rect.Top + check_wd + 2 * scale + i);
2380                                                         dc.DrawLine (check_pen,
2381                                                                      rect.Left + check_wd / 2 + 2 * scale,
2382                                                                      rect.Top + check_wd + 2 * scale + i,
2383                                                                      rect.Left + check_wd / 2 + 6 * scale,
2384                                                                      rect.Top + check_wd - 2 * scale + i);
2385                                                 }
2386                                         }
2387                                 }
2388                                 else {
2389                                         if (item.Checked && control.StateImageList.Images.Count > 1)
2390                                                 control.StateImageList.Draw (dc, rect_checkrect.Location, 1);
2391                                         else if (control.StateImageList.Images.Count > 0)
2392                                                 control.StateImageList.Draw (dc, rect_checkrect.Location, 0);
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)
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                         Rectangle highlight_rect = text_rect;
2433                         if (control.View == View.Details) { // Adjustments for Details view
2434                                 Size text_size = Size.Ceiling (dc.MeasureString (item.Text, item.Font));
2435
2436                                 if (!control.FullRowSelect) // Selection shouldn't be outside the item bounds
2437                                         highlight_rect.Width = Math.Min (text_size.Width + 4, text_rect.Width);
2438
2439                                 if (text_size.Width > text_rect.Width)
2440                                         format.Trimming = StringTrimming.EllipsisCharacter;
2441                         }
2442
2443                         if (item.Selected && control.Focused)
2444                                 dc.FillRectangle (SystemBrushes.Highlight, highlight_rect);
2445                         else if (item.Selected && !control.HideSelection)
2446                                 dc.FillRectangle (SystemBrushes.Control, highlight_rect);
2447                         else
2448                                 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
2449                         
2450                         Brush textBrush =
2451                                 !control.Enabled ? SystemBrushes.ControlLight :
2452                                 (item.Selected && control.Focused) ? SystemBrushes.HighlightText :
2453                                 this.ResPool.GetSolidBrush (item.ForeColor);
2454
2455 #if NET_2_0
2456                         // Tile view renders its Text in a different fashion
2457                         if (control.View == View.Tile) {
2458                                 // Item.Text is drawn using its first subitem's bounds
2459                                 dc.DrawString (item.Text, item.Font, textBrush, item.SubItems [0].Bounds, format);
2460
2461                                 int count = Math.Min (control.Columns.Count, item.SubItems.Count);
2462                                 for (int i = 1; i < count; i++) {
2463                                         ListViewItem.ListViewSubItem sub_item = item.SubItems [i];
2464                                         if (sub_item.Text == null || sub_item.Text.Length == 0)
2465                                                 continue;
2466
2467                                         Brush itemBrush = item.Selected && control.Focused ? 
2468                                                 SystemBrushes.HighlightText : GetControlForeBrush (sub_item.ForeColor);
2469                                         dc.DrawString (sub_item.Text, sub_item.Font, itemBrush, sub_item.Bounds, format);
2470                                 }
2471                         } else
2472 #endif
2473                         
2474                         if (item.Text != null && item.Text.Length > 0) {
2475                                 if (item.Selected && control.Focused)
2476                                         dc.DrawString (item.Text, item.Font, textBrush, highlight_rect, format);
2477                                 else
2478                                         dc.DrawString (item.Text, item.Font, textBrush, text_rect, format);
2479                         }
2480
2481                         if (control.View == View.Details && control.Columns.Count > 0) {
2482                                 // draw subitems for details view
2483                                 ListViewItem.ListViewSubItemCollection subItems = item.SubItems;
2484                                 int count = (control.Columns.Count < subItems.Count ? 
2485                                              control.Columns.Count : subItems.Count);
2486
2487                                 if (count > 0) {
2488                                         ColumnHeader col;
2489                                         ListViewItem.ListViewSubItem subItem;
2490                                         Rectangle sub_item_rect = text_rect; 
2491
2492                                         // set the format for subitems
2493                                         format.FormatFlags = StringFormatFlags.NoWrap;
2494
2495                                         // 0th subitem is the item already drawn
2496                                         for (int index = 1; index < count; index++) {
2497                                                 subItem = subItems [index];
2498                                                 col = control.Columns [index];
2499                                                 format.Alignment = col.Format.Alignment;
2500                                                 sub_item_rect.X = col.Rect.X - control.h_marker;
2501                                                 sub_item_rect.Width = col.Wd;
2502                                                 Rectangle sub_item_text_rect = sub_item_rect;
2503                                                 sub_item_text_rect.X += 3;
2504                                                 sub_item_text_rect.Width -= 6;
2505
2506                                                 SolidBrush sub_item_back_br = null;
2507                                                 SolidBrush sub_item_fore_br = null;
2508                                                 Font sub_item_font = null;
2509
2510                                                 if (item.UseItemStyleForSubItems) {
2511                                                         sub_item_back_br = ResPool.GetSolidBrush (item.BackColor);
2512                                                         sub_item_fore_br = ResPool.GetSolidBrush (item.ForeColor);
2513                                                         sub_item_font = item.Font;
2514                                                 } else {
2515                                                         sub_item_back_br = ResPool.GetSolidBrush (subItem.BackColor);
2516                                                         sub_item_fore_br = ResPool.GetSolidBrush (subItem.ForeColor);
2517                                                         sub_item_font = subItem.Font;
2518                                                 }
2519
2520                                                 int sub_item_text_width = (int) Math.Ceiling (control.DeviceContext.MeasureString (subItem.Text,
2521                                                                 sub_item_font).Width);
2522
2523                                                 format.Trimming = sub_item_text_width > sub_item_text_rect.Width ? StringTrimming.EllipsisCharacter :
2524                                                         StringTrimming.None;
2525
2526                                                 if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
2527                                                         Brush bg, text;
2528                                                         if (control.Focused) {
2529                                                                 bg = SystemBrushes.Highlight;
2530                                                                 text = SystemBrushes.HighlightText;
2531                                                         } else {
2532                                                                 bg = SystemBrushes.Control;
2533                                                                 text = sub_item_fore_br;
2534                                                         }
2535                                         
2536                                                         dc.FillRectangle (bg, sub_item_rect);
2537                                                         if (subItem.Text != null && subItem.Text.Length > 0)
2538                                                                 dc.DrawString (subItem.Text, sub_item_font,
2539                                                                                text, sub_item_text_rect, format);
2540                                                 } else {
2541                                                         dc.FillRectangle (sub_item_back_br, sub_item_rect);
2542                                                         if (subItem.Text != null && subItem.Text.Length > 0)
2543                                                                 dc.DrawString (subItem.Text, sub_item_font,
2544                                                                                sub_item_fore_br,
2545                                                                                sub_item_text_rect, format);
2546                                                 }
2547                                         }
2548
2549                                         // Fill in selection for remaining columns if Column.Count > SubItems.Count
2550                                         if (item.Selected && (control.Focused || !control.HideSelection) && control.FullRowSelect) {
2551                                                 for (int index = count; index < control.Columns.Count; index++)
2552                                                 {
2553                                                         col = control.Columns [index];
2554                                                         sub_item_rect.X = col.Rect.X - control.h_marker;
2555                                                         sub_item_rect.Width = col.Wd;
2556                                                         if (control.Focused)
2557                                                                 dc.FillRectangle (SystemBrushes.Highlight, sub_item_rect);
2558                                                         else
2559                                                                 dc.FillRectangle (SystemBrushes.Control, sub_item_rect);
2560                                                 }
2561                                         }
2562                                 }
2563                         }
2564
2565                         if (item.Focused && control.Focused) {                          
2566                                 Rectangle focus_rect = highlight_rect;
2567                                 if (control.FullRowSelect && control.View == View.Details) {
2568                                         int width = 0;
2569                                         foreach (ColumnHeader col in control.Columns)
2570                                                 width += col.Width;
2571                                         focus_rect = new Rectangle (0, full_rect.Y, width, full_rect.Height);
2572                                 }
2573                                 if (item.Selected)
2574                                         CPDrawFocusRectangle (dc, focus_rect, ColorHighlightText, ColorHighlight);
2575                                 else
2576                                         CPDrawFocusRectangle (dc, focus_rect, control.ForeColor, control.BackColor);
2577                         }
2578
2579                         format.Dispose ();
2580                 }
2581
2582                 // Sizing
2583                 public override Size ListViewCheckBoxSize {
2584                         get { return new Size (16, 16); }
2585                 }
2586
2587                 public override int ListViewColumnHeaderHeight {
2588                         get { return 16; }
2589                 }
2590
2591                 public override int ListViewDefaultColumnWidth {
2592                         get { return 60; }
2593                 }
2594
2595                 public override int ListViewVerticalSpacing {
2596                         get { return 22; }
2597                 }
2598
2599                 public override int ListViewEmptyColumnWidth {
2600                         get { return 10; }
2601                 }
2602
2603                 public override int ListViewHorizontalSpacing {
2604                         get { return 10; }
2605                 }
2606
2607                 public override Size ListViewDefaultSize {
2608                         get { return new Size (121, 97); }
2609                 }
2610
2611                 public override int ListViewGroupHeight { 
2612                         get { return 20; }
2613                 }
2614
2615                 public override int ListViewTileWidthFactor {
2616                         get { return 22; }
2617                 }
2618
2619                 public override int ListViewTileHeightFactor {
2620                         get { return 3; }
2621                 }
2622                 #endregion      // ListView
2623                 
2624                 #region Menus
2625                 
2626                 public override bool MenuAccessKeysUnderlined {
2627                         get { return false;     }
2628                 }
2629                 
2630                 public override void CalcItemSize (Graphics dc, MenuItem item, int y, int x, bool menuBar)
2631                 {
2632                         item.X = x;
2633                         item.Y = y;
2634
2635                         if (item.Visible == false) {
2636                                 item.Width = 0;
2637                                 item.Height = 0;
2638                                 return;
2639                         }
2640
2641                         if (item.Separator == true) {
2642                                 item.Height = SEPARATOR_HEIGHT;
2643                                 item.Width = SEPARATOR_MIN_WIDTH;
2644                                 return;
2645                         }
2646                         
2647                         if (item.MeasureEventDefined) {
2648                                 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.Index);
2649                                 item.PerformMeasureItem (mi);
2650                                 item.Height = mi.ItemHeight;
2651                                 item.Width = mi.ItemWidth;
2652                                 return;
2653                         } else {                
2654                                 SizeF size;
2655                                 size =  dc.MeasureString (item.Text, MenuFont);
2656                                 item.Width = (int) size.Width;
2657                                 item.Height = (int) size.Height;
2658         
2659                                 if (!menuBar) {
2660                                         if (item.Shortcut != Shortcut.None && item.ShowShortcut) {
2661                                                 item.XTab = MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
2662                                                 size =  dc.MeasureString (" " + item.GetShortCutText (), MenuFont);
2663                                                 item.Width += MENU_TAB_SPACE + (int) size.Width;
2664                                         }
2665         
2666                                         item.Width += 4 + (MenuCheckSize.Width * 2);
2667                                 } else {
2668                                         item.Width += MENU_BAR_ITEMS_SPACE;
2669                                         x += item.Width;
2670                                 }
2671         
2672                                 if (item.Height < MenuHeight)
2673                                         item.Height = MenuHeight;
2674                         }
2675                 }
2676                 
2677                 // Updates the menu rect and returns the height
2678                 public override int CalcMenuBarSize (Graphics dc, Menu menu, int width)
2679                 {
2680                         int x = 0;
2681                         int y = 0;
2682                         menu.Height = 0;
2683
2684                         foreach (MenuItem item in menu.MenuItems) {
2685
2686                                 CalcItemSize (dc, item, y, x, true);
2687
2688                                 if (x + item.Width > width) {
2689                                         item.X = 0;
2690                                         y += item.Height;
2691                                         item.Y = y;
2692                                         x = 0;
2693                                 }
2694
2695                                 x += item.Width;
2696                                 item.MenuBar = true;                            
2697
2698                                 if (y + item.Height > menu.Height)
2699                                         menu.Height = item.Height + y;
2700                         }
2701
2702                         menu.Width = width;                                             
2703                         return menu.Height;
2704                 }
2705
2706                 public override void CalcPopupMenuSize (Graphics dc, Menu menu)
2707                 {
2708                         int x = 3;
2709                         int start = 0;
2710                         int i, n, y, max;
2711
2712                         menu.Height = 0;
2713
2714                         while (start < menu.MenuItems.Count) {
2715                                 y = 3;
2716                                 max = 0;
2717                                 for (i = start; i < menu.MenuItems.Count; i++) {
2718                                         MenuItem item = menu.MenuItems [i];
2719
2720                                         if ((i != start) && (item.Break || item.BarBreak))
2721                                                 break;
2722
2723                                         CalcItemSize (dc, item, y, x, false);
2724                                         y += item.Height;
2725
2726                                         if (item.Width > max)
2727                                                 max = item.Width;
2728                                 }
2729
2730                                 // Replace the -1 by the menu width (separators)
2731                                 for (n = start; n < i; n++, start++)
2732                                         menu.MenuItems [n].Width = max;
2733
2734                                 if (y > menu.Height)
2735                                         menu.Height = y;
2736
2737                                 x+= max;
2738                         }
2739
2740                         menu.Width = x;
2741                         
2742                         //space for border
2743                         menu.Width += 2;
2744                         menu.Height += 2;
2745
2746                         menu.Width += SM_CXBORDER;
2747                 menu.Height += SM_CYBORDER;
2748                 }
2749                 
2750                 // Draws a menu bar in a window
2751                 public override void DrawMenuBar (Graphics dc, Menu menu, Rectangle rect)
2752                 {
2753                         if (menu.Height == 0)
2754                                 CalcMenuBarSize (dc, menu, rect.Width);
2755
2756                         bool keynav = (menu as MainMenu).tracker.hotkey_active;
2757                         HotkeyPrefix hp = MenuAccessKeysUnderlined || keynav ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
2758                         string_format_menu_menubar_text.HotkeyPrefix = hp;
2759                         string_format_menu_text.HotkeyPrefix = hp;
2760
2761                         rect.Height = menu.Height;
2762                         dc.FillRectangle (SystemBrushes.Menu, rect);
2763                         
2764                         for (int i = 0; i < menu.MenuItems.Count; i++) {
2765                                 MenuItem item = menu.MenuItems [i];
2766                                 Rectangle item_rect = item.bounds;
2767                                 item_rect.X += rect.X;
2768                                 item_rect.Y += rect.Y;
2769                                 item.MenuHeight = menu.Height;
2770                                 item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item_rect, i, item.Status)); 
2771                         }       
2772                 }               
2773                 
2774                 protected Bitmap CreateGlyphBitmap (Size size, MenuGlyph glyph, Color color)
2775                 {
2776                         Color bg_color;
2777                         if (color.R == 0 && color.G == 0 && color.B == 0)
2778                                 bg_color = Color.White;
2779                         else
2780                                 bg_color = Color.Black;
2781                         
2782                         Bitmap  bmp = new Bitmap (size.Width, size.Height);
2783                         Graphics gr = Graphics.FromImage (bmp);
2784                         Rectangle rect = new Rectangle (Point.Empty, size);
2785                         gr.FillRectangle (ResPool.GetSolidBrush (bg_color), rect);
2786                         CPDrawMenuGlyph (gr, rect, glyph, color);
2787                         bmp.MakeTransparent (bg_color);
2788                         gr.Dispose ();
2789                         
2790                         return bmp;
2791                 }
2792
2793                 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
2794                 {
2795                         StringFormat string_format;
2796                         Rectangle rect_text = e.Bounds;
2797                         
2798                         if (item.Visible == false)
2799                                 return;
2800
2801                         if (item.MenuBar)
2802                                 string_format = string_format_menu_menubar_text;
2803                         else
2804                                 string_format = string_format_menu_text;
2805
2806                         if (item.Separator == true) {
2807                                 int liney = e.Bounds.Y + (e.Bounds.Height / 2);
2808                                 
2809                                 e.Graphics.DrawLine (SystemPens.ControlDark,
2810                                         e.Bounds.X, liney, e.Bounds.X + e.Bounds.Width, liney);
2811
2812                                 e.Graphics.DrawLine (SystemPens.ControlLight,
2813                                         e.Bounds.X, liney + 1, e.Bounds.X + e.Bounds.Width, liney + 1);
2814
2815                                 return;
2816                         }
2817
2818                         if (!item.MenuBar)
2819                                 rect_text.X += MenuCheckSize.Width;
2820
2821                         if (item.BarBreak) { /* Draw vertical break bar*/
2822                                 Rectangle rect = e.Bounds;
2823                                 rect.Y++;
2824                                 rect.Width = 3;
2825                                 rect.Height = item.MenuHeight - 6;
2826
2827                                 e.Graphics.DrawLine (SystemPens.ControlDark,
2828                                         rect.X, rect.Y , rect.X, rect.Y + rect.Height);
2829
2830                                 e.Graphics.DrawLine (SystemPens.ControlLight,
2831                                         rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
2832                         }                       
2833                         
2834                         Color color_text;
2835                         Color color_back;
2836                         Brush brush_text = null;
2837                         Brush brush_back = null;
2838                         
2839                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected && !item.MenuBar) {
2840                                 color_text = ColorHighlightText;
2841                                 color_back = ColorHighlight;
2842                                 brush_text = SystemBrushes.HighlightText;
2843                                 brush_back = SystemBrushes.Highlight;
2844                         } else {
2845                                 color_text = ColorMenuText;
2846                                 color_back = ColorMenu;
2847                                 brush_text = ResPool.GetSolidBrush (ColorMenuText);
2848                                 brush_back = SystemBrushes.Menu;
2849                         }
2850
2851                         /* Draw background */
2852                         if (!item.MenuBar)
2853                                 e.Graphics.FillRectangle (brush_back, e.Bounds);
2854                         
2855                         if (item.Enabled) {
2856                                 e.Graphics.DrawString (item.Text, e.Font,
2857                                         brush_text,
2858                                         rect_text, string_format);
2859                                 
2860                                 if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
2861                                         string str = item.GetShortCutText ();
2862                                         Rectangle rect = rect_text;
2863                                         rect.X = item.XTab;
2864                                         rect.Width -= item.XTab;
2865
2866                                         e.Graphics.DrawString (str, e.Font, brush_text,
2867                                                 rect, string_format_menu_shortcut);
2868                                 }
2869                                 
2870                                 if (item.MenuBar) {
2871                                         Border3DStyle border_style = Border3DStyle.Adjust;
2872                                         if ((item.Status & DrawItemState.HotLight) != 0)
2873                                                 border_style = Border3DStyle.RaisedInner;
2874                                         else if ((item.Status & DrawItemState.Selected) != 0)
2875                                                 border_style = Border3DStyle.SunkenOuter;
2876                                         
2877                                         if (border_style != Border3DStyle.Adjust)
2878                                                 CPDrawBorder3D(e.Graphics, e.Bounds, border_style,  Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, ColorMenu);
2879                                 }
2880                         } else {
2881                                 if ((item.Status & DrawItemState.Selected) != DrawItemState.Selected) {
2882                                         e.Graphics.DrawString (item.Text, e.Font, Brushes.White, 
2883                                                                new RectangleF(rect_text.X + 1, rect_text.Y + 1, rect_text.Width, rect_text.Height),
2884                                                                string_format);
2885                                 }
2886                                 
2887                                 e.Graphics.DrawString (item.Text, e.Font, ResPool.GetSolidBrush(ColorGrayText), rect_text, string_format);
2888                         }
2889
2890                         /* Draw arrow */
2891                         if (item.MenuBar == false && (item.IsPopup || item.MdiList)) {
2892
2893                                 int cx = MenuCheckSize.Width;
2894                                 int cy = MenuCheckSize.Height;
2895                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), MenuGlyph.Arrow, color_text);
2896                                 
2897                                 if (item.Enabled) {
2898                                         e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
2899                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
2900                                 } else {
2901                                         ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
2902                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
2903                                 }
2904  
2905                                 bmp.Dispose ();
2906                         }
2907
2908                         /* Draw checked or radio */
2909                         if (item.MenuBar == false && item.Checked) {
2910
2911                                 Rectangle area = e.Bounds;
2912                                 int cx = MenuCheckSize.Width;
2913                                 int cy = MenuCheckSize.Height;
2914                                 Bitmap  bmp = CreateGlyphBitmap (new Size (cx, cy), item.RadioCheck ? MenuGlyph.Bullet : MenuGlyph.Checkmark, color_text);
2915
2916                                 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
2917
2918                                 bmp.Dispose ();
2919                         }                       
2920                 }               
2921                         
2922                 public override void DrawPopupMenu (Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect)
2923                 {
2924                         // Fill rectangle area
2925                         dc.FillRectangle (SystemBrushes.Menu, cliparea);
2926                         
2927                         // Draw menu borders
2928                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
2929                         
2930                         // Draw menu items
2931                         for (int i = 0; i < menu.MenuItems.Count; i++) {
2932                                 if (cliparea.IntersectsWith (menu.MenuItems [i].bounds)) {
2933                                         MenuItem item = menu.MenuItems [i];
2934                                         item.MenuHeight = menu.Height;
2935                                         item.PerformDrawItem (new DrawItemEventArgs (dc, MenuFont, item.bounds, i, item.Status));
2936                                 }
2937                         }
2938                 }
2939                 
2940                 #endregion // Menus
2941
2942                 #region MonthCalendar
2943
2944                 // draw the month calendar
2945                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) 
2946                 {
2947                         Rectangle client_rectangle = mc.ClientRectangle;
2948                         Size month_size = mc.SingleMonthSize;
2949                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
2950                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
2951                         Size date_cell_size = (Size)((object)mc.date_cell_size);
2952                         
2953                         // draw the singlecalendars
2954                         int x_offset = 1;
2955                         int y_offset = 1;
2956                         // adjust for the position of the specific month
2957                         for (int i=0; i < mc.CalendarDimensions.Height; i++) 
2958                         {
2959                                 if (i > 0) 
2960                                 {
2961                                         y_offset += month_size.Height + calendar_spacing.Height;
2962                                 }
2963                                 // now adjust for x position    
2964                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) 
2965                                 {
2966                                         if (j > 0) 
2967                                         {
2968                                                 x_offset += month_size.Width + calendar_spacing.Width;
2969                                         } 
2970                                         else 
2971                                         {
2972                                                 x_offset = 1;
2973                                         }
2974
2975                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
2976                                         if (month_rect.IntersectsWith (clip_rectangle)) {
2977                                                 DrawSingleMonth (
2978                                                         dc,
2979                                                         clip_rectangle,
2980                                                         month_rect,
2981                                                         mc,
2982                                                         i,
2983                                                         j);
2984                                         }
2985                                 }
2986                         }
2987                         
2988                         Rectangle bottom_rect = new Rectangle (
2989                                                 client_rectangle.X,
2990                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
2991                                                 client_rectangle.Width,
2992                                                 date_cell_size.Height + 2);
2993                         // draw the today date if it's set
2994                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) 
2995                         {
2996                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), bottom_rect);
2997                                 if (mc.ShowToday) {
2998                                         int today_offset = 5;
2999                                         if (mc.ShowTodayCircle) 
3000                                         {
3001                                                 Rectangle today_circle_rect = new Rectangle (
3002                                                         client_rectangle.X + 5,
3003                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
3004                                                         date_cell_size.Width,
3005                                                         date_cell_size.Height);
3006                                                         DrawTodayCircle (dc, today_circle_rect);
3007                                                 today_offset += date_cell_size.Width + 5;
3008                                         }
3009                                         // draw today's date
3010                                         StringFormat text_format = new StringFormat();
3011                                         text_format.LineAlignment = StringAlignment.Center;
3012                                         text_format.Alignment = StringAlignment.Near;
3013                                         Rectangle today_rect = new Rectangle (
3014                                                         today_offset + client_rectangle.X,
3015                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
3016                                                         Math.Max(client_rectangle.Width - today_offset, 0),
3017                                                         date_cell_size.Height);
3018                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), mc.bold_font, GetControlForeBrush (mc.ForeColor), today_rect, text_format);
3019                                         text_format.Dispose ();
3020                                 }                               
3021                         }
3022                         
3023                         // finally paint the borders of the calendars as required
3024                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
3025                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
3026                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height);
3027                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
3028                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), client_rectangle.Right-1, client_rectangle.Y, 1, client_rectangle.Height);
3029                                 } else { 
3030                                         Rectangle rect = new Rectangle (
3031                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
3032                                                 client_rectangle.Y,
3033                                                 calendar_spacing.Width,
3034                                                 client_rectangle.Height);
3035                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3036                                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), rect);
3037                                         }
3038                                 }
3039                         }
3040                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
3041                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
3042                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1);
3043                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
3044                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), client_rectangle.X, client_rectangle.Bottom-1, client_rectangle.Width, 1);
3045                                 } else { 
3046                                         Rectangle rect = new Rectangle (
3047                                                 client_rectangle.X,
3048                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
3049                                                 client_rectangle.Width,
3050                                                 calendar_spacing.Height);
3051                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
3052                                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), rect);
3053                                         }
3054                                 }
3055                         }
3056                         
3057                         // draw the drop down border if need
3058                         if (mc.owner != null) {
3059                                 Rectangle bounds = mc.ClientRectangle;
3060                                 if (clip_rectangle.Contains (mc.Location)) {
3061                                         // find out if top or left line to draw
3062                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3063                                         
3064                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
3065                                         }
3066                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3067                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
3068                                         }
3069                                 }
3070                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
3071                                         // find out if bottom or right line to draw
3072                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
3073                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
3074                                         }
3075                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
3076                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
3077                                         }
3078                                 }
3079                         }
3080                 }
3081
3082                 // darws a single part of the month calendar (with one month)
3083                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) 
3084                 {
3085                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
3086                         Size title_size = (Size)((object)mc.title_size);
3087                         Size date_cell_size = (Size)((object)mc.date_cell_size);
3088                         DateTime current_month = (DateTime)((object)mc.current_month);
3089                         DateTime sunday = new DateTime(2006, 10, 1);
3090                         
3091                         // draw the title back ground
3092                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
3093                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
3094                         if (title_rect.IntersectsWith (clip_rectangle)) {
3095                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
3096                                 // draw the title                               
3097                                 string title_text = this_month.ToString ("MMMM yyyy");
3098                                 dc.DrawString (title_text, mc.bold_font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, mc.centered_format);
3099
3100                                 if (mc.ShowYearUpDown) {
3101                                         Rectangle year_rect;
3102                                         Rectangle upRect, downRect;
3103                                         ButtonState upState, downState;
3104                                         
3105                                         mc.GetYearNameRectangles (title_rect, row * mc.CalendarDimensions.Width + col, out year_rect, out upRect, out downRect);
3106                                         dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control), year_rect);
3107                                         dc.DrawString (this_month.ToString ("yyyy"), mc.bold_font, ResPool.GetSolidBrush (Color.Black), year_rect, mc.centered_format);
3108                                         
3109                                         upState = mc.IsYearGoingUp ? ButtonState.Pushed : ButtonState.Normal;
3110                                         downState = mc.IsYearGoingDown ? ButtonState.Pushed : ButtonState.Normal;
3111
3112                                         ControlPaint.DrawScrollButton (dc, upRect, ScrollButton.Up, upState);
3113                                         ControlPaint.DrawScrollButton (dc, downRect, ScrollButton.Down, downState);
3114                                 }
3115
3116                                 // draw previous and next buttons if it's time
3117                                 if (row == 0 && col == 0) 
3118                                 {
3119                                         // draw previous button
3120                                         DrawMonthCalendarButton (
3121                                                 dc,
3122                                                 rectangle,
3123                                                 mc,
3124                                                 title_size,
3125                                                 mc.button_x_offset,
3126                                                 (System.Drawing.Size)((object)mc.button_size),
3127                                                 true);
3128                                 }
3129                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) 
3130                                 {
3131                                         // draw next button
3132                                         DrawMonthCalendarButton (
3133                                                 dc,
3134                                                 rectangle,
3135                                                 mc,
3136                                                 title_size,
3137                                                 mc.button_x_offset,
3138                                                 (System.Drawing.Size)((object)mc.button_size),
3139                                                 false);
3140                                 }
3141                         }
3142                         
3143                         // set the week offset and draw week nums if needed
3144                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
3145                         Rectangle day_name_rect = new Rectangle(
3146                                 rectangle.X,
3147                                 rectangle.Y + title_size.Height,
3148                                 (7 + col_offset) * date_cell_size.Width,
3149                                 date_cell_size.Height);
3150                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
3151                                 dc.FillRectangle (GetControlBackBrush (mc.BackColor), day_name_rect);
3152                                 // draw the day names 
3153                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
3154                                 for (int i=0; i < 7; i++) 
3155                                 {
3156                                         int position = i - (int) first_day_of_week;
3157                                         if (position < 0) 
3158                                         {
3159                                                 position = 7 + position;
3160                                         }
3161                                         // draw it
3162                                         Rectangle day_rect = new Rectangle(
3163                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
3164                                                 day_name_rect.Y,
3165                                                 date_cell_size.Width,
3166                                                 date_cell_size.Height);
3167                                         dc.DrawString (sunday.AddDays (i + (int) first_day_of_week).ToString ("ddd"), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, mc.centered_format);
3168                                 }
3169                                 
3170                                 // draw the vertical divider
3171                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
3172                                 dc.DrawLine (
3173                                         ResPool.GetPen (mc.ForeColor),
3174                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
3175                                         rectangle.Y + vert_divider_y,
3176                                         rectangle.Right - mc.divider_line_offset,
3177                                         rectangle.Y + vert_divider_y);
3178                         }
3179
3180
3181                         // draw the actual date items in the grid (including the week numbers)
3182                         Rectangle date_rect = new Rectangle (
3183                                 rectangle.X,
3184                                 rectangle.Y + title_size.Height + date_cell_size.Height,
3185                                 date_cell_size.Width,
3186                                 date_cell_size.Height);
3187                         int month_row_count = 0;
3188                         bool draw_week_num_divider = false;
3189                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
3190                         for (int i=0; i < 6; i++) 
3191                         {
3192                                 // establish if this row is in our clip_area
3193                                 Rectangle row_rect = new Rectangle (
3194                                         rectangle.X,
3195                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
3196                                         date_cell_size.Width * 7,
3197                                         date_cell_size.Height);
3198                                 if (mc.ShowWeekNumbers) {
3199                                         row_rect.Width += date_cell_size.Width;
3200                                 }
3201                 
3202                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
3203                                 if (draw_row) {
3204                                         dc.FillRectangle (GetControlBackBrush (mc.BackColor), row_rect);
3205                                 }
3206                                 // establish if this is a valid week to draw
3207                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
3208                                         month_row_count = i;
3209                                 }
3210                                 
3211                                 // draw the week number if required
3212                                 if (mc.ShowWeekNumbers && month_row_count == i) {
3213                                         if (!draw_week_num_divider) {
3214                                                 draw_week_num_divider = draw_row;
3215                                         }
3216                                         // get the week for this row
3217                                         int week = mc.GetWeekOfYear (current_date);     
3218
3219                                         if (draw_row) {
3220                                                 dc.DrawString (
3221                                                         week.ToString(),
3222                                                         mc.Font,
3223                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
3224                                                         date_rect,
3225                                                         mc.centered_format);
3226                                         }
3227                                         date_rect.Offset(date_cell_size.Width, 0);
3228                                 }
3229                                                                 
3230                                 // only draw the days if we have to
3231                                 if(month_row_count == i) {
3232                                         for (int j=0; j < 7; j++) 
3233                                         {
3234                                                 if (draw_row) {
3235                                                         DrawMonthCalendarDate (
3236                                                                 dc,
3237                                                                 date_rect,
3238                                                                 mc,
3239                                                                 current_date,
3240                                                                 this_month,
3241                                                                 row,
3242                                                                 col);
3243                                                 }
3244
3245                                                 // move the day on
3246                                                 current_date = current_date.AddDays(1);
3247                                                 date_rect.Offset(date_cell_size.Width, 0);
3248                                         }
3249
3250                                         // shift the rectangle down one row
3251                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
3252                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
3253                                 }
3254                         }
3255
3256                         // month_row_count is zero based, so add one
3257                         month_row_count++;
3258
3259                         // draw week numbers if required
3260                         if (draw_week_num_divider) {
3261                                 col_offset = 1;
3262                                 dc.DrawLine (
3263                                         ResPool.GetPen (mc.ForeColor),
3264                                         rectangle.X + date_cell_size.Width - 1,
3265                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
3266                                         rectangle.X + date_cell_size.Width - 1,
3267                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
3268                         }
3269                 }
3270
3271                 // draws the pervious or next button
3272                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) 
3273                 {
3274                         bool is_clicked = false;
3275                         Rectangle button_rect;
3276                         Rectangle arrow_rect = new Rectangle (rectangle.X, rectangle.Y, 4, 7);
3277                         Point[] arrow_path = new Point[3];
3278                         // prepare the button
3279                         if (is_previous) 
3280                         {
3281                                 is_clicked = mc.is_previous_clicked;
3282                                 button_rect = new Rectangle (
3283                                         rectangle.X + 1 + x_offset,
3284                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3285                                         Math.Max(button_size.Width - 1, 0),
3286                                         Math.Max(button_size.Height - 1, 0));
3287                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
3288                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
3289                                 if (is_clicked) {
3290                                         arrow_rect.Offset(1,1);
3291                                 }
3292                                 arrow_path[0] = new Point (arrow_rect.Right, arrow_rect.Y);
3293                                 arrow_path[1] = new Point (arrow_rect.X, arrow_rect.Y + arrow_rect.Height/2);
3294                                 arrow_path[2] = new Point (arrow_rect.Right, arrow_rect.Bottom);
3295                         }
3296                         else
3297                         {
3298                                 is_clicked = mc.is_next_clicked;
3299                                 button_rect = new Rectangle (
3300                                         rectangle.Right - 1 - x_offset - button_size.Width,
3301                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
3302                                         Math.Max(button_size.Width - 1, 0),
3303                                         Math.Max(button_size.Height - 1, 0));
3304                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
3305                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
3306                                 if (is_clicked) {
3307                                         arrow_rect.Offset(1,1);
3308                                 }
3309                                 arrow_path[0] = new Point (arrow_rect.X, arrow_rect.Y);
3310                                 arrow_path[1] = new Point (arrow_rect.Right, arrow_rect.Y + arrow_rect.Height/2);
3311                                 arrow_path[2] = new Point (arrow_rect.X, arrow_rect.Bottom);                            
3312                         }
3313
3314                         // fill the background
3315                         dc.FillRectangle (SystemBrushes.Control, button_rect);
3316                         // draw the border
3317                         if (is_clicked) {
3318                                 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
3319                         }
3320                         else {
3321                                 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
3322                         }
3323                         // draw the arrow
3324                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);                 
3325                 }
3326                 
3327
3328                 // draws one day in the calendar grid
3329                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
3330                         Color date_color = mc.ForeColor;
3331                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
3332
3333                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
3334                         if (date.Year != month.Year || date.Month != month.Month) {
3335                                 DateTime check_date = month.AddMonths (-1);
3336                                 // check if it's the month before 
3337                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
3338                                         date_color = mc.TrailingForeColor;
3339                                 } else {
3340                                         // check if it's the month after
3341                                         check_date = month.AddMonths (1);
3342                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
3343                                                 date_color = mc.TrailingForeColor;
3344                                         } else {
3345                                                 return;
3346                                         }
3347                                 }
3348                         } else {
3349                                 date_color = mc.ForeColor;
3350                         }
3351
3352                         const int inflate = -1;
3353                         if (date == mc.SelectionStart && date == mc.SelectionEnd) {
3354                                 // see if the date is in the start of selection
3355                                 date_color = mc.BackColor;
3356                                 // draw the left hand of the back ground
3357                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
3358                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 360);
3359                         } else if (date == mc.SelectionStart) {
3360                                 // see if the date is in the start of selection
3361                                 date_color = mc.BackColor;
3362                                 // draw the left hand of the back ground
3363                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);                             
3364                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
3365                                 // fill the other side as a straight rect
3366                                 if (date < mc.SelectionEnd) 
3367                                 {
3368                                         // use rectangle instead of rectangle to go all the way to edge of rect
3369                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
3370                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
3371                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3372                                 }
3373                         } else if (date == mc.SelectionEnd) {
3374                                 // see if it is the end of selection
3375                                 date_color = mc.BackColor;
3376                                 // draw the left hand of the back ground
3377                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, inflate, inflate);
3378                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
3379                                 // fill the other side as a straight rect
3380                                 if (date > mc.SelectionStart) {
3381                                         selection_rect.X = rectangle.X;
3382                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
3383                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3384                                 }
3385                         } else if (date > mc.SelectionStart && date < mc.SelectionEnd) {
3386                                 // now see if it's in the middle
3387                                 date_color = mc.BackColor;
3388                                 // draw the left hand of the back ground
3389                                 Rectangle selection_rect = Rectangle.Inflate (rectangle, 0, inflate);
3390                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
3391                         }
3392
3393                         // establish if it's a bolded font
3394                         Font font = mc.IsBoldedDate (date) ? mc.bold_font : mc.Font;
3395
3396                         // just draw the date now
3397                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, mc.centered_format);
3398
3399                         // today circle if needed
3400                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
3401                                 DrawTodayCircle (dc, interior);
3402                         }
3403
3404                         // draw the selection grid
3405                         if (mc.is_date_clicked && mc.clicked_date == date) {
3406                                 Pen pen = ResPool.GetDashPen (Color.Black, DashStyle.Dot);
3407                                 dc.DrawRectangle (pen, interior);
3408                         }
3409                 }
3410
3411                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
3412                         Color circle_color = Color.FromArgb (248, 0, 0);
3413                         // draw the left hand of the circle 
3414                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
3415                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
3416                         Point [] curve_points = new Point [3];
3417                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
3418                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
3419                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
3420
3421                         Pen pen = ResPool.GetSizedPen(circle_color, 2);
3422                         dc.DrawArc (pen, lhs_circle_rect, 90, 180);
3423                         dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
3424                         dc.DrawCurve (pen, curve_points);
3425                         dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
3426                 }
3427
3428                 #endregion      // MonthCalendar
3429
3430                 #region Panel
3431                 public override Size PanelDefaultSize {
3432                         get {
3433                                 return new Size (200, 100);
3434                         }
3435                 }
3436                 #endregion      // Panel
3437
3438                 #region PictureBox
3439                 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
3440                         Rectangle client = pb.ClientRectangle;
3441
3442                         // FIXME - instead of drawing the whole picturebox every time
3443                         // intersect the clip rectangle with the drawn picture and only draw what's needed,
3444                         // Also, we only need a background fill where no image goes
3445                         if (pb.Image != null) {
3446                                 switch (pb.SizeMode) {
3447                                 case PictureBoxSizeMode.StretchImage:
3448                                         dc.DrawImage (pb.Image, 0, 0, client.Width, client.Height);
3449                                         break;
3450
3451                                 case PictureBoxSizeMode.CenterImage:
3452                                         dc.FillRectangle(GetControlBackBrush (pb.BackColor), clip);
3453                                         dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
3454                                         break;
3455                                 default:
3456                                         dc.FillRectangle(GetControlBackBrush (pb.BackColor), clip);
3457                                         // Normal, AutoSize
3458                                         dc.DrawImage(pb.Image, 0, 0, pb.Image.Width, pb.Image.Height);
3459                                         break;
3460                                 }
3461
3462                                 return;
3463                         }
3464
3465                         // We only get here if no image is set. At least paint the background
3466                         dc.FillRectangle(GetControlBackBrush (pb.BackColor), clip);
3467                 }
3468
3469                 public override Size PictureBoxDefaultSize {
3470                         get {
3471                                 return new Size (100, 50);
3472                         }
3473                 }
3474                 #endregion      // PictureBox
3475
3476                 #region PrintPreviewControl
3477                 public override int PrintPreviewControlPadding {
3478                         get { return 8; }
3479                 }
3480
3481                 public override Size PrintPreviewControlGetPageSize (PrintPreviewControl preview)
3482                 {
3483                         int page_width, page_height;
3484                         int padding = PrintPreviewControlPadding;
3485                         PreviewPageInfo[] pis = preview.page_infos;
3486
3487                         if (preview.AutoZoom) {
3488                                 int height_available = preview.ClientRectangle.Height - (preview.Rows) * padding - 2 * padding;
3489                                 int width_available = preview.ClientRectangle.Width - (preview.Columns - 1) * padding - 2 * padding;
3490
3491                                 float image_ratio = (float)pis[0].Image.Width / pis[0].Image.Height;
3492
3493                                 /* try to lay things out using the width to determine the size */
3494                                 page_width = width_available / preview.Columns;
3495                                 page_height = (int)(page_width / image_ratio);
3496
3497                                 /* does the height fit? */
3498                                 if (page_height * (preview.Rows + 1) > height_available) {
3499                                         /* no, lay things out via the height */
3500                                         page_height = height_available / (preview.Rows + 1);
3501                                         page_width = (int)(page_height * image_ratio);
3502                                 }
3503                         }
3504                         else {
3505                                 page_width = (int)(pis[0].Image.Width * preview.Zoom);
3506                                 page_height = (int)(pis[0].Image.Height * preview.Zoom);
3507                         }
3508
3509                         return new Size (page_width, page_height);
3510                 }
3511
3512                 public override void PrintPreviewControlPaint (PaintEventArgs pe, PrintPreviewControl preview, Size page_size)
3513                 {
3514                         int padding = 8;
3515                         PreviewPageInfo[] pis = preview.page_infos;
3516                         if (pis == null)
3517                                 return;
3518
3519                         int page_x, page_y;
3520
3521                         int width = page_size.Width * preview.Columns + padding * (preview.Columns - 1) + 2 * padding;
3522                         int height = page_size.Height * (preview.Rows + 1) + padding * preview.Rows + 2 * padding;
3523
3524                         Rectangle viewport = preview.ViewPort;
3525
3526                         pe.Graphics.Clip = new Region (viewport);
3527
3528                         /* center things if we can */
3529                         int off_x = viewport.Width / 2 - width / 2;
3530                         if (off_x < 0) off_x = 0;
3531                         int off_y = viewport.Height / 2 - height / 2;
3532                         if (off_y < 0) off_y = 0;
3533
3534                         page_y = off_y + padding - preview.vbar_value;
3535
3536                         if (preview.StartPage > 0) {
3537                                 int p = preview.StartPage - 1;
3538                                 for (int py = 0; py < preview.Rows + 1; py ++) {
3539                                         page_x = off_x + padding - preview.hbar_value;
3540                                         for (int px = 0; px < preview.Columns; px ++) {
3541                                                 if (p >= pis.Length)
3542                                                         continue;
3543                                                 Image image = preview.image_cache[p];
3544                                                 if (image == null)
3545                                                         image = pis[p].Image;
3546                                                 Rectangle dest = new Rectangle (new Point (page_x, page_y), page_size);
3547
3548                                                 pe.Graphics.DrawImage (image, dest, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
3549
3550                                                 page_x += padding + page_size.Width;
3551                                                 p++;
3552                                         }
3553                                         page_y += padding + page_size.Height;
3554                                 }
3555                         }
3556                 }
3557                 #endregion      // PrintPreviewControl
3558
3559                 #region ProgressBar
3560                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) 
3561                 {
3562                         Rectangle client_area = ctrl.client_area;
3563                         
3564                         /* Draw border */
3565                         CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenOuter, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom & ~Border3DSide.Middle, ColorControl);
3566                         
3567                         /* Draw Blocks */
3568                         int draw_mode = 0;
3569                         int max_blocks = int.MaxValue;
3570                         int start_pixel = client_area.X;
3571 #if NET_2_0
3572                         draw_mode = (int) ctrl.Style;
3573 #endif
3574                         switch (draw_mode) {
3575 #if NET_2_0
3576                         case 1: { // Continuous
3577                                 int pixels_to_draw;
3578                                 pixels_to_draw = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(ctrl.Maximum - ctrl.Minimum)));
3579                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), new Rectangle (client_area.X, client_area.Y, pixels_to_draw, client_area.Height));
3580                                 break;
3581                         }
3582                         case 2: // Marquee
3583                                 if (XplatUI.ThemesEnabled) {
3584                                         int ms_diff = (int) (DateTime.Now - ctrl.start).TotalMilliseconds;
3585                                         double percent_done = (double) ms_diff % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
3586                                         max_blocks = 5;
3587                                         start_pixel = client_area.X + (int) (client_area.Width * percent_done);
3588                                 }
3589                                 
3590                                 goto case 0;
3591 #endif
3592                         case 0:
3593                         default:  // Blocks
3594                                 Rectangle block_rect;
3595                                 int space_betweenblocks = 2;
3596                                 int block_width;
3597                                 int increment;
3598                                 int barpos_pixels;
3599                                 int block_count = 0;
3600                                 
3601                                 block_width = (client_area.Height * 2) / 3;
3602                                 barpos_pixels = ((ctrl.Value - ctrl.Minimum) * client_area.Width) / (ctrl.Maximum - ctrl.Minimum);
3603                                 increment = block_width + space_betweenblocks;
3604                                 
3605                                 block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
3606                                 while (true) {
3607                                         if (max_blocks != int.MaxValue) {
3608                                                 if (block_count >= max_blocks)
3609                                                         break;
3610                                                 if (block_rect.X > client_area.Width)
3611                                                         block_rect.X -= client_area.Width;
3612                                         } else {
3613                                                 if ((block_rect.X - client_area.X) >= barpos_pixels)
3614                                                         break;
3615                                         }
3616                                         
3617                                         if (clip_rect.IntersectsWith (block_rect) == true) {                            
3618                                                 dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), block_rect);
3619                                         }                               
3620                                         
3621                                         block_rect.X  += increment;
3622                                         block_count++;
3623                                 }
3624                                 break;
3625                         
3626                         }
3627                 }
3628                 
3629                 public override Size ProgressBarDefaultSize {
3630                         get {
3631                                 return new Size (100, 23);
3632                         }
3633                 }
3634
3635                 #endregion      // ProgressBar
3636
3637                 #region RadioButton
3638                 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
3639                         StringFormat    text_format;
3640                         Rectangle       client_rectangle;
3641                         Rectangle       text_rectangle;
3642                         Rectangle       radiobutton_rectangle;
3643                         int             radiobutton_size = 13;
3644                         int     radiobutton_space = 4;
3645
3646                         client_rectangle = radio_button.ClientRectangle;
3647                         text_rectangle = client_rectangle;
3648                         radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
3649
3650                         text_format = new StringFormat();
3651                         text_format.Alignment = StringAlignment.Near;
3652                         text_format.LineAlignment = StringAlignment.Center;
3653                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
3654
3655                         /* Calculate the position of text and checkbox rectangle */
3656                         if (radio_button.appearance!=Appearance.Button) {
3657                                 switch(radio_button.radiobutton_alignment) {
3658                                 case ContentAlignment.BottomCenter: {
3659                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
3660                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
3661                                         text_rectangle.X=client_rectangle.X;
3662                                         text_rectangle.Width=client_rectangle.Width;
3663                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
3664                                         break;
3665                                 }
3666
3667                                 case ContentAlignment.BottomLeft: {
3668                                         radiobutton_rectangle.X=client_rectangle.Left;
3669                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
3670                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
3671                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;                                 
3672                                         break;
3673                                 }
3674
3675                                 case ContentAlignment.BottomRight: {
3676                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
3677                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
3678                                         text_rectangle.X=client_rectangle.X;
3679                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
3680                                         break;
3681                                 }
3682
3683                                 case ContentAlignment.MiddleCenter: {
3684                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
3685                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
3686                                         text_rectangle.X=client_rectangle.X;
3687                                         text_rectangle.Width=client_rectangle.Width;
3688                                         break;
3689                                 }
3690
3691                                 default:
3692                                 case ContentAlignment.MiddleLeft: {
3693                                         radiobutton_rectangle.X=client_rectangle.Left;
3694                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
3695                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
3696                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
3697                                         break;
3698                                 }
3699
3700                                 case ContentAlignment.MiddleRight: {
3701                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
3702                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
3703                                         text_rectangle.X=client_rectangle.X;
3704                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
3705                                         break;
3706                                 }
3707
3708                                 case ContentAlignment.TopCenter: {
3709                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
3710                                         radiobutton_rectangle.Y=client_rectangle.Top;
3711                                         text_rectangle.X=client_rectangle.X;
3712                                         text_rectangle.Y=radiobutton_size+radiobutton_space;
3713                                         text_rectangle.Width=client_rectangle.Width;
3714                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
3715                                         break;
3716                                 }
3717
3718                                 case ContentAlignment.TopLeft: {
3719                                         radiobutton_rectangle.X=client_rectangle.Left;
3720                                         radiobutton_rectangle.Y=client_rectangle.Top;
3721                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
3722                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
3723                                         break;
3724                                 }
3725
3726                                 case ContentAlignment.TopRight: {
3727                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
3728                                         radiobutton_rectangle.Y=client_rectangle.Top;
3729                                         text_rectangle.X=client_rectangle.X;
3730                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
3731                                         break;
3732                                 }
3733                                 }
3734                         } else {
3735                                 text_rectangle.X=client_rectangle.X;
3736                                 text_rectangle.Width=client_rectangle.Width;
3737                         }
3738                         
3739                         /* Set the horizontal alignment of our text */
3740                         switch(radio_button.text_alignment) {
3741                                 case ContentAlignment.BottomLeft:
3742                                 case ContentAlignment.MiddleLeft:
3743                                 case ContentAlignment.TopLeft: {
3744                                         text_format.Alignment=StringAlignment.Near;
3745                                         break;
3746                                 }
3747
3748                                 case ContentAlignment.BottomCenter:
3749                                 case ContentAlignment.MiddleCenter:
3750                                 case ContentAlignment.TopCenter: {
3751                                         text_format.Alignment=StringAlignment.Center;
3752                                         break;
3753                                 }
3754
3755                                 case ContentAlignment.BottomRight:
3756                                 case ContentAlignment.MiddleRight:
3757                                 case ContentAlignment.TopRight: {
3758                                         text_format.Alignment=StringAlignment.Far;
3759                                         break;
3760                                 }
3761                         }
3762
3763                         /* Set the vertical alignment of our text */
3764                         switch(radio_button.text_alignment) {
3765                                 case ContentAlignment.TopLeft: 
3766                                 case ContentAlignment.TopCenter: 
3767                                 case ContentAlignment.TopRight: {
3768                                         text_format.LineAlignment=StringAlignment.Near;
3769                                         break;
3770                                 }
3771
3772                                 case ContentAlignment.BottomLeft:
3773                                 case ContentAlignment.BottomCenter:
3774                                 case ContentAlignment.BottomRight: {
3775                                         text_format.LineAlignment=StringAlignment.Far;
3776                                         break;
3777                                 }
3778
3779                                 case ContentAlignment.MiddleLeft:
3780                                 case ContentAlignment.MiddleCenter:
3781                                 case ContentAlignment.MiddleRight: {
3782                                         text_format.LineAlignment=StringAlignment.Center;
3783                                         break;
3784                                 }
3785                         }
3786
3787                         ButtonState state = ButtonState.Normal;
3788                         if (radio_button.FlatStyle == FlatStyle.Flat) {
3789                                 state |= ButtonState.Flat;
3790                         }
3791                         
3792                         if (radio_button.Checked) {
3793                                 state |= ButtonState.Checked;
3794                         }
3795                         
3796                         if (!radio_button.Enabled) {
3797                                 state |= ButtonState.Inactive;
3798                         }
3799
3800                         // Start drawing
3801                         RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
3802                         
3803                         if ((radio_button.image != null) || (radio_button.image_list != null))
3804                                 ButtonBase_DrawImage(radio_button, dc);
3805                         
3806                         RadioButton_DrawText(radio_button, text_rectangle, dc, text_format);
3807
3808                         RadioButton_DrawFocus(radio_button, dc, text_rectangle);
3809                         
3810                         text_format.Dispose ();
3811                 }
3812
3813                 protected virtual void RadioButton_DrawButton(RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
3814                 {
3815                         dc.FillRectangle(GetControlBackBrush (radio_button.BackColor), radio_button.ClientRectangle);
3816                         
3817                         if (radio_button.appearance==Appearance.Button) {
3818                                 ButtonBase_DrawButton (radio_button, dc);
3819                                 
3820                                 if ((radio_button.Focused) && radio_button.Enabled)
3821                                         ButtonBase_DrawFocus(radio_button, dc);
3822                         } else {
3823                                 // establish if we are rendering a flat style of some sort
3824                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
3825                                         DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
3826                                 } else {
3827                                         CPDrawRadioButton(dc, radiobutton_rectangle, state);
3828                                 }
3829                         }
3830                 }
3831                 
3832                 protected virtual void RadioButton_DrawText(RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
3833                 {
3834                         DrawCheckBox_and_RadioButtonText (radio_button, text_rectangle, dc, 
3835                                                           text_format, radio_button.Appearance, radio_button.Checked);
3836                 }
3837                 
3838                 protected virtual void RadioButton_DrawFocus(RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
3839                 {
3840                         if ( radio_button.Focused && radio_button.appearance != Appearance.Button && radio_button.Enabled )
3841                                 DrawInnerFocusRectangle( dc, text_rectangle, radio_button.BackColor );
3842                 }
3843                 
3844                 
3845                 // renders a radio button with the Flat and Popup FlatStyle
3846                 protected virtual void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
3847                 {
3848                         int     lineWidth;
3849                         
3850                         if (radio_button.Enabled) {
3851                                 
3852                                 // draw the outer flatstyle arcs
3853                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
3854                                         graphics.DrawArc (SystemPens.ControlDarkDark, rectangle, 0, 359);
3855                                         
3856                                         // fill in the area depending on whether or not the mouse is hovering
3857                                         if ((radio_button.is_entered || radio_button.Capture) && !radio_button.is_pressed) {
3858                                                 graphics.FillPie (SystemBrushes.ControlLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
3859                                         } else {
3860                                                 graphics.FillPie (SystemBrushes.ControlLightLight, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
3861                                         }
3862                                 } else {
3863                                         // must be a popup radio button
3864                                         // fill the control
3865                                         graphics.FillPie (SystemBrushes.ControlLightLight, rectangle, 0, 359);
3866
3867                                         if (radio_button.is_entered || radio_button.Capture) {
3868                                                 // draw the popup 3d button knob
3869                                                 graphics.DrawArc (SystemPens.ControlLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
3870
3871                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 135, 180);
3872                                                 graphics.DrawArc (SystemPens.ControlLightLight, rectangle, 315, 180);
3873                                                 
3874                                         } else {
3875                                                 // just draw lighter flatstyle outer circle
3876                                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);                                           
3877                                         }                                                                               
3878                                 }
3879                         } else {
3880                                 // disabled
3881                                 // fill control background color regardless of actual backcolor
3882                                 graphics.FillPie (SystemBrushes.Control, rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
3883                                 // draw the ark as control dark
3884                                 graphics.DrawArc (SystemPens.ControlDark, rectangle, 0, 359);
3885                         }
3886
3887                         // draw the check
3888                         if (radio_button.Checked) {
3889                                 lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
3890                                 
3891                                 Pen dot_pen = SystemPens.ControlDarkDark;
3892                                 Brush dot_brush = SystemBrushes.ControlDarkDark;
3893
3894                                 if (!radio_button.Enabled || ((radio_button.FlatStyle == FlatStyle.Popup) && radio_button.is_pressed)) {
3895                                         dot_pen = SystemPens.ControlDark;
3896                                         dot_brush = SystemBrushes.ControlDark;
3897                                 } 
3898                                 
3899                                 if (rectangle.Height >  13) {
3900                                         graphics.FillPie (dot_brush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
3901                                 } else {
3902                                         int x_half_pos = (rectangle.Width / 2) + rectangle.X;
3903                                         int y_half_pos = (rectangle.Height / 2) + rectangle.Y;
3904                                         
3905                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos, x_half_pos + 2, y_half_pos);
3906                                         graphics.DrawLine (dot_pen, x_half_pos - 1, y_half_pos + 1, x_half_pos + 2, y_half_pos + 1);
3907                                         
3908                                         graphics.DrawLine (dot_pen, x_half_pos, y_half_pos - 1, x_half_pos, y_half_pos + 2);
3909                                         graphics.DrawLine (dot_pen, x_half_pos + 1, y_half_pos - 1, x_half_pos + 1, y_half_pos + 2);
3910                                 }
3911                         }
3912                 }
3913
3914                 public override Size RadioButtonDefaultSize {
3915                         get {
3916                                 return new Size (104,24);
3917                         }
3918                 }
3919                 #endregion      // RadioButton
3920
3921                 #region ScrollBar
3922                 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
3923                 {
3924                         int             scrollbutton_width = bar.scrollbutton_width;
3925                         int             scrollbutton_height = bar.scrollbutton_height;
3926                         Rectangle       first_arrow_area;
3927                         Rectangle       second_arrow_area;                      
3928                         Rectangle       thumb_pos;
3929                         
3930                         thumb_pos = bar.ThumbPos;
3931
3932                         if (bar.vert) {
3933                                 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
3934                                 bar.FirstArrowArea = first_arrow_area;
3935
3936                                 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
3937                                 bar.SecondArrowArea = second_arrow_area;
3938
3939                                 thumb_pos.Width = bar.Width;
3940                                 bar.ThumbPos = thumb_pos;
3941
3942                                 /* Buttons */
3943                                 if (clip.IntersectsWith (first_arrow_area))
3944                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
3945                                 if (clip.IntersectsWith (second_arrow_area))
3946                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
3947
3948                                 /* Background */
3949                                 switch (bar.thumb_moving) {
3950                                 case ScrollBar.ThumbMoving.None: {
3951                                         ScrollBar_Vertical_Draw_ThumbMoving_None(scrollbutton_height, bar, clip, dc);
3952                                         break;
3953                                 }
3954                                 case ScrollBar.ThumbMoving.Forward: {
3955                                         ScrollBar_Vertical_Draw_ThumbMoving_Forward(scrollbutton_height, bar, thumb_pos, clip, dc);
3956                                         break;
3957                                 }
3958                                 
3959                                 case ScrollBar.ThumbMoving.Backwards: {
3960                                         ScrollBar_Vertical_Draw_ThumbMoving_Backwards(scrollbutton_height, bar, thumb_pos, clip, dc);
3961                                         break;
3962                                 }
3963                                 
3964                                 default:
3965                                         break;
3966                                 }
3967                         } else {
3968                                 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
3969                                 bar.FirstArrowArea = first_arrow_area;
3970
3971                                 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
3972                                 bar.SecondArrowArea = second_arrow_area;
3973
3974                                 thumb_pos.Height = bar.Height;
3975                                 bar.ThumbPos = thumb_pos;
3976
3977                                 /* Buttons */
3978                                 if (clip.IntersectsWith (first_arrow_area))
3979                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
3980                                 if (clip.IntersectsWith (second_arrow_area))
3981                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
3982
3983                                 /* Background */                                        
3984                                 switch (bar.thumb_moving) {
3985                                 case ScrollBar.ThumbMoving.None: {
3986                                         ScrollBar_Horizontal_Draw_ThumbMoving_None(scrollbutton_width, bar, clip, dc);
3987                                         break;
3988                                 }
3989                                 
3990                                 case ScrollBar.ThumbMoving.Forward: {
3991                                         ScrollBar_Horizontal_Draw_ThumbMoving_Forward(scrollbutton_width, thumb_pos, bar, clip, dc);
3992                                         break;
3993                                 }
3994                                 
3995                                 case ScrollBar.ThumbMoving.Backwards: {
3996                                         ScrollBar_Horizontal_Draw_ThumbMoving_Backwards(scrollbutton_width, thumb_pos, bar, clip, dc);
3997                                         break;
3998                                 }
3999                                 }
4000                         }
4001
4002                         /* Thumb */
4003                         ScrollBar_DrawThumb(bar, thumb_pos, clip, dc);                          
4004                 }
4005
4006                 protected virtual void ScrollBar_DrawThumb(ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc)
4007                 {
4008                         if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith(thumb_pos))
4009                                 DrawScrollButtonPrimitive(dc, thumb_pos, ButtonState.Normal);
4010                 }
4011
4012                 protected virtual void ScrollBar_Vertical_Draw_ThumbMoving_None( int scrollbutton_height, ScrollBar bar, Rectangle clip, Graphics dc )
4013                 {
4014                         Rectangle r = new Rectangle( 0,  
4015                                                     scrollbutton_height, bar.ClientRectangle.Width, bar.ClientRectangle.Height - ( scrollbutton_height * 2 ) );
4016                         Rectangle intersect = Rectangle.Intersect( clip, r );
4017
4018                         if ( intersect != Rectangle.Empty )
4019                         {
4020                                 Brush h = ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White);
4021                                 dc.FillRectangle( h, intersect );
4022                         }
4023                 }
4024                 
4025                 protected virtual void ScrollBar_Vertical_Draw_ThumbMoving_Forward( int scrollbutton_height, ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc )
4026                 {
4027                         Rectangle r = new Rectangle( 0,  scrollbutton_height,
4028                                                     bar.ClientRectangle.Width, thumb_pos.Y - scrollbutton_height );
4029                         Rectangle intersect = Rectangle.Intersect( clip, r );
4030                         
4031                         if ( intersect != Rectangle.Empty )
4032                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White ), intersect );
4033                         
4034                         r.X = 0;
4035                         r.Y = thumb_pos.Y + thumb_pos.Height;
4036                         r.Width = bar.ClientRectangle.Width;
4037                         r.Height = bar.ClientRectangle.Height -  ( thumb_pos.Y + thumb_pos.Height ) - scrollbutton_height;
4038                         
4039                         intersect = Rectangle.Intersect( clip, r );
4040                         if ( intersect != Rectangle.Empty )
4041                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
4042                 }
4043                 
4044                 protected virtual void ScrollBar_Vertical_Draw_ThumbMoving_Backwards( int scrollbutton_height, ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc )
4045                 {
4046                         Rectangle r = new Rectangle( 0,  scrollbutton_height,
4047                                                     bar.ClientRectangle.Width, thumb_pos.Y - scrollbutton_height );
4048                         Rectangle intersect = Rectangle.Intersect( clip, r );
4049                         
4050                         if ( intersect != Rectangle.Empty )
4051                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
4052                         
4053                         r.X = 0;
4054                         r.Y = thumb_pos.Y + thumb_pos.Height;
4055                         r.Width = bar.ClientRectangle.Width; 
4056                         r.Height = bar.ClientRectangle.Height -  ( thumb_pos.Y + thumb_pos.Height ) - scrollbutton_height;
4057                         
4058                         intersect = Rectangle.Intersect( clip, r );
4059                         if ( intersect != Rectangle.Empty )
4060                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
4061                 }
4062                 
4063                 protected virtual void ScrollBar_Horizontal_Draw_ThumbMoving_None( int scrollbutton_width, ScrollBar bar, Rectangle clip, Graphics dc )
4064                 {
4065                         Rectangle r = new Rectangle( scrollbutton_width,
4066                                                     0, bar.ClientRectangle.Width - ( scrollbutton_width * 2 ), bar.ClientRectangle.Height );
4067                         Rectangle intersect = Rectangle.Intersect( clip, r );
4068                         
4069                         if ( intersect != Rectangle.Empty )
4070                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
4071                 }
4072                 
4073                 protected virtual void ScrollBar_Horizontal_Draw_ThumbMoving_Forward( int scrollbutton_width, Rectangle thumb_pos, ScrollBar bar, Rectangle clip, Graphics dc )
4074                 {
4075                         Rectangle r = new Rectangle( scrollbutton_width,  0,
4076                                                     thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height );
4077                         Rectangle intersect = Rectangle.Intersect( clip, r );
4078                         
4079                         if ( intersect != Rectangle.Empty )
4080                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
4081                         
4082                         r.X = thumb_pos.X + thumb_pos.Width;
4083                         r.Y = 0;
4084                         r.Width = bar.ClientRectangle.Width -  ( thumb_pos.X + thumb_pos.Width ) - scrollbutton_width;
4085                         r.Height = bar.ClientRectangle.Height;
4086                         
4087                         intersect = Rectangle.Intersect( clip, r );
4088                         if ( intersect != Rectangle.Empty )
4089                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
4090                 }
4091                 
4092                 protected virtual void ScrollBar_Horizontal_Draw_ThumbMoving_Backwards( int scrollbutton_width, Rectangle thumb_pos, ScrollBar bar, Rectangle clip, Graphics dc )
4093                 {
4094                         Rectangle r = new Rectangle( scrollbutton_width,  0,
4095                                                     thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height );
4096                         Rectangle intersect = Rectangle.Intersect( clip, r );
4097                         
4098                         if ( intersect != Rectangle.Empty )
4099                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, Color.FromArgb( 255, 63, 63, 63 ), Color.Black ), intersect );
4100                         
4101                         r.X = thumb_pos.X + thumb_pos.Width;
4102                         r.Y = 0;
4103                         r.Width = bar.ClientRectangle.Width -  ( thumb_pos.X + thumb_pos.Width ) - scrollbutton_width;
4104                         r.Height = bar.ClientRectangle.Height;
4105                         
4106                         intersect = Rectangle.Intersect( clip, r );
4107                         if ( intersect != Rectangle.Empty )
4108                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorScrollBar, Color.White), intersect );
4109                 }
4110
4111                 public override int ScrollBarButtonSize {
4112                         get { return 16; }
4113                 }
4114                 #endregion      // ScrollBar
4115
4116                 #region StatusBar
4117                 public  override void DrawStatusBar (Graphics dc, Rectangle clip, StatusBar sb) {
4118                         Rectangle area = sb.ClientRectangle;
4119                         int horz_border = 2;
4120                         int vert_border = 2;
4121                         
4122                         bool is_color_control = sb.BackColor.ToArgb () == ColorControl.ToArgb ();
4123
4124                         Brush brush = is_color_control ? SystemBrushes.Control : ResPool.GetSolidBrush (sb.BackColor);
4125                         dc.FillRectangle (brush, clip);
4126                         
4127                         if (!sb.ShowPanels && sb.Text != String.Empty) {
4128                                 string text = sb.Text;
4129                                 StringFormat string_format = new StringFormat ();
4130                                 string_format.Trimming = StringTrimming.Character;
4131                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
4132                                 
4133                                 if (text.Length > 127)
4134                                         text = text.Substring (0, 127);
4135
4136                                 if (text [0] == '\t') {
4137                                         string_format.Alignment = StringAlignment.Center;
4138                                         text = text.Substring (1);
4139                                         if (text [0] == '\t') {
4140                                                 string_format.Alignment = StringAlignment.Far;
4141                                                 text = text.Substring (1);
4142                                         }
4143                                 }
4144                 
4145                                 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
4146                                                 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
4147                                 string_format.Dispose ();
4148                         } else if (sb.ShowPanels) {
4149                                 Brush br_forecolor = GetControlForeBrush (sb.ForeColor);
4150                                 int prev_x = area.X + horz_border;
4151                                 int y = area.Y + vert_border;
4152                                 for (int i = 0; i < sb.Panels.Count; i++) {
4153                                         Rectangle pr = new Rectangle (prev_x, y,
4154                                                 sb.Panels [i].Width, area.Height);
4155                                         prev_x += pr.Width + StatusBarHorzGapWidth;
4156                                         if (pr.IntersectsWith (clip))
4157                                                 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
4158                                 }
4159                         }
4160
4161                         if (sb.SizingGrip) {
4162                                 area = new Rectangle (area.Right - 16 - 2, area.Bottom - 12 - 1, 16, 16);
4163                                 CPDrawSizeGrip (dc, ColorControl, area);
4164                         }
4165
4166                 }
4167
4168
4169                 protected virtual void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
4170                         Brush br_forecolor, StatusBarPanel panel) {
4171                         int border_size = 3; // this is actually const, even if the border style is none
4172                         int icon_width = 16;
4173                         
4174                         area.Height -= border_size;
4175                         
4176                         if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
4177                                 Border3DStyle border_style = Border3DStyle.SunkenOuter;
4178                                 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
4179                                         border_style = Border3DStyle.RaisedInner;
4180                                         
4181                                 CPDrawBorder3D(dc, area, border_style, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, panel.Parent.BackColor);
4182                         }
4183                         
4184                         if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
4185                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
4186                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
4187                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor);
4188                                 panel.Parent.OnDrawItemInternal (e);
4189                                 return;
4190                         }
4191
4192                         if (panel.Text == String.Empty)
4193                                         return;
4194
4195                         string text = panel.Text;
4196                         StringFormat string_format = new StringFormat ();
4197                         string_format.Trimming = StringTrimming.Character;
4198                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4199
4200                         
4201                         if (text [0] == '\t') {
4202                                 string_format.Alignment = StringAlignment.Center;
4203                                 text = text.Substring (1);
4204                                 if (text [0] == '\t') {
4205                                         string_format.Alignment = StringAlignment.Far;
4206                                         text = text.Substring (1);
4207                                 }
4208                         }
4209
4210                         Rectangle string_rect = Rectangle.Empty;
4211                         int x;
4212                         int len;
4213                         int icon_x = 0;
4214                         int y = (area.Height / 2 - (int) panel.Parent.Font.Size / 2) - 1;
4215
4216                         switch (panel.Alignment) {
4217                         case HorizontalAlignment.Right:
4218                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4219                                 x = area.Right - len - 4;
4220                                 string_rect = new Rectangle (x, y, 
4221                                                 area.Right - x - border_size,
4222                                                 area.Bottom - y - border_size);
4223                                 if (panel.Icon != null) {
4224                                         icon_x = x - icon_width - 2;
4225                                 }
4226                                 break;
4227                         case HorizontalAlignment.Center:
4228                                 len = (int) dc.MeasureString (text, panel.Parent.Font).Width;
4229                                 x = (panel.Width / 2) + (len / 2);
4230                                 string_rect = new Rectangle (x, y, 
4231                                                 area.Right - x - border_size,
4232                                                 area.Bottom - y - border_size);
4233
4234                                 if (panel.Icon != null) {
4235                                         icon_x = x - icon_width - 2;
4236                                 }
4237                                 break;
4238
4239                                 
4240                         default:
4241                                 int left = area.Left + border_size;;
4242                                 if (panel.Icon != null) {
4243                                         icon_x = area.Left + 2;
4244                                         left = icon_x + icon_width + 2;
4245                                 }
4246
4247                                 x = left;
4248                                 string_rect = new Rectangle (x, y, 
4249                                                 area.Right - x - border_size,
4250                                                 area.Bottom - y - border_size);
4251                                 break;
4252                         }
4253
4254                         RectangleF clip_bounds = dc.ClipBounds;
4255                         dc.SetClip (area);
4256                         dc.DrawString (text, panel.Parent.Font, br_forecolor, string_rect, string_format);                      
4257                         dc.SetClip (clip_bounds);
4258
4259                         if (panel.Icon != null) {
4260                                 dc.DrawIcon (panel.Icon, new Rectangle (icon_x, y, icon_width, icon_width));
4261                         }
4262                 }
4263
4264                 public override int StatusBarSizeGripWidth {
4265                         get { return 15; }
4266                 }
4267
4268                 public override int StatusBarHorzGapWidth {
4269                         get { return 3; }
4270                 }
4271
4272                 public override Size StatusBarDefaultSize {
4273                         get {
4274                                 return new Size (100, 22);
4275                         }
4276                 }
4277                 #endregion      // StatusBar
4278
4279                 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
4280                 {
4281                         Brush brush = SystemBrushes.Control;
4282                         dc.FillRectangle (brush, area);
4283                         Rectangle panel_rect = GetTabPanelRectExt (tab);
4284
4285                         if (tab.Appearance == TabAppearance.Normal) {
4286                                 CPDrawBorder3D (dc, panel_rect, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top, ColorControl);
4287                                 CPDrawBorder3D (dc, panel_rect, Border3DStyle.Raised, Border3DSide.Right | Border3DSide.Bottom, ColorControl);
4288                         }
4289
4290                         if (tab.Alignment == TabAlignment.Top) {
4291                                 for (int r = tab.TabPages.Count; r > 0; r--) {
4292                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
4293                                                 if (i == tab.SelectedIndex)
4294                                                         continue;
4295                                                 if (r != tab.TabPages [i].Row)
4296                                                         continue;
4297                                                 Rectangle rect = tab.GetTabRect (i);
4298                                                 if (!rect.IntersectsWith (area))
4299                                                         continue;
4300                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
4301                                         }
4302                                 }
4303                         } else {
4304                                 for (int r = 0; r < tab.TabPages.Count; r++) {
4305                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
4306                                                 if (i == tab.SelectedIndex)
4307                                                         continue;
4308                                                 if (r != tab.TabPages [i].Row)
4309                                                         continue;
4310                                                 Rectangle rect = tab.GetTabRect (i);
4311                                                 if (!rect.IntersectsWith (area))
4312                                                         continue;
4313                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
4314                                         }
4315                                 }
4316                         }
4317
4318                         if (tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos) {
4319                                 Rectangle rect = tab.GetTabRect (tab.SelectedIndex);
4320                                 if (rect.IntersectsWith (area))
4321                                         DrawTab (dc, tab.TabPages [tab.SelectedIndex], tab, rect, true);
4322                         }
4323
4324                         if (tab.ShowSlider) {
4325                                 Rectangle right = GetTabControlRightScrollRect (tab);
4326                                 Rectangle left = GetTabControlLeftScrollRect (tab);
4327                                 CPDrawScrollButton (dc, right, ScrollButton.Right, tab.RightSliderState);
4328                                 CPDrawScrollButton (dc, left, ScrollButton.Left, tab.LeftSliderState);
4329                         }
4330                 }
4331
4332                 public override Rectangle GetTabControlLeftScrollRect (TabControl tab)
4333                 {
4334                         switch (tab.Alignment) {
4335                         case TabAlignment.Top:
4336                                 return new Rectangle (tab.ClientRectangle.Right - 34, tab.ClientRectangle.Top + 1, 17, 17);
4337                         default:
4338                                 Rectangle panel_rect = GetTabPanelRectExt (tab);
4339                                 return new Rectangle (tab.ClientRectangle.Right - 34, panel_rect.Bottom + 2, 17, 17);
4340                         }
4341                 }
4342
4343                 public override Rectangle GetTabControlRightScrollRect (TabControl tab)
4344                 {
4345                         switch (tab.Alignment) {
4346                         case TabAlignment.Top:
4347                                 return new Rectangle (tab.ClientRectangle.Right - 17, tab.ClientRectangle.Top + 1, 17, 17);
4348                         default:
4349                                 Rectangle panel_rect = GetTabPanelRectExt (tab);
4350                                 return new Rectangle (tab.ClientRectangle.Right - 17, panel_rect.Bottom + 2, 17, 17);
4351                         }
4352                 }
4353
4354                 public override Size TabControlDefaultItemSize {
4355                         get { return new Size (42, 21); }
4356                 }
4357
4358                 public override Point TabControlDefaultPadding {
4359                         get { return new Point (6, 3); }
4360                 }
4361
4362                 public override int TabControlMinimumTabWidth {
4363                         get { return 42; }
4364                 }
4365
4366                 public override Rectangle GetTabControlDisplayRectangle (TabControl tab)
4367                 {
4368                         Rectangle ext = GetTabPanelRectExt (tab);
4369                         // Account for border size
4370                         return new Rectangle (ext.Left + 2, ext.Top + 1, ext.Width - 6, ext.Height - 4);
4371                 }
4372
4373                 public override Size TabControlGetSpacing (TabControl tab) {
4374                         switch (tab.Appearance) {
4375                                 case TabAppearance.Normal:
4376                                         return new Size (1, -2);
4377                                 case TabAppearance.Buttons:
4378                                         return new Size (3, 3);
4379                                 case TabAppearance.FlatButtons:
4380                                         return new Size (9, 3);
4381                                 default:
4382                                         throw new Exception ("Invalid Appearance value: " + tab.Appearance);
4383                                 }
4384                 }
4385
4386                 protected virtual Rectangle GetTabPanelRectExt (TabControl tab)
4387                 {
4388                         // Offset the tab from the top corner
4389                         Rectangle res = new Rectangle (tab.ClientRectangle.X + 2,
4390                                         tab.ClientRectangle.Y,
4391                                         tab.ClientRectangle.Width - 2,
4392                                         tab.ClientRectangle.Height - 1);
4393
4394                         if (tab.TabCount == 0)
4395                                 return res;
4396
4397                         int spacing = TabControlGetSpacing (tab).Height;
4398                         int offset = (tab.ItemSize.Height + spacing) * tab.RowCount + 3;
4399
4400                         switch (tab.Alignment) {
4401                         case TabAlignment.Left:
4402                                 res.X += offset;
4403                                 res.Width -= offset;
4404                                 break;
4405                         case TabAlignment.Right:
4406                                 res.Width -= offset;
4407                                 break;
4408                         case TabAlignment.Top:
4409                                 res.Y += offset;
4410                                 res.Height -= offset;
4411                                 break;
4412                         case TabAlignment.Bottom:
4413                                 res.Height -= offset;
4414                                 break;
4415                         }
4416
4417                         return res;
4418                 }
4419
4420                 protected virtual int DrawTab (Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected)
4421                 {
4422                         int FlatButtonSpacing = 8;
4423                         Rectangle interior;
4424                         int res = bounds.Width;
4425
4426                         
4427                         
4428                         // we can't fill the background right away because the bounds might be adjusted if the tab is selected
4429
4430                         StringFormat string_format = new StringFormat ();
4431                         if (tab.Appearance == TabAppearance.Buttons || tab.Appearance == TabAppearance.FlatButtons) {
4432                                 dc.FillRectangle (ResPool.GetSolidBrush (tab.BackColor), bounds);
4433
4434                                 // Separators
4435                                 if (tab.Appearance == TabAppearance.FlatButtons) {
4436                                         int width = bounds.Width;
4437                                         bounds.Width += (FlatButtonSpacing - 2);
4438                                         res = bounds.Width;
4439                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Etched, Border3DSide.Right);
4440                                         bounds.Width = width;
4441                                 }
4442
4443                                 if (is_selected) {
4444                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
4445                                 } else if (tab.Appearance != TabAppearance.FlatButtons) {
4446                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
4447                                 }
4448
4449                                 interior = new Rectangle (bounds.Left + 2, bounds.Top + 2, bounds.Width - 4, bounds.Height - 4);
4450
4451                                 
4452                                 string_format.Alignment = StringAlignment.Center;
4453                                 string_format.LineAlignment = StringAlignment.Center;
4454                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
4455                         } else {
4456                                 CPColor cpcolor = ResPool.GetCPColor (tab.BackColor);
4457                                 
4458                                 Pen light = ResPool.GetPen (cpcolor.LightLight);
4459
4460                                 switch (tab.Alignment) {
4461                                         
4462                                 case TabAlignment.Top:
4463
4464                                         dc.FillRectangle (ResPool.GetSolidBrush (tab.BackColor), bounds);
4465
4466                                         dc.DrawLine (light, bounds.Left, bounds.Bottom, bounds.Left, bounds.Top + 3);
4467                                         dc.DrawLine (light, bounds.Left, bounds.Top + 3, bounds.Left + 3, bounds.Top);
4468                                         dc.DrawLine (light, bounds.Left + 3, bounds.Top, bounds.Right - 3, bounds.Top);
4469
4470                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom);
4471                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 1, bounds.Top + 2, bounds.Right, bounds.Top + 3);
4472                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Top + 3, bounds.Right, bounds.Bottom);
4473
4474                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
4475
4476                                         string_format.Alignment = StringAlignment.Center;
4477                                         string_format.LineAlignment = StringAlignment.Center;
4478                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4479
4480                                         break;
4481
4482                                 case TabAlignment.Bottom:
4483
4484                                         dc.FillRectangle (ResPool.GetSolidBrush (tab.BackColor), bounds);
4485
4486                                         dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 3);
4487                                         dc.DrawLine (light, bounds.Left, bounds.Bottom - 3, bounds.Left + 2, bounds.Bottom - 1);
4488
4489                                         dc.DrawLine (SystemPens.ControlDark, bounds.Left + 3, bounds.Bottom - 1, bounds.Right - 3, bounds.Bottom - 1);
4490                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Bottom - 3, bounds.Right - 1, bounds.Top);
4491
4492                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 3, bounds.Bottom, bounds.Right - 3, bounds.Bottom);
4493                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 3, bounds.Bottom, bounds.Right, bounds.Bottom - 3);
4494                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Bottom - 3, bounds.Right, bounds.Top);
4495
4496                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
4497
4498                                         string_format.Alignment = StringAlignment.Center;
4499                                         string_format.LineAlignment = StringAlignment.Center;
4500                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4501
4502                                         break;
4503
4504                                 case TabAlignment.Left:
4505
4506                                         dc.FillRectangle (ResPool.GetSolidBrush (tab.BackColor), bounds);
4507
4508                                         dc.DrawLine (light, bounds.Left, bounds.Bottom - 3, bounds.Left, bounds.Top + 3);
4509                                         dc.DrawLine (light, bounds.Left, bounds.Top + 3, bounds.Left + 3, bounds.Top);
4510                                         dc.DrawLine (light, bounds.Left + 3, bounds.Top, bounds.Right, bounds.Top);
4511
4512                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right, bounds.Bottom - 1, bounds.Left + 2, bounds.Bottom - 1);
4513
4514                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Bottom, bounds.Left + 2, bounds.Bottom);
4515                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 2, bounds.Bottom, bounds.Left, bounds.Bottom - 3);
4516
4517                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
4518
4519                                         string_format.Alignment = StringAlignment.Center;
4520                                         string_format.LineAlignment = StringAlignment.Center;
4521                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4522                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
4523
4524                                         break;
4525
4526                                 default:
4527                                         // TabAlignment.Right
4528
4529                                         dc.FillRectangle (ResPool.GetSolidBrush (tab.BackColor), bounds);
4530
4531                                         dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Right - 3, bounds.Top);
4532                                         dc.DrawLine (light, bounds.Right - 3, bounds.Top, bounds.Right, bounds.Top + 3);
4533
4534                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom - 1);
4535                                         dc.DrawLine (SystemPens.ControlDark, bounds.Left, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom - 1);
4536
4537                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Top + 3, bounds.Right, bounds.Bottom - 3);
4538                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left, bounds.Bottom, bounds.Right - 3, bounds.Bottom);
4539
4540                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
4541
4542                                         string_format.Alignment = StringAlignment.Center;
4543                                         string_format.LineAlignment = StringAlignment.Center;
4544                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
4545                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
4546
4547                                         break;
4548                                 }
4549                         }
4550
4551                         if (tab.DrawMode == TabDrawMode.Normal && page.Text != null) {
4552                                 if (tab.Alignment == TabAlignment.Left) {
4553                                         int wo = interior.Width / 2;
4554                                         int ho = interior.Height / 2;
4555                                         dc.TranslateTransform (interior.X + wo, interior.Y + ho);
4556                                         dc.RotateTransform (180);
4557                                         dc.DrawString (page.Text, page.Font, SystemBrushes.ControlText, 0, 0, string_format);
4558                                         dc.ResetTransform ();
4559                                 } else {
4560                                         Rectangle str_rect = interior;
4561
4562                                         if (tab.ImageList != null && page.ImageIndex >= 0 && page.ImageIndex < tab.ImageList.Images.Count) {
4563                                                 tab.ImageList.Draw (dc, new Point (interior.X, interior.Y), page.ImageIndex);
4564                                                 str_rect.X += tab.ImageList.ImageSize.Width + 2;
4565                                                 str_rect.Width -= tab.ImageList.ImageSize.Width + 2;
4566                                         }
4567                                         dc.DrawString (page.Text, page.Font,
4568                                                        SystemBrushes.ControlText,
4569                                                         str_rect, string_format);
4570                                 }
4571                         } else if (page.Text != null) {
4572                                 DrawItemState state = DrawItemState.None;
4573                                 if (page == tab.SelectedTab)
4574                                         state |= DrawItemState.Selected;
4575                                 DrawItemEventArgs e = new DrawItemEventArgs (dc,
4576                                                 tab.Font, bounds, tab.IndexForTabPage (page),
4577                                                 state, page.ForeColor, page.BackColor);
4578                                 tab.OnDrawItemInternal (e);
4579                                 return res;
4580                         }
4581
4582                         if (page.Parent.Focused && is_selected) {
4583                                 CPDrawFocusRectangle (dc, interior, tab.ForeColor, tab.BackColor);
4584                         }
4585
4586                         return res;
4587                 }
4588
4589                 #region ToolBar
4590                 public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) 
4591                 {
4592                         StringFormat format = new StringFormat ();
4593                         format.Trimming = StringTrimming.EllipsisCharacter;
4594                         format.LineAlignment = StringAlignment.Center;
4595                         format.HotkeyPrefix = MenuAccessKeysUnderlined ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
4596                         if (control.TextAlign == ToolBarTextAlign.Underneath)
4597                                 format.Alignment = StringAlignment.Center;
4598                         else
4599                                 format.Alignment = StringAlignment.Near;
4600
4601                         if (control is PropertyGrid.PropertyToolBar) {
4602                                 dc.FillRectangle (ResPool.GetSolidBrush(control.BackColor), clip_rectangle);
4603                                 
4604                                 if (clip_rectangle.X == 0) {
4605                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.X, control.Bottom);
4606                                 }
4607
4608                                 if (clip_rectangle.Y < 2) {
4609                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
4610                                 }
4611
4612                                 if (clip_rectangle.Bottom == control.Bottom) {
4613                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, clip_rectangle.Bottom - 1, clip_rectangle.Right, clip_rectangle.Bottom - 1);
4614                                 }
4615
4616                                 if (clip_rectangle.Right == control.Right) {
4617                                         dc.DrawLine (SystemPens.ControlDark, clip_rectangle.Right - 1, 1, clip_rectangle.Right - 1, control.Bottom - 1);
4618                                 }
4619                         } else {
4620
4621                                 if (control.Appearance == ToolBarAppearance.Flat && control.Parent != null) {
4622                                         if (control.Parent.BackgroundImage != null) {
4623                                                 using (TextureBrush b = new TextureBrush (control.Parent.BackgroundImage, WrapMode.Tile))
4624                                                         dc.FillRectangle (b, clip_rectangle);
4625                                         } else {
4626                                                 dc.FillRectangle (ResPool.GetSolidBrush (control.Parent.BackColor), clip_rectangle);
4627                                         }
4628                                 } else {
4629                                         dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
4630                                 }
4631
4632                                 if (control.Divider && clip_rectangle.Y < 2) {
4633                                         if (clip_rectangle.Y < 1) {
4634                                                 dc.DrawLine (SystemPens.ControlDark, clip_rectangle.X, 0, clip_rectangle.Right, 0);
4635                                         }
4636                                         dc.DrawLine (SystemPens.ControlLightLight, clip_rectangle.X, 1, clip_rectangle.Right, 1);
4637                                 }
4638                         }
4639
4640                         foreach (ToolBarItem item in control.items)
4641                                 if (item.Button.Visible && clip_rectangle.IntersectsWith (item.Rectangle))
4642                                         DrawToolBarButton (dc, control, item, format);
4643
4644                         format.Dispose ();
4645                 }
4646
4647                 protected virtual void DrawToolBarButton (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
4648                 {
4649                         bool is_flat = (control.Appearance == ToolBarAppearance.Flat);
4650                         
4651                         DrawToolBarButtonBorder (dc, item, is_flat);
4652
4653                         switch (item.Button.Style) {
4654                         case ToolBarButtonStyle.DropDownButton:
4655                                 if (control.DropDownArrows)
4656                                         DrawToolBarDropDownArrow (dc, item, is_flat);
4657                                 DrawToolBarButtonContents (dc, control, item, format);
4658                                 break;
4659
4660                         case ToolBarButtonStyle.Separator:
4661                                 if (is_flat)
4662                                         DrawToolBarSeparator (dc, item);
4663                                 break;
4664
4665                         case ToolBarButtonStyle.ToggleButton:
4666                                 DrawToolBarToggleButtonBackground (dc, item);
4667                                 DrawToolBarButtonContents (dc, control, item, format);
4668                                 break;
4669
4670                         default:
4671                                 DrawToolBarButtonContents (dc, control, item, format);
4672                                 break;
4673                         }
4674                 }
4675
4676                 const Border3DSide all_sides = Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom;
4677
4678                 protected virtual void DrawToolBarButtonBorder (Graphics dc, ToolBarItem item, bool is_flat)
4679                 {
4680                         if (item.Button.Style == ToolBarButtonStyle.Separator)
4681                                 return;
4682
4683                         Border3DStyle style;
4684
4685                         if (is_flat) {
4686                                 if (item.Button.Pushed || item.Pressed)
4687                                         style = Border3DStyle.SunkenOuter;
4688                                 else if (item.Hilight)
4689                                         style = Border3DStyle.RaisedInner;
4690                                 else
4691                                         return;
4692
4693                         } else {
4694                                 if (item.Button.Pushed || item.Pressed)
4695                                         style = Border3DStyle.Sunken;
4696                                 else 
4697                                         style = Border3DStyle.Raised;
4698                         }
4699                         
4700                         Rectangle rect = item.Rectangle;
4701                         if ((item.Button.Style == ToolBarButtonStyle.DropDownButton) && (item.Button.Parent.DropDownArrows) && is_flat)
4702                                 rect.Width -= ToolBarDropDownWidth;
4703
4704                         CPDrawBorder3D (dc, rect, style, all_sides);
4705                 }
4706
4707                 protected virtual void DrawToolBarSeparator (Graphics dc, ToolBarItem item)
4708                 {
4709                         Rectangle area = item.Rectangle;
4710                         int offset = (int) SystemPens.Control.Width + 1;
4711                         dc.DrawLine (SystemPens.ControlDark, area.X + 1, area.Y, area.X + 1, area.Bottom);
4712                         dc.DrawLine (SystemPens.ControlLight, area.X + offset, area.Y, area.X + offset, area.Bottom);
4713                 }
4714
4715                 protected virtual void DrawToolBarToggleButtonBackground (Graphics dc, ToolBarItem item)
4716                 {
4717                         Brush brush;
4718                         Rectangle area = item.Rectangle;
4719                         area.X += ToolBarImageGripWidth;
4720                         area.Y += ToolBarImageGripWidth;
4721                         area.Width -= 2 * ToolBarImageGripWidth;
4722                         area.Height -= 2 * ToolBarImageGripWidth;
4723                         
4724                         if (item.Button.Pushed)
4725                                 brush = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorScrollBar, ColorControlLightLight);
4726                         else if (item.Button.PartialPush)
4727                                 brush = SystemBrushes.ControlLight;
4728                         else
4729                                 brush = SystemBrushes.Control;
4730                          
4731                         dc.FillRectangle (brush, area);
4732                 }
4733
4734                 protected virtual void DrawToolBarDropDownArrow (Graphics dc, ToolBarItem item, bool is_flat)
4735                 {
4736                         Rectangle rect = item.Rectangle;
4737                         rect.X = item.Rectangle.Right - ToolBarDropDownWidth;
4738                         rect.Width = ToolBarDropDownWidth;
4739                         
4740                         if (is_flat) {
4741                                 if (item.DDPressed)
4742                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
4743                                 else if (item.Button.Pushed || item.Pressed)
4744                                         CPDrawBorder3D (dc, rect, Border3DStyle.SunkenOuter, all_sides);
4745                                 else if (item.Hilight)
4746                                         CPDrawBorder3D (dc, rect, Border3DStyle.RaisedInner, all_sides);
4747                         } else {
4748                                 if (item.DDPressed)
4749                                         CPDrawBorder3D (dc, rect, Border3DStyle.Flat, all_sides);
4750                                 else if (item.Button.Pushed || item.Pressed)
4751                                         CPDrawBorder3D (dc, Rectangle.Inflate(rect, -1, -1), Border3DStyle.SunkenOuter, all_sides);
4752                                 else
4753                                         CPDrawBorder3D (dc, rect, Border3DStyle.Raised, all_sides);
4754                         }
4755                         
4756                         PointF [] vertices = new PointF [3];
4757                         PointF ddCenter = new PointF (rect.X + (rect.Width/2.0f), rect.Y + (rect.Height / 2));
4758                         
4759                         // Increase vertical and horizontal position by 1 when button is pressed
4760                         if (item.Pressed || item.Button.Pushed || item.DDPressed) {
4761                             ddCenter.X += 1;
4762                             ddCenter.Y += 1;
4763                         }
4764                         
4765                         vertices [0].X = ddCenter.X - ToolBarDropDownArrowWidth / 2.0f + 0.5f;
4766                         vertices [0].Y = ddCenter.Y;
4767                         vertices [1].X = ddCenter.X + ToolBarDropDownArrowWidth / 2.0f + 0.5f;
4768                         vertices [1].Y = ddCenter.Y;
4769                         vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
4770                         vertices [2].Y = ddCenter.Y + ToolBarDropDownArrowHeight;
4771                         dc.FillPolygon (SystemBrushes.ControlText, vertices);
4772                 }
4773
4774                 protected virtual void DrawToolBarButtonContents (Graphics dc, ToolBar control, ToolBarItem item, StringFormat format)
4775                 {
4776                         if (item.Button.Image != null) {
4777                                 int x = item.ImageRectangle.X + ToolBarImageGripWidth;
4778                                 int y = item.ImageRectangle.Y + ToolBarImageGripWidth;
4779                                 
4780                                 // Increase vertical and horizontal position by 1 when button is pressed
4781                                 if (item.Pressed || item.Button.Pushed) {
4782                                     x += 1;
4783                                     y += 1;
4784                                 }
4785                                 
4786                                 if (item.Button.Enabled)
4787                                         dc.DrawImage (item.Button.Image, x, y);
4788                                 else 
4789                                         CPDrawImageDisabled (dc, item.Button.Image, x, y, ColorControl);
4790                         }
4791
4792                         Rectangle text_rect = item.TextRectangle;
4793                         if (text_rect.Width <= 0 || text_rect.Height <= 0)
4794                                 return;
4795
4796                         if (item.Pressed || item.Button.Pushed) {
4797                                 text_rect.X += 1;
4798                                 text_rect.Y += 1;
4799                         }
4800                         
4801                         if (item.Button.Enabled)
4802                                 dc.DrawString (item.Button.Text, control.Font, SystemBrushes.ControlText, text_rect, format);
4803                         else
4804                                 CPDrawStringDisabled (dc, item.Button.Text, control.Font, control.BackColor, text_rect, format);
4805                 }
4806
4807                 // Grip width for the ToolBar
4808                 public override int ToolBarGripWidth {
4809                         get { return 2;}
4810                 }
4811
4812                 // Grip width for the Image on the ToolBarButton
4813                 public override int ToolBarImageGripWidth {
4814                         get { return 2;}
4815                 }
4816
4817                 // width of the separator
4818                 public override int ToolBarSeparatorWidth {
4819                         get { return 4; }
4820                 }
4821
4822                 // width of the dropdown arrow rect
4823                 public override int ToolBarDropDownWidth {
4824                         get { return 13; }
4825                 }
4826
4827                 // width for the dropdown arrow on the ToolBarButton
4828                 public override int ToolBarDropDownArrowWidth {
4829                         get { return 5;}
4830                 }
4831
4832                 // height for the dropdown arrow on the ToolBarButton
4833                 public override int ToolBarDropDownArrowHeight {
4834                         get { return 3;}
4835                 }
4836
4837                 public override Size ToolBarDefaultSize {
4838                         get {
4839                                 return new Size (100, 42);
4840                         }
4841                 }
4842
4843                 #endregion      // ToolBar
4844
4845                 #region ToolTip
4846                 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) {
4847                         dc.FillRectangle(SystemBrushes.Info, control.ClientRectangle);
4848                         dc.DrawRectangle(SystemPens.WindowFrame, 0, 0, control.Width-1, control.Height-1);
4849                         dc.DrawString(control.Text, control.Font, ResPool.GetSolidBrush(this.ColorInfoText), control.ClientRectangle, control.string_format);
4850                 }
4851
4852                 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text) {
4853                         SizeF   sizef;
4854
4855                         sizef = tt.DeviceContext.MeasureString(text, tt.Font, SizeF.Empty, tt.string_format);
4856                         return new Size((int)sizef.Width+8, (int)sizef.Height+3);       // Need space for the border
4857                 }
4858                 #endregion      // ToolTip
4859
4860                 #region BalloonWindow
4861 #if NET_2_0
4862                 NotifyIcon.BalloonWindow balloon_window;
4863                 
4864                 public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
4865                 {
4866                         Control control = Control.FromHandle(handle);
4867                         
4868                         if (control == null)
4869                                 return;
4870
4871                         if (balloon_window != null) {
4872                                 balloon_window.Close ();
4873                                 balloon_window.Dispose ();
4874                         }
4875
4876                         balloon_window = new NotifyIcon.BalloonWindow (handle);
4877                         balloon_window.Title = title;
4878                         balloon_window.Text = text;
4879                         balloon_window.Icon = icon;
4880                         balloon_window.Timeout = timeout;
4881                         balloon_window.Show ();
4882                 }
4883
4884                 private const int balloon_iconsize = 16;
4885                 private const int balloon_bordersize = 8; 
4886                 
4887                 public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) 
4888                 {
4889                         Brush solidbrush = ResPool.GetSolidBrush (this.ColorInfoText);
4890                         Rectangle rect = control.ClientRectangle;
4891                         int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
4892                         
4893                         // Rectangle borders and background.
4894                         dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
4895                         dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), 0, 0, rect.Width - 1, rect.Height - 1);
4896
4897                         // Icon
4898                         Image image;
4899                         switch (control.Icon) {
4900                                 case ToolTipIcon.Info: {
4901                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
4902                                         break;
4903                                 }
4904
4905                                 case ToolTipIcon.Warning: {
4906                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
4907                                         break;
4908                                 }
4909
4910                                 case ToolTipIcon.Error: {
4911                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
4912                                         break;
4913                                 }
4914                                 
4915                                 default: {
4916                                         image = null;
4917                                         break;
4918                                 }
4919                         }
4920
4921                         if (control.Icon != ToolTipIcon.None)
4922                                 dc.DrawImage (image, new Rectangle (balloon_bordersize, balloon_bordersize, iconsize, iconsize));
4923                         
4924                         // Title
4925                         Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + iconsize + (iconsize > 0 ? balloon_bordersize : 0), 
4926                                                                                                 rect.Y + balloon_bordersize, 
4927                                                                                                 rect.Width - ((3 * balloon_bordersize) + iconsize), 
4928                                                                                                 rect.Height - (2 * balloon_bordersize));
4929                         
4930                         Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
4931                         dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
4932                         
4933                         // Text
4934                         Rectangle textrect = new Rectangle (rect.X + balloon_bordersize, 
4935                                                                                                 rect.Y + balloon_bordersize, 
4936                                                                                                 rect.Width - (2 * balloon_bordersize), 
4937                                                                                                 rect.Height - (2 * balloon_bordersize));
4938
4939                         StringFormat textformat = control.Format;
4940                         textformat.LineAlignment = StringAlignment.Far;
4941                         dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
4942                 }
4943
4944                 public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
4945                 {
4946                         Rectangle deskrect = Screen.GetWorkingArea (control);
4947                         SizeF maxsize = new SizeF (250, 200);
4948
4949                         SizeF titlesize = control.DeviceContext.MeasureString (control.Title, control.Font, maxsize, control.Format);
4950                         SizeF textsize = control.DeviceContext.MeasureString (control.Text, control.Font, maxsize, control.Format);
4951                         
4952                         if (titlesize.Height < balloon_iconsize)
4953                                 titlesize.Height = balloon_iconsize;
4954                         
4955                         Rectangle rect = new Rectangle ();
4956                         rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
4957                         rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (2 * balloon_bordersize);
4958                         rect.X = deskrect.Width - rect.Width - 2;
4959                         rect.Y = deskrect.Height - rect.Height - 2;
4960                         
4961                         return rect;
4962                 }
4963 #endif
4964                 #endregion      // BalloonWindow
4965
4966                 #region TrackBar
4967                 public override int TrackBarValueFromMousePosition (int x, int y, TrackBar tb)
4968                 {
4969                         int result = tb.Value;
4970                         int value_pos = tb.Value;
4971                         float pixels_betweenticks;
4972                         Rectangle thumb_pos = Rectangle.Empty, thumb_area = Rectangle.Empty;
4973                         Point channel_startpoint = Point.Empty, na_point = Point.Empty;
4974                         
4975                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out na_point, out na_point);
4976                         
4977                         /* Convert thumb position from mouse position to value*/
4978                         if (tb.Orientation == Orientation.Vertical) {
4979                                 value_pos = (int)((thumb_area.Bottom - y -(float)pixels_betweenticks / 2) / (float)pixels_betweenticks);
4980
4981                                 if (value_pos + tb.Minimum > tb.Maximum)
4982                                         value_pos = tb.Maximum - tb.Minimum;
4983                                 else if (value_pos + tb.Minimum < tb.Minimum)
4984                                         value_pos = 0;
4985
4986                                 result = value_pos + tb.Minimum;
4987                         } else {
4988                                 value_pos = (int) ((x - channel_startpoint.X - (float) pixels_betweenticks / 2) / (float) pixels_betweenticks);
4989
4990                                 if (value_pos + tb.Minimum > tb.Maximum)
4991                                         value_pos = tb.Maximum - tb.Minimum;
4992                                 else if (value_pos + tb.Minimum < tb.Minimum)
4993                                         value_pos = 0;
4994
4995                                 result = value_pos + tb.Minimum;
4996                         }
4997                         
4998                         return result;
4999                 }
5000                 
5001                 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)
5002                 {
5003                         thumb_area = Rectangle.Empty;
5004                         thumb_pos = Rectangle.Empty;
5005                         
5006                         if (tb.Orientation == Orientation.Vertical) {
5007                                 toptick_startpoint = new Point ();
5008                                 bottomtick_startpoint = new Point ();
5009                                 channel_startpoint = new Point ();
5010                                 float pixel_len;
5011                                 const int space_from_right = 8;
5012                                 const int space_from_left = 8;
5013                                 const int space_from_bottom = 11;
5014                                 Rectangle area = tb.ClientRectangle;
5015
5016                                 switch (tb.TickStyle) {
5017                                 case TickStyle.BottomRight:
5018                                 case TickStyle.None:
5019                                         channel_startpoint.Y = 8;
5020                                         channel_startpoint.X = 9;
5021                                         bottomtick_startpoint.Y = 13;
5022                                         bottomtick_startpoint.X = 24;
5023                                         break;
5024                                 case TickStyle.TopLeft:
5025                                         channel_startpoint.Y = 8;
5026                                         channel_startpoint.X = 19;
5027                                         toptick_startpoint.Y = 13;
5028                                         toptick_startpoint.X = 8;
5029                                         break;
5030                                 case TickStyle.Both:
5031                                         channel_startpoint.Y = 8;
5032                                         channel_startpoint.X = 18;
5033                                         bottomtick_startpoint.Y = 13;
5034                                         bottomtick_startpoint.X = 32;
5035                                         toptick_startpoint.Y = 13;
5036                                         toptick_startpoint.X = 8;
5037                                         break;
5038                                 default:
5039                                         break;
5040                                 }
5041
5042                                 thumb_area.X = area.X + channel_startpoint.X;
5043                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5044                                 thumb_area.Height = area.Height - space_from_right - space_from_left;
5045                                 thumb_area.Width = 4;
5046
5047                                 pixel_len = thumb_area.Height - 11;
5048                                 if (tb.Maximum == tb.Minimum) {
5049                                         pixels_betweenticks = 0;
5050                                 } else {
5051                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5052                                 }
5053
5054                                 thumb_pos.Y = thumb_area.Bottom - space_from_bottom - (int)(pixels_betweenticks * (float)(tb.Value - tb.Minimum));
5055
5056                                 /* Draw thumb fixed 10x22 size */
5057                                 thumb_pos.Width = 10;
5058                                 thumb_pos.Height = 22;
5059                         } else {        
5060                                 toptick_startpoint = new Point ();
5061                                 bottomtick_startpoint = new Point ();
5062                                 channel_startpoint = new Point ();
5063                                 float pixel_len;
5064                                 const int space_from_right = 8;
5065                                 const int space_from_left = 8;
5066                                 Rectangle area = tb.ClientRectangle;
5067                                                         
5068                                 switch (tb.TickStyle) {
5069                                 case TickStyle.BottomRight:
5070                                 case TickStyle.None:
5071                                         channel_startpoint.X = 8;
5072                                         channel_startpoint.Y = 9;
5073                                         bottomtick_startpoint.X = 13;
5074                                         bottomtick_startpoint.Y = 24;                           
5075                                         break;
5076                                 case TickStyle.TopLeft:
5077                                         channel_startpoint.X = 8;
5078                                         channel_startpoint.Y = 19;
5079                                         toptick_startpoint.X = 13;
5080                                         toptick_startpoint.Y = 8;
5081                                         break;
5082                                 case TickStyle.Both:
5083                                         channel_startpoint.X = 8;
5084                                         channel_startpoint.Y = 18;      
5085                                         bottomtick_startpoint.X = 13;
5086                                         bottomtick_startpoint.Y = 32;                           
5087                                         toptick_startpoint.X = 13;
5088                                         toptick_startpoint.Y = 8;                               
5089                                         break;
5090                                 default:
5091                                         break;
5092                                 }
5093                                                         
5094                                 thumb_area.X = area.X + channel_startpoint.X;
5095                                 thumb_area.Y = area.Y + channel_startpoint.Y;
5096                                 thumb_area.Width = area.Width - space_from_right - space_from_left;
5097                                 thumb_area.Height = 4;
5098
5099                                 pixel_len = thumb_area.Width - 11;
5100                                 if (tb.Maximum == tb.Minimum) {
5101                                         pixels_betweenticks = 0;
5102                                 } else {
5103                                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
5104                                 }
5105
5106                                 thumb_pos.X = channel_startpoint.X + (int)(pixels_betweenticks * (float) (tb.Value - tb.Minimum));
5107
5108                                 /* Draw thumb fixed 10x22 size */
5109                                 thumb_pos.Width = 10;
5110                                 thumb_pos.Height = 22;
5111                         }
5112                 }
5113                 
5114                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5115                         ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
5116                         float ticks, int value_pos, bool mouse_value) {                 
5117
5118                         Point toptick_startpoint = new Point ();
5119                         Point bottomtick_startpoint = new Point ();
5120                         Point channel_startpoint = new Point ();
5121                         float pixel_len;
5122                         float pixels_betweenticks;
5123                         Rectangle area = tb.ClientRectangle;
5124                         
5125                         GetTrackBarDrawingInfo (tb, out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5126
5127                         /* Draw channel */
5128                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5129                                 1, thumb_area.Height);
5130                         
5131                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X + 1, channel_startpoint.Y,
5132                                 1, thumb_area.Height);
5133
5134                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X + 3, channel_startpoint.Y,
5135                                 1, thumb_area.Height);
5136
5137                         switch (tb.TickStyle)   {
5138                         case TickStyle.BottomRight:
5139                         case TickStyle.None: {
5140                                 thumb_pos.X = channel_startpoint.X - 8;
5141
5142                                 Pen pen = SystemPens.ControlLightLight;
5143                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X , thumb_pos.Y + 10);
5144                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
5145                                 dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
5146                                 
5147                                 pen = SystemPens.ControlDark;
5148                                 dc.DrawLine (pen, thumb_pos.X +1, thumb_pos.Y + 9, thumb_pos.X +15, thumb_pos.Y  +9);
5149                                 dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X +16 + 4, thumb_pos.Y  +9 - 4);
5150
5151                                 pen = SystemPens.ControlDarkDark;
5152                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y  + 10, thumb_pos.X +16, thumb_pos.Y +10);
5153                                 dc.DrawLine (pen, thumb_pos.X + 16, thumb_pos.Y  + 10, thumb_pos.X  +16 + 5, thumb_pos.Y +10 - 5);
5154
5155                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
5156                                 dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
5157                                 dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
5158                                 dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
5159
5160                                 break;
5161                         }
5162                         case TickStyle.TopLeft: {
5163                                 thumb_pos.X = channel_startpoint.X - 10;
5164
5165                                 Pen pen = SystemPens.ControlLightLight;
5166                                 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
5167                                 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
5168
5169                                 pen = SystemPens.ControlDark;
5170                                 dc.DrawLine (pen, thumb_pos.X  + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16 , thumb_pos.Y+ 9);
5171                                 dc.DrawLine (pen, thumb_pos.X + 4, thumb_pos.Y  + 9, thumb_pos.X, thumb_pos.Y + 5);
5172                                 dc.DrawLine (pen, thumb_pos.X  + 19, thumb_pos.Y + 9, thumb_pos.X  +19 , thumb_pos.Y+ 1);
5173
5174                                 pen = SystemPens.ControlDarkDark;
5175                                 dc.DrawLine (pen, thumb_pos.X  + 4, thumb_pos.Y+ 10, thumb_pos.X  + 4 + 16, thumb_pos.Y+ 10);
5176                                 dc.DrawLine (pen, thumb_pos.X  + 4, thumb_pos.Y + 10, thumb_pos.X  -1, thumb_pos.Y+ 5);
5177                                 dc.DrawLine (pen, thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X+ 20, thumb_pos.Y + 10);
5178
5179                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
5180                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
5181                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
5182                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
5183
5184                                 break;
5185                         }
5186
5187                         case TickStyle.Both: {
5188                                 thumb_pos.X = area.X + 10;
5189
5190                                 Pen pen = SystemPens.ControlLightLight;
5191                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
5192                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
5193
5194                                 pen = SystemPens.ControlDark;
5195                                 dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X+ 19, thumb_pos.Y  + 9);
5196                                 dc.DrawLine (pen, thumb_pos.X  + 10, thumb_pos.Y+ 1, thumb_pos.X + 19, thumb_pos.Y  + 8);
5197
5198                                 pen = SystemPens.ControlDarkDark;
5199                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X+ 20, thumb_pos.Y  +10);
5200                                 dc.DrawLine (pen, thumb_pos.X  + 20, thumb_pos.Y, thumb_pos.X  + 20, thumb_pos.Y+ 9);
5201
5202                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
5203
5204                                 break;
5205                         }
5206
5207                         default:
5208                                 break;
5209                         }
5210
5211                         pixel_len = thumb_area.Height - 11;
5212                         pixels_betweenticks = pixel_len / ticks;
5213                         
5214                         thumb_area.X = thumb_pos.X;
5215                         thumb_area.Y = channel_startpoint.Y;
5216                         thumb_area.Width = thumb_pos.Height;
5217                         
5218                         /* Draw ticks*/
5219                         Region outside = new Region (area);
5220                         outside.Exclude (thumb_area);                   
5221                         
5222                         if (outside.IsVisible (clip_rectangle)) {                               
5223                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
5224                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) { 
5225                                         
5226                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks)  {                                       
5227                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
5228                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X , area.Y + bottomtick_startpoint.Y  + inc, 
5229                                                                 area.X + bottomtick_startpoint.X  + 3, area.Y + bottomtick_startpoint.Y + inc);
5230                                                 else
5231                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X, area.Y + bottomtick_startpoint.Y  + inc, 
5232                                                                 area.X + bottomtick_startpoint.X  + 2, area.Y + bottomtick_startpoint.Y + inc);
5233                                         }
5234                                 }
5235         
5236                                 if (pixels_betweenticks > 0 &&  ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
5237                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
5238         
5239                                         pixel_len = thumb_area.Height - 11;
5240                                         pixels_betweenticks = pixel_len / ticks;
5241                                         
5242                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
5243                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
5244                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 3 , area.Y + toptick_startpoint.Y + inc, 
5245                                                                 area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc);
5246                                                 else
5247                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 2, area.Y + toptick_startpoint.Y + inc, 
5248                                                                 area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y  + inc);
5249                                         }                       
5250                                 }
5251                         }
5252                         
5253                         outside.Dispose ();
5254                         
5255                 }
5256
5257                 /* 
5258                         Horizontal trackbar 
5259                   
5260                         Does not matter the size of the control, Win32 always draws:
5261                                 - Ticks starting from pixel 13, 8
5262                                 - Channel starting at pos 8, 19 and ends at Width - 8
5263                                 - Autosize makes always the control 45 pixels high
5264                                 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
5265                                 
5266                 */
5267                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
5268                         ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
5269                         float ticks, int value_pos, bool mouse_value) {                 
5270                         Point toptick_startpoint = new Point ();
5271                         Point bottomtick_startpoint = new Point ();
5272                         Point channel_startpoint = new Point ();
5273                         float pixel_len;
5274                         float pixels_betweenticks;
5275                         Rectangle area = tb.ClientRectangle;
5276                         
5277                         GetTrackBarDrawingInfo (tb , out pixels_betweenticks, out thumb_area, out thumb_pos, out channel_startpoint, out bottomtick_startpoint, out toptick_startpoint);
5278                         
5279                         /* Draw channel */
5280                         dc.FillRectangle (SystemBrushes.ControlDark, channel_startpoint.X, channel_startpoint.Y,
5281                                 thumb_area.Width, 1);
5282                         
5283                         dc.FillRectangle (SystemBrushes.ControlDarkDark, channel_startpoint.X, channel_startpoint.Y + 1,
5284                                 thumb_area.Width, 1);
5285
5286                         dc.FillRectangle (SystemBrushes.ControlLight, channel_startpoint.X, channel_startpoint.Y +3,
5287                                 thumb_area.Width, 1);
5288
5289                         switch (tb.TickStyle) {
5290                         case TickStyle.BottomRight:
5291                         case TickStyle.None: {
5292                                 thumb_pos.Y = channel_startpoint.Y - 8;
5293
5294                                 Pen pen = SystemPens.ControlLightLight;
5295                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
5296                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
5297                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
5298
5299                                 pen = SystemPens.ControlDark;
5300                                 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X +9, thumb_pos.Y +15);
5301                                 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X +9 - 4, thumb_pos.Y +16 + 4);
5302
5303                                 pen = SystemPens.ControlDarkDark;
5304                                 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X +10, thumb_pos.Y +16);
5305                                 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X +10 - 5, thumb_pos.Y +16 + 5);
5306
5307                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
5308                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
5309                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
5310                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
5311                                 break;
5312                         }
5313                         case TickStyle.TopLeft: {
5314                                 thumb_pos.Y = channel_startpoint.Y - 10;
5315
5316                                 Pen pen = SystemPens.ControlLightLight;
5317                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
5318                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
5319
5320                                 pen = SystemPens.ControlDark;
5321                                 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
5322                                 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
5323                                 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1 , thumb_pos.Y +19);
5324
5325                                 pen = SystemPens.ControlDarkDark;
5326                                 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
5327                                 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y -1);
5328                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
5329
5330                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
5331                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
5332                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
5333                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
5334                                 break;
5335                         }
5336
5337                         case TickStyle.Both: {
5338                                 thumb_pos.Y = area.Y + 10;
5339                                         
5340                                 Pen pen = SystemPens.ControlLightLight;
5341                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
5342                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
5343
5344                                 pen = SystemPens.ControlDark;
5345                                 dc.DrawLine (pen, thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
5346                                 dc.DrawLine (pen, thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
5347
5348                                 pen = SystemPens.ControlDarkDark;
5349                                 dc.DrawLine (pen, thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X +10, thumb_pos.Y + 20);
5350                                 dc.DrawLine (pen, thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
5351
5352                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
5353
5354                                 break;
5355                         }
5356
5357                         default:
5358                                 break;
5359                         }
5360
5361                         pixel_len = thumb_area.Width - 11;
5362                         pixels_betweenticks = pixel_len / ticks;
5363
5364                         /* Draw ticks*/
5365                         thumb_area.Y = thumb_pos.Y;
5366                         thumb_area.X = channel_startpoint.X;
5367                         thumb_area.Height = thumb_pos.Height;
5368                         Region outside = new Region (area);
5369                         outside.Exclude (thumb_area);                   
5370                         
5371                         if (outside.IsVisible (clip_rectangle)) {                               
5372                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
5373                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {                         
5374                                         
5375                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
5376                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
5377                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y, 
5378                                                                 area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y + 3);
5379                                                 else
5380                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y, 
5381                                                                 area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y + 2);
5382                                         }
5383                                 }
5384         
5385                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
5386                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
5387                                         
5388                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
5389                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
5390                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y - 3, 
5391                                                                 area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y);
5392                                                 else
5393                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y - 2, 
5394                                                                 area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y );
5395                                         }                       
5396                                 }
5397                         }
5398                         
5399                         outside.Dispose ();                     
5400                 }
5401
5402                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) 
5403                 {
5404                         Brush           br_thumb;
5405                         int             value_pos;
5406                         bool            mouse_value;
5407                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
5408                         Rectangle       area;
5409                         Rectangle       thumb_pos = tb.ThumbPos;
5410                         Rectangle       thumb_area = tb.ThumbArea;
5411                         
5412                         if (tb.thumb_pressed) {
5413                                 value_pos = tb.thumb_mouseclick;
5414                                 mouse_value = true;
5415                         } else {
5416                                 value_pos = tb.Value - tb.Minimum;
5417                                 mouse_value = false;
5418                         }
5419
5420                         area = tb.ClientRectangle;
5421
5422                         if (!tb.Enabled) {
5423                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight);
5424                         } else if (tb.thumb_pressed == true) {
5425                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl);
5426                         } else {
5427                                 br_thumb = SystemBrushes.Control;
5428                         }
5429
5430                         
5431                         /* Control Background */
5432                         if (tb.BackColor.ToArgb () == DefaultControlBackColor.ToArgb ()) {
5433                                 dc.FillRectangle (SystemBrushes.Control, clip_rectangle);
5434                         } else {
5435                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
5436                         }
5437                         
5438                         if (tb.Focused) {
5439                                 CPDrawFocusRectangle(dc, area, tb.ForeColor, tb.BackColor);
5440                         }
5441
5442                         if (tb.Orientation == Orientation.Vertical) {
5443                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
5444                                         br_thumb, ticks, value_pos, mouse_value);
5445                         
5446                         } else {
5447                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
5448                                         br_thumb, ticks, value_pos, mouse_value);
5449                         }
5450
5451                         tb.ThumbPos = thumb_pos;
5452                         tb.ThumbArea = thumb_area;
5453                 }
5454
5455                 public override Size TrackBarDefaultSize {
5456                         get {
5457                                 return new Size (104, 42);
5458                         }
5459                 }
5460
5461                 #endregion      // TrackBar
5462
5463                 #region VScrollBar
5464                 public override Size VScrollBarDefaultSize {
5465                         get {
5466                                 return new Size (this.ScrollBarButtonSize, 80);
5467                         }
5468                 }
5469                 #endregion      // VScrollBar
5470
5471                 #region TreeView
5472                 public override Size TreeViewDefaultSize {
5473                         get {
5474                                 return new Size (121, 97);
5475                         }
5476                 }
5477
5478                 #endregion
5479
5480                 public override int ManagedWindowTitleBarHeight (InternalWindowManager wm)
5481                 {
5482                         if (wm.IsToolWindow && !wm.IsMinimized)
5483                                 return SystemInformation.ToolWindowCaptionHeight;
5484                         if (wm.Form.FormBorderStyle == FormBorderStyle.None)
5485                                 return 0;
5486                         return SystemInformation.CaptionHeight;
5487                 }
5488
5489                 public override int ManagedWindowBorderWidth (InternalWindowManager wm)
5490                 {
5491                         return 4;
5492                 }
5493
5494                 public override int ManagedWindowIconWidth (InternalWindowManager wm)
5495                 {
5496                         return ManagedWindowTitleBarHeight (wm) - 5;
5497                 }
5498
5499                 public override void ManagedWindowSetButtonLocations (InternalWindowManager wm)
5500                 {
5501                         TitleButtons buttons = wm.TitleButtons;
5502                         Form form = wm.form;
5503                         
5504                         buttons.HelpButton.Visible = form.HelpButton;
5505                         
5506                         foreach (TitleButton button in buttons) {
5507                                 button.Visible = false;
5508                         }
5509                         
5510                         switch (form.FormBorderStyle) {
5511                         case FormBorderStyle.None:
5512                                 if (form.WindowState != FormWindowState.Normal)
5513                                         goto case FormBorderStyle.Sizable;
5514                                 break;
5515                         case FormBorderStyle.FixedToolWindow:
5516                         case FormBorderStyle.SizableToolWindow:
5517                                 buttons.CloseButton.Visible = true;
5518                                 if (form.WindowState != FormWindowState.Normal)
5519                                         goto case FormBorderStyle.Sizable;
5520                                 break;
5521                         case FormBorderStyle.FixedSingle:
5522                         case FormBorderStyle.Fixed3D:
5523                         case FormBorderStyle.FixedDialog:
5524                         case FormBorderStyle.Sizable:
5525                                 switch (form.WindowState) {
5526                                         case FormWindowState.Normal:
5527                                                 buttons.MinimizeButton.Visible = true;
5528                                                 buttons.MaximizeButton.Visible = true;
5529                                                 buttons.RestoreButton.Visible = false;
5530                                                 break;
5531                                         case FormWindowState.Maximized:
5532                                                 buttons.MinimizeButton.Visible = true;
5533                                                 buttons.MaximizeButton.Visible = false;
5534                                                 buttons.RestoreButton.Visible = true;
5535                                                 break;
5536                                         case FormWindowState.Minimized:
5537                                                 buttons.MinimizeButton.Visible = false;
5538                                                 buttons.MaximizeButton.Visible = true;
5539                                                 buttons.RestoreButton.Visible = true;
5540                                                 break;
5541                                 }
5542                                 buttons.CloseButton.Visible = true;
5543                                 break;
5544                         }
5545
5546                         int bw = ManagedWindowBorderWidth (wm);
5547                         Size btsize = ManagedWindowButtonSize (wm);
5548                         int btw = btsize.Width;
5549                         int bth = btsize.Height;
5550                         int top = bw + 2;
5551                         int left = form.Width - bw - btw - 2;
5552                         
5553                         if ((!wm.IsToolWindow || wm.IsMinimized) && wm.HasBorders) {
5554                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
5555                                 left -= 2 + btw;
5556                                 
5557                                 if (buttons.MaximizeButton.Visible) {
5558                                         buttons.MaximizeButton.Rectangle = new Rectangle (left, top, btw, bth);
5559                                         left -= 2 + btw;
5560                                 } 
5561                                 if (buttons.RestoreButton.Visible) {
5562                                         buttons.RestoreButton.Rectangle = new Rectangle (left, top, btw, bth);
5563                                         left -= 2 + btw;
5564                                 }
5565
5566                                 buttons.MinimizeButton.Rectangle = new Rectangle (left, top, btw, bth);
5567                                 left -= 2 + btw;
5568                         } else if (wm.IsToolWindow) {
5569                                 buttons.CloseButton.Rectangle = new Rectangle (left, top, btw, bth);
5570                                 left -= 2 + btw;
5571                         }
5572                 }
5573
5574                 public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
5575                 {
5576                         Form form = wm.Form;
5577                         int tbheight = ManagedWindowTitleBarHeight (wm);
5578                         int bdwidth = ManagedWindowBorderWidth (wm);
5579                         Color titlebar_color = Color.FromArgb (255, 10, 36, 106);
5580                         Color titlebar_color2 = Color.FromArgb (255, 166, 202, 240);
5581                         Color color = ThemeEngine.Current.ColorControlDark;
5582                         Color color2 = Color.FromArgb (255, 192, 192, 192);
5583
5584 #if debug
5585                         Console.WriteLine (DateTime.Now.ToLongTimeString () + " DrawManagedWindowDecorations");
5586                         dc.FillRectangle (Brushes.Black, clip);
5587 #endif
5588                         
5589                         if (wm.HasBorders) {
5590                                 Pen pen = ResPool.GetPen (ColorControl);
5591                                 Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
5592                                 ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
5593                                 // The 3d border is only 2 pixels wide, so we draw the innermost pixels ourselves
5594                                 borders = new Rectangle (2, 2, form.Width - 5, form.Height - 5);
5595                                 for (int i = 2; i < bdwidth; i++) {
5596                                         dc.DrawRectangle (pen, borders);
5597                                         borders.Inflate (-1, -1);
5598                                 }                               
5599                         }
5600
5601
5602                         bool draw_titlebar_enabled = false;
5603                         if (wm.Form.Parent != null && wm.Form.Parent is Form) {
5604                                 draw_titlebar_enabled = false;
5605                         } else if (wm.IsActive && !wm.IsMaximized) {
5606                                 draw_titlebar_enabled = true;
5607                         }
5608                         if (draw_titlebar_enabled) {
5609                                 color = titlebar_color;
5610                                 color2 = titlebar_color2;
5611                         }
5612
5613                         Rectangle tb = new Rectangle (bdwidth, bdwidth, form.Width - (bdwidth * 2), tbheight - 1);
5614
5615                         // HACK: For now always draw the titlebar until we get updates better
5616                         if (tb.Width > 0 && tb.Height > 0) {
5617                                 using (System.Drawing.Drawing2D.LinearGradientBrush gradient = new LinearGradientBrush (tb, color, color2, LinearGradientMode.Horizontal))
5618                                 {
5619                                         dc.FillRectangle (gradient, tb);
5620                                 }       
5621                         }
5622                         
5623                         // Draw the line just beneath the title bar
5624                         dc.DrawLine (ResPool.GetPen (SystemColors.Control), bdwidth,
5625                                         tbheight + bdwidth - 1, form.Width - bdwidth - 1,
5626                                         tbheight + bdwidth - 1);
5627
5628                         if (!wm.IsToolWindow) {
5629                                 tb.X += 18; // Room for the icon and the buttons
5630                                 tb.Width = (form.Width - 62) - tb.X;
5631                         }
5632
5633                         if (form.Text != null && form.Text != string.Empty) {
5634                                 StringFormat format = new StringFormat ();
5635                                 format.FormatFlags = StringFormatFlags.NoWrap;
5636                                 format.Trimming = StringTrimming.EllipsisCharacter;
5637                                 format.LineAlignment = StringAlignment.Center;
5638
5639                                 if (tb.IntersectsWith (clip))
5640                                         dc.DrawString (form.Text, WindowBorderFont,
5641                                                 ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
5642                                                 tb, format);
5643                         }
5644
5645                         if (wm.HasBorders) {
5646                                 bool draw_icon = false;
5647 #if NET_2_0
5648                                 draw_icon = !wm.IsToolWindow && form.Icon != null && form.ShowIcon;
5649 #else
5650                                 draw_icon = !wm.IsToolWindow && form.Icon != null;
5651 #endif
5652                                 if (draw_icon) {
5653                                         Rectangle icon = new Rectangle (bdwidth + 3,
5654                                                         bdwidth + 2, wm.IconWidth, wm.IconWidth);
5655                                         if (icon.IntersectsWith (clip))
5656                                                 dc.DrawIcon (form.Icon, icon);
5657                                 }
5658                                 
5659                                 foreach (TitleButton button in wm.TitleButtons.AllButtons) {
5660                                         DrawTitleButton (dc, button, clip);
5661                                 }
5662                         }
5663                 }
5664
5665                 public override Size ManagedWindowButtonSize (InternalWindowManager wm)
5666                 {
5667                         int height = ManagedWindowTitleBarHeight (wm);
5668                         if (!wm.IsMaximized && !wm.IsMinimized) {
5669                                 if (wm.IsToolWindow)
5670                                         return new Size (SystemInformation.ToolWindowCaptionButtonSize.Width - 2,
5671                                                         height - 5);
5672                                 if (wm.Form.FormBorderStyle == FormBorderStyle.None)
5673                                         return Size.Empty;
5674                         } else
5675                                 height = SystemInformation.CaptionHeight;
5676
5677                         return new Size (SystemInformation.CaptionButtonSize.Width - 2,
5678                                         height - 5);
5679                 }
5680
5681                 private void DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip)
5682                 {
5683                         if (!button.Visible) {
5684                                 return;
5685                         }
5686                         
5687                         if (!button.Rectangle.IntersectsWith (clip))
5688                                 return;
5689
5690                         dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
5691
5692                         ControlPaint.DrawCaptionButton (dc, button.Rectangle,
5693                                         button.Caption, button.State);
5694                 }
5695
5696                 #region ControlPaint
5697                 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
5698                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
5699                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
5700                         int bottomWidth, ButtonBorderStyle bottomStyle) {
5701                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
5702                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
5703                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
5704                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
5705                 }
5706
5707                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
5708                         CPDrawBorder3D(graphics, rectangle, style, sides, ColorControl);
5709                 }
5710
5711                 protected virtual void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color)
5712                 {
5713                         Pen             penTopLeft;
5714                         Pen             penTopLeftInner;
5715                         Pen             penBottomRight;
5716                         Pen             penBottomRightInner;
5717                         Rectangle       rect= new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
5718                         bool is_ColorControl = control_color.ToArgb () == ColorControl.ToArgb () ? true : false;
5719                         
5720                         if ((style & Border3DStyle.Adjust) != 0) {
5721                                 rect.Y -= 2;
5722                                 rect.X -= 2;
5723                                 rect.Width += 4;
5724                                 rect.Height += 4;
5725                         }
5726                         
5727                         penTopLeft = penTopLeftInner = penBottomRight = penBottomRightInner = is_ColorControl ? SystemPens.Control : ResPool.GetPen (control_color);
5728                         
5729                         CPColor cpcolor = CPColor.Empty;
5730                         
5731                         if (!is_ColorControl)
5732                                 cpcolor = ResPool.GetCPColor (control_color);
5733                         
5734                         switch (style) {
5735                         case Border3DStyle.Raised:
5736                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
5737                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
5738                                 penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
5739                                 break;
5740                         case Border3DStyle.Sunken:
5741                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
5742                                 penTopLeftInner = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
5743                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
5744                                 break;
5745                         case Border3DStyle.Etched:
5746                                 penTopLeft = penBottomRightInner = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
5747                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
5748                                 break;
5749                         case Border3DStyle.RaisedOuter:
5750                                 penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
5751                                 break;
5752                         case Border3DStyle.SunkenOuter:
5753                                 penTopLeft = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
5754                                 penBottomRight = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
5755                                 break;
5756                         case Border3DStyle.RaisedInner:
5757                                 penTopLeft = is_ColorControl ? SystemPens.ControlLightLight : ResPool.GetPen (cpcolor.LightLight);
5758                                 penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
5759                                 break;
5760                         case Border3DStyle.SunkenInner:
5761                                 penTopLeft = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
5762                                 break;
5763                         case Border3DStyle.Flat:
5764                                 penTopLeft = penBottomRight = is_ColorControl ? SystemPens.ControlDark : ResPool.GetPen (cpcolor.Dark);
5765                                 break;
5766                         case Border3DStyle.Bump:
5767                                 penTopLeftInner = penBottomRight = is_ColorControl ? SystemPens.ControlDarkDark : ResPool.GetPen (cpcolor.DarkDark);
5768                                 break;
5769                         default:
5770                                 break;
5771                         }
5772                         
5773                         bool inner = ((style != Border3DStyle.RaisedOuter) && (style != Border3DStyle.SunkenOuter));
5774                         
5775                         if ((sides & Border3DSide.Middle) != 0) {
5776                                 Brush brush = is_ColorControl ? SystemBrushes.Control : ResPool.GetSolidBrush (control_color);
5777                                 graphics.FillRectangle (brush, rect);
5778                         }
5779                         
5780                         if ((sides & Border3DSide.Left) != 0) {
5781                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Bottom - 2, rect.Left, rect.Top);
5782                                 if ((rect.Width > 2) && inner)
5783                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Bottom - 2, rect.Left + 1, rect.Top);
5784                         }
5785                         
5786                         if ((sides & Border3DSide.Top) != 0) {
5787                                 graphics.DrawLine (penTopLeft, rect.Left, rect.Top, rect.Right - 2, rect.Top);
5788                                 if ((rect.Height > 2) && inner)
5789                                         graphics.DrawLine (penTopLeftInner, rect.Left + 1, rect.Top + 1, rect.Right - 3, rect.Top + 1);
5790                         }
5791                         
5792                         if ((sides & Border3DSide.Right) != 0) {
5793                                 graphics.DrawLine (penBottomRight, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
5794                                 if ((rect.Width > 3) && inner)
5795                                         graphics.DrawLine (penBottomRightInner, rect.Right - 2, rect.Top + 1, rect.Right - 2, rect.Bottom - 2);
5796                         }
5797                         
5798                         if ((sides & Border3DSide.Bottom) != 0) {
5799                                 graphics.DrawLine (penBottomRight, rect.Left, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
5800                                 if ((rect.Height > 3) && inner)
5801                                         graphics.DrawLine (penBottomRightInner, rect.Left + 1, rect.Bottom - 2, rect.Right - 2, rect.Bottom - 2);
5802                         }
5803                 }
5804
5805                 public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
5806                 {
5807                         CPDrawButtonInternal (dc, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLight);
5808                 }
5809
5810                 private void CPDrawButtonInternal (Graphics dc, Rectangle rectangle, ButtonState state, Pen DarkPen, Pen NormalPen, Pen LightPen)
5811                 {
5812                         // sadly enough, the rectangle gets always filled with a hatchbrush
5813                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
5814                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
5815                                                                                  ColorControl.G, ColorControl.B),
5816                                                                  ColorControl),
5817                                           rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2);
5818                         
5819                         if ((state & ButtonState.All) == ButtonState.All || ((state & ButtonState.Checked) == ButtonState.Checked && (state & ButtonState.Flat) == ButtonState.Flat)) {
5820                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
5821                                 
5822                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
5823                         } else
5824                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
5825                                 dc.DrawRectangle (SystemPens.ControlDark, rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1);
5826                         } else
5827                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
5828                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLight, ColorControl), rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4);
5829                                 
5830                                 Pen pen = DarkPen;
5831                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
5832                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
5833                                 
5834                                 pen = NormalPen;
5835                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
5836                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
5837                                 
5838                                 pen = LightPen;
5839                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
5840                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
5841                         } else
5842                         if (((state & ButtonState.Pushed) == ButtonState.Pushed) && ((state & ButtonState.Normal) == ButtonState.Normal)) {
5843                                 Pen pen = DarkPen;
5844                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
5845                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y, rectangle.Right - 2, rectangle.Y);
5846                                 
5847                                 pen = NormalPen;
5848                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 3);
5849                                 dc.DrawLine (pen, rectangle.X + 2, rectangle.Y + 1, rectangle.Right - 3, rectangle.Y + 1);
5850                                 
5851                                 pen = LightPen;
5852                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 2, rectangle.Bottom - 1);
5853                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1);
5854                         } else
5855                         if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Normal) == ButtonState.Normal)) {
5856                                 Pen pen = LightPen;
5857                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.Right - 2, rectangle.Y);
5858                                 dc.DrawLine (pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 2);
5859                                 
5860                                 pen = NormalPen;
5861                                 dc.DrawLine (pen, rectangle.X + 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2);
5862                                 dc.DrawLine (pen, rectangle.Right - 2, rectangle.Y + 1, rectangle.Right - 2, rectangle.Bottom - 3);
5863                                 
5864                                 pen = DarkPen;
5865                                 dc.DrawLine (pen, rectangle.X, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 1);
5866                                 dc.DrawLine (pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 2);
5867                         }
5868                 }
5869
5870
5871                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
5872                         Rectangle       captionRect;
5873                         int                     lineWidth;
5874
5875                         CPDrawButtonInternal (graphics, rectangle, state, SystemPens.ControlDarkDark, SystemPens.ControlDark, SystemPens.ControlLightLight);
5876
5877                         if (rectangle.Width<rectangle.Height) {
5878                                 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
5879                         } else {
5880                                 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
5881                         }
5882
5883                         if ((state & ButtonState.Pushed)!=0) {
5884                                 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
5885                         }
5886
5887                         /* Make sure we've got at least a line width of 1 */
5888                         lineWidth=Math.Max(1, captionRect.Width/7);
5889
5890                         switch(button) {
5891                         case CaptionButton.Close: {
5892                                 Pen     pen;
5893
5894                                 if ((state & ButtonState.Inactive)!=0) {
5895                                         pen = ResPool.GetSizedPen (ColorControlLight, lineWidth);
5896                                         DrawCaptionHelper(graphics, ColorControlLight, pen, lineWidth, 1, captionRect, button);
5897
5898                                         pen = ResPool.GetSizedPen (ColorControlDark, lineWidth);
5899                                         DrawCaptionHelper(graphics, ColorControlDark, pen, lineWidth, 0, captionRect, button);
5900                                         return;
5901                                 } else {
5902                                         pen = ResPool.GetSizedPen (ColorControlText, lineWidth);
5903                                         DrawCaptionHelper(graphics, ColorControlText, pen, lineWidth, 0, captionRect, button);
5904                                         return;
5905                                 }
5906                         }
5907
5908                         case CaptionButton.Help:
5909                         case CaptionButton.Maximize:
5910                         case CaptionButton.Minimize:
5911                         case CaptionButton.Restore: {
5912                                 if ((state & ButtonState.Inactive)!=0) {
5913                                         DrawCaptionHelper(graphics, ColorControlLight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
5914
5915                                         DrawCaptionHelper(graphics, ColorControlDark, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
5916                                         return;
5917                                 } else {
5918                                         DrawCaptionHelper(graphics, ColorControlText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
5919                                         return;
5920                                 }
5921                         }
5922                         }
5923                 }
5924
5925                 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
5926                 {
5927                         Pen check_pen = SystemPens.ControlDarkDark;
5928                         
5929                         Rectangle cb_rect = new Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
5930                         
5931                         if ((state & ButtonState.All) == ButtonState.All) {
5932                                 cb_rect.Width -= 2;
5933                                 cb_rect.Height -= 2;
5934                                 
5935                                 dc.FillRectangle (SystemBrushes.Control, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
5936                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
5937                                 
5938                                 check_pen = SystemPens.ControlDark;
5939                         } else
5940                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
5941                                 cb_rect.Width -= 2;
5942                                 cb_rect.Height -= 2;
5943                                 
5944                                 dc.FillRectangle (SystemBrushes.ControlLight, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
5945                                 dc.DrawRectangle (SystemPens.ControlDark, cb_rect.X, cb_rect.Y, cb_rect.Width - 1, cb_rect.Height - 1);
5946                         } else {
5947                                 cb_rect.Width -= 1;
5948                                 cb_rect.Height -= 1;
5949                                 
5950                                 int check_box_visible_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width : cb_rect.Height;
5951                                 
5952                                 int x_pos = Math.Max (0, cb_rect.X + (cb_rect.Width / 2) - check_box_visible_size / 2);
5953                                 int y_pos = Math.Max (0, cb_rect.Y + (cb_rect.Height / 2) - check_box_visible_size / 2);
5954                                 
5955                                 Rectangle rect = new Rectangle (x_pos, y_pos, check_box_visible_size, check_box_visible_size);
5956                                 
5957                                 if (((state & ButtonState.Pushed) == ButtonState.Pushed) || ((state & ButtonState.Inactive) == ButtonState.Inactive)) {
5958                                         dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50,
5959                                                                                  Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
5960                                                                                                  ColorControl.G, ColorControl.B),
5961                                                                                  ColorControl), rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
5962                                 } else
5963                                         dc.FillRectangle (SystemBrushes.ControlLightLight, rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3);
5964                                 
5965                                 Pen pen = SystemPens.ControlDark;
5966                                 dc.DrawLine (pen, rect.X, rect.Y, rect.X, rect.Bottom - 1);
5967                                 dc.DrawLine (pen, rect.X + 1, rect.Y, rect.Right - 1, rect.Y);
5968                                 
5969                                 pen = SystemPens.ControlDarkDark;
5970                                 dc.DrawLine (pen, rect.X + 1, rect.Y + 1, rect.X + 1, rect.Bottom - 2);
5971                                 dc.DrawLine (pen, rect.X + 2, rect.Y + 1, rect.Right - 2, rect.Y + 1);
5972                                 
5973                                 pen = SystemPens.ControlLight;
5974                                 dc.DrawLine (pen, rect.Right, rect.Y, rect.Right, rect.Bottom);
5975                                 dc.DrawLine (pen, rect.X, rect.Bottom, rect.Right, rect.Bottom);
5976                                 
5977                                 // oh boy, matching ms is like fighting against windmills
5978                                 using (Pen h_pen = new Pen (ResPool.GetHatchBrush (HatchStyle.Percent50,
5979                                                                                    Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
5980                                                                                                    ColorControl.G, ColorControl.B), ColorControl))) {
5981                                         dc.DrawLine (h_pen, rect.X + 1, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
5982                                         dc.DrawLine (h_pen, rect.Right - 1, rect.Y + 1, rect.Right - 1, rect.Bottom - 1);
5983                                 }
5984                                 
5985                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
5986                                         check_pen = SystemPens.ControlDark;
5987                         }
5988                         
5989                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
5990                                 int check_size = (cb_rect.Height > cb_rect.Width) ? cb_rect.Width / 2: cb_rect.Height / 2;
5991                                 
5992                                 if (check_size < 7) {
5993                                         int lineWidth = Math.Max (3, check_size / 3);
5994                                         int Scale = Math.Max (1, check_size / 9);
5995                                         
5996                                         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, 
5997                                                                         check_size, check_size);
5998                                         
5999                                         for (int i = 0; i < lineWidth; i++) {
6000                                                 dc.DrawLine (check_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * Scale, rect.Top + lineWidth + 2 * Scale + i);
6001                                                 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);
6002                                         }
6003                                 } else {
6004                                         int lineWidth = Math.Max (3, check_size / 3) + 1;
6005                                         
6006                                         int x_half = cb_rect.Width / 2;
6007                                         int y_half = cb_rect.Height / 2;
6008                                         
6009                                         Rectangle rect = new Rectangle (cb_rect.X + x_half - (check_size / 2) - 1, cb_rect.Y + y_half - (check_size / 2), 
6010                                                                         check_size, check_size);
6011                                         
6012                                         int gradient_left = check_size / 3;
6013                                         int gradient_right = check_size - gradient_left - 1;
6014                                         
6015                                         
6016                                         for (int i = 0; i < lineWidth; i++) {
6017                                                 dc.DrawLine (check_pen, rect.X, rect.Bottom - 1 - gradient_left - i, rect.X + gradient_left, rect.Bottom - 1 - i);
6018                                                 dc.DrawLine (check_pen, rect.X + gradient_left, rect.Bottom - 1 - i, rect.Right - 1, rect.Bottom - i  - 1 - gradient_right);
6019                                         }
6020                                 }
6021                         }
6022                 }
6023
6024                 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
6025                         Point[]                 arrow = new Point[3];
6026                         Point                           P1;
6027                         Point                           P2;
6028                         Point                           P3;
6029                         int                             centerX;
6030                         int                             centerY;
6031                         int                             shiftX;
6032                         int                             shiftY;
6033                         Rectangle               rect;
6034
6035                         if ((state & ButtonState.Checked)!=0) {
6036                                 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorControlLightLight, ColorControlLight),rectangle);                              
6037                         }
6038
6039                         if ((state & ButtonState.Flat)!=0) {
6040                                 ControlPaint.DrawBorder(graphics, rectangle, ColorControlDark, ButtonBorderStyle.Solid);
6041                         } else {
6042                                 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
6043                                         // this needs to render like a pushed button - jba
6044                                         // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6045                                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6046                                         graphics.DrawRectangle (SystemPens.ControlDark, trace_rectangle);
6047                                 } else {
6048                                         CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorControl);
6049                                 }
6050                         }
6051
6052                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
6053                         centerX=rect.Left+rect.Width/2;
6054                         centerY=rect.Top+rect.Height/2;
6055                         shiftX=Math.Max(1, rect.Width/8);
6056                         shiftY=Math.Max(1, rect.Height/8);
6057
6058                         if ((state & ButtonState.Pushed)!=0) {
6059                                 shiftX++;
6060                                 shiftY++;
6061                         }
6062
6063                         rect.Y-=shiftY;
6064                         centerY-=shiftY;
6065                         P1=new Point(rect.Left, centerY);
6066                         P2=new Point(rect.Right, centerY);
6067                         P3=new Point(centerX, rect.Bottom);
6068
6069                         arrow[0]=P1;
6070                         arrow[1]=P2;
6071                         arrow[2]=P3;
6072                         
6073                         /* Draw the arrow */
6074                         if ((state & ButtonState.Inactive)!=0) {
6075                                 /* Move away from the shadow */
6076                                 arrow[0].X += 1;        arrow[0].Y += 1;
6077                                 arrow[1].X += 1;        arrow[1].Y += 1;
6078                                 arrow[2].X += 1;        arrow[2].Y += 1;
6079                                 
6080                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
6081
6082                                 arrow[0]=P1;
6083                                 arrow[1]=P2;
6084                                 arrow[2]=P3;
6085
6086                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
6087                         } else {
6088                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
6089                         }
6090                 }
6091
6092
6093                 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds)
6094                 {
6095                         Pen                     pen     = Pens.Black;
6096                         Rectangle       rect    = new Rectangle (bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);      // Dunno why, but MS does it that way, too
6097                         int                     X;
6098                         int                     Y;
6099                         
6100                         graphics.FillRectangle (SystemBrushes.ControlLightLight, rect);
6101                         graphics.DrawRectangle (pen, rect);
6102                         
6103                         X = rect.X + rect.Width / 2;
6104                         Y = rect.Y + rect.Height / 2;
6105                         
6106                         /* Draw the cross */
6107                         graphics.DrawLine (pen, X, rect.Y + 2, X, rect.Bottom - 2);
6108                         graphics.DrawLine (pen, rect.X + 2, Y, rect.Right - 2, Y);
6109                         
6110                         /* Draw 'arrows' for vertical lines */
6111                         graphics.DrawLine (pen, X - 1, rect.Y + 3, X + 1, rect.Y + 3);
6112                         graphics.DrawLine (pen, X - 1, rect.Bottom - 3, X + 1, rect.Bottom - 3);
6113                         
6114                         /* Draw 'arrows' for horizontal lines */
6115                         graphics.DrawLine (pen, rect.X + 3, Y - 1, rect.X + 3, Y + 1);
6116                         graphics.DrawLine (pen, rect.Right - 3, Y - 1, rect.Right - 3, Y + 1);
6117                 }
6118
6119                 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
6120                         // make a rectange to trace around border of the button
6121                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6122                         
6123                         Color outerColor = foreColor;
6124                         // adjust focus color according to the flatstyle
6125                         if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
6126                                 outerColor = (backColor.ToArgb () == ColorControl.ToArgb ()) ? ControlPaint.Dark(ColorControl) : ColorControlText;                              
6127                         }
6128                         
6129                         // draw the outer rectangle
6130                         graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);                  
6131                         
6132                         // draw the inner rectangle                                             
6133                         if (button.FlatStyle == FlatStyle.Popup) {
6134                                 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
6135                         } else {
6136                                 // draw a flat inner rectangle
6137                                 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
6138                                 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));                               
6139                         }
6140                 }
6141                 
6142                 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
6143                 {       
6144                         // make a rectange to trace around border of the button
6145                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
6146                         
6147 #if NotUntilCairoIsFixed
6148                         Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6149                         DashStyle oldStyle; // used for caching old penstyle
6150                         Pen pen = ResPool.GetPen (colorBackInverted);
6151
6152                         oldStyle = pen.DashStyle; 
6153                         pen.DashStyle = DashStyle.Dot;
6154
6155                         graphics.DrawRectangle (pen, trace_rectangle);
6156                         pen.DashStyle = oldStyle;
6157 #else
6158                         CPDrawFocusRectangle(graphics, trace_rectangle, Color.Wheat, backColor);
6159 #endif
6160                 }
6161                                 
6162
6163                 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) 
6164                 {                       
6165                         Rectangle rect = rectangle;
6166                         Pen pen;
6167                         HatchBrush brush;
6168                                 
6169                         if (backColor.GetBrightness () >= 0.5) {
6170                                 foreColor = Color.Transparent;
6171                                 backColor = Color.Black;
6172                                 
6173                         } else {
6174                                 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
6175                                 foreColor = Color.Black;
6176                         }
6177                                                 
6178                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
6179                         pen = new Pen (brush, 1);
6180                                                 
6181                         rect.Width--;
6182                         rect.Height--;                  
6183                         
6184                         graphics.DrawRectangle (pen, rect);
6185                         pen.Dispose ();
6186                 }
6187                 
6188                 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled)
6189                 {
6190                         Brush   sb;
6191                         Pen pen;
6192                         
6193                         if (primary == true) {
6194                                 pen = Pens.Black;
6195                                 if (enabled == true) {
6196                                         sb = Brushes.White;
6197                                 } else {
6198                                         sb = SystemBrushes.Control;
6199                                 }
6200                         } else {
6201                                 pen = Pens.White;
6202                                 if (enabled == true) {
6203                                         sb = Brushes.Black;
6204                                 } else {
6205                                         sb = SystemBrushes.Control;
6206                                 }
6207                         }
6208                         graphics.FillRectangle (sb, rectangle);
6209                         graphics.DrawRectangle (pen, rectangle);                        
6210                 }
6211
6212
6213                 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
6214                         Color   foreColor;
6215                         int     h;
6216                         int     b;
6217                         int     s;
6218
6219                         ControlPaint.Color2HBS(backColor, out h, out b, out s);
6220                         
6221                         if (b>127) {
6222                                 foreColor=Color.Black;
6223                         } else {
6224                                 foreColor=Color.White;
6225                         }
6226
6227                         // still not perfect. it seems that ms calculates the position of the first dot or line
6228
6229                         using (Pen pen = new Pen (foreColor)) {
6230                                 pen.DashPattern = new float [] {1.0f, pixelsBetweenDots.Width - 1};
6231                                 
6232                                 for (int y = area.Top; y < area.Bottom; y += pixelsBetweenDots.Height)
6233                                         graphics.DrawLine (pen, area.X, y, area.Right - 1, y);
6234                         }
6235                 }
6236
6237                 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
6238                         /*
6239                                 Microsoft seems to ignore the background and simply make
6240                                 the image grayscale. At least when having > 256 colors on
6241                                 the display.
6242                         */
6243                         
6244                         if (imagedisabled_attributes == null) {                         
6245                                 imagedisabled_attributes = new ImageAttributes ();
6246                                 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
6247                                           // This table would create a perfect grayscale image, based on luminance
6248                                           //                            new float[]{0.3f,0.3f,0.3f,0,0},
6249                                           //                            new float[]{0.59f,0.59f,0.59f,0,0},
6250                                           //                            new float[]{0.11f,0.11f,0.11f,0,0},
6251                                           //                            new float[]{0,0,0,1,0,0},
6252                                           //                            new float[]{0,0,0,0,1,0},
6253                                           //                            new float[]{0,0,0,0,0,1}
6254                 
6255                                           // This table generates a image that is grayscaled and then
6256                                           // brightened up. Seems to match MS close enough.
6257                                           new float[]{0.2f,0.2f,0.2f,0,0},
6258                                           new float[]{0.41f,0.41f,0.41f,0,0},
6259                                           new float[]{0.11f,0.11f,0.11f,0,0},
6260                                           new float[]{0.15f,0.15f,0.15f,1,0,0},
6261                                           new float[]{0.15f,0.15f,0.15f,0,1,0},
6262                                           new float[]{0.15f,0.15f,0.15f,0,0,1}
6263                                   });
6264                                   
6265                                  imagedisabled_attributes.SetColorMatrix (colorMatrix);
6266                         }
6267                         
6268                         graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
6269                         
6270                 }
6271
6272
6273                 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
6274                         Pen     penBorder;
6275                         Pen     penInside;
6276
6277                         if (primary) {
6278                                 penBorder = ResPool.GetSizedPen (Color.White, 2);
6279                                 penInside = ResPool.GetPen (Color.Black);
6280                         } else {
6281                                 penBorder = ResPool.GetSizedPen (Color.Black, 2);
6282                                 penInside = ResPool.GetPen (Color.White);
6283                         }
6284                         penBorder.Alignment=PenAlignment.Inset;
6285                         penInside.Alignment=PenAlignment.Inset;
6286
6287                         graphics.DrawRectangle(penBorder, rectangle);
6288                         graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
6289                 }
6290
6291
6292                 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph, Color color) {
6293                         Rectangle       rect;
6294                         int                     lineWidth;
6295
6296                         Brush brush = ResPool.GetSolidBrush (color);
6297
6298                         switch(glyph) {
6299                         case MenuGlyph.Arrow: {
6300                                 float height = rectangle.Height * 0.7f;
6301                                 float width  = height / 2.0f;
6302                                 
6303                                 PointF ddCenter = new PointF (rectangle.X + ((rectangle.Width-width) / 2.0f), rectangle.Y + (rectangle.Height / 2.0f));
6304
6305                                 PointF [] vertices = new PointF [3];
6306                                 vertices [0].X = ddCenter.X;
6307                                 vertices [0].Y = ddCenter.Y - (height / 2.0f);
6308                                 vertices [1].X = ddCenter.X;
6309                                 vertices [1].Y = ddCenter.Y + (height / 2.0f);
6310                                 vertices [2].X = ddCenter.X + width + 0.1f;
6311                                 vertices [2].Y = ddCenter.Y;
6312                                 
6313                                 graphics.FillPolygon (brush, vertices);
6314
6315                                 return;
6316                         }
6317
6318                         case MenuGlyph.Bullet: {
6319                                 
6320                                 lineWidth=Math.Max(2, rectangle.Width/3);
6321                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
6322                                 
6323                                 graphics.FillEllipse(brush, rect);
6324                                 
6325                                 return;
6326                         }
6327
6328                         case MenuGlyph.Checkmark: {
6329                                 
6330                                 Pen pen = ResPool.GetPen (color);
6331                                 lineWidth = Math.Max (2, rectangle.Width / 6);
6332                                 rect = new Rectangle(rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height- lineWidth * 2);
6333
6334                                 int Scale = Math.Max (1, rectangle.Width / 12);
6335                                 int top = (rect.Y + lineWidth + ((rect.Height - ((2 * Scale) + lineWidth)) / 2));
6336
6337                                 for (int i=0; i<lineWidth; i++) {
6338                                         graphics.DrawLine (pen, rect.Left+lineWidth/2, top+i, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i);
6339                                         graphics.DrawLine (pen, rect.Left+lineWidth/2+2*Scale, top+2*Scale+i, rect.Left+lineWidth/2+6*Scale, top-2*Scale+i);
6340                                 }
6341                                 return;
6342                         }
6343                         }
6344
6345                 }
6346
6347                 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
6348                 {
6349                         CPColor cpcolor = ResPool.GetCPColor (ColorControl);
6350                         
6351                         Color dot_color = Color.Black;
6352                         
6353                         Color top_left_outer = Color.Black;
6354                         Color top_left_inner = Color.Black;
6355                         Color bottom_right_outer = Color.Black;
6356                         Color bottom_right_inner = Color.Black;
6357                         
6358                         int ellipse_diameter = (rectangle.Width > rectangle.Height) ? (int)(rectangle.Height  * 0.9f) : (int)(rectangle.Width * 0.9f);
6359                         int radius = ellipse_diameter / 2;
6360                         
6361                         Rectangle rb_rect = new Rectangle (rectangle.X + (rectangle.Width / 2) - radius, rectangle.Y + (rectangle.Height / 2) - radius, ellipse_diameter, ellipse_diameter);
6362                         
6363                         Brush brush = null;
6364                         
6365                         if ((state & ButtonState.All) == ButtonState.All) {
6366                                 brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255),
6367                                                                                                      ColorControl.G, ColorControl.B), ColorControl);
6368                                 dot_color = cpcolor.Dark;
6369                         } else
6370                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
6371                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
6372                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
6373                                 else
6374                                         brush = SystemBrushes.ControlLightLight;
6375                         } else {
6376                                 if (((state & ButtonState.Inactive) == ButtonState.Inactive) || ((state & ButtonState.Pushed) == ButtonState.Pushed))
6377                                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (Clamp (ColorControl.R + 3, 0, 255), ColorControl.G, ColorControl.B), ColorControl);
6378                                 else
6379                                         brush = SystemBrushes.ControlLightLight;
6380                                 
6381                                 top_left_outer = cpcolor.Dark;
6382                                 top_left_inner = cpcolor.DarkDark;
6383                                 bottom_right_outer = cpcolor.Light;
6384                                 bottom_right_inner = Color.Transparent;
6385                                 
6386                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
6387                                         dot_color = cpcolor.Dark;
6388                         }
6389                         
6390                         dc.FillEllipse (brush, rb_rect.X + 1, rb_rect.Y + 1, ellipse_diameter - 1, ellipse_diameter - 1);
6391                         
6392                         int line_width = Math.Max (1, (int)(ellipse_diameter * 0.08f));
6393                         
6394                         dc.DrawArc (ResPool.GetSizedPen (top_left_outer, line_width), rb_rect, 135.0f, 180.0f);
6395                         dc.DrawArc (ResPool.GetSizedPen (top_left_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 135.0f, 180.0f);
6396                         dc.DrawArc (ResPool.GetSizedPen (bottom_right_outer, line_width), rb_rect, 315.0f, 180.0f);
6397                         
6398                         if (bottom_right_inner != Color.Transparent)
6399                                 dc.DrawArc (ResPool.GetSizedPen (bottom_right_inner, line_width), Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
6400                         else
6401                                 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)) {
6402                                         dc.DrawArc (h_pen, Rectangle.Inflate (rb_rect, -line_width, -line_width), 315.0f, 180.0f);
6403                                 }
6404                         
6405                         if ((state & ButtonState.Checked) == ButtonState.Checked) {
6406                                 int inflate = line_width * 4;
6407                                 Rectangle tmp = Rectangle.Inflate (rb_rect, -inflate, -inflate);
6408                                 if (rectangle.Height >  13) {
6409                                         tmp.X += 1;
6410                                         tmp.Y += 1;
6411                                         tmp.Height -= 1;
6412                                         dc.FillEllipse (ResPool.GetSolidBrush (dot_color), tmp);
6413                                 } else {
6414                                         Pen pen = ResPool.GetPen (dot_color);
6415                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2), tmp.Right, tmp.Y + (tmp.Height / 2));
6416                                         dc.DrawLine (pen, tmp.X, tmp.Y + (tmp.Height / 2) + 1, tmp.Right, tmp.Y + (tmp.Height / 2) + 1);
6417                                         
6418                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2), tmp.Y, tmp.X + (tmp.Width / 2), tmp.Bottom);
6419                                         dc.DrawLine (pen, tmp.X + (tmp.Width / 2) + 1, tmp.Y, tmp.X + (tmp.Width / 2) + 1, tmp.Bottom);
6420                                 }
6421                         }
6422                 }
6423
6424                 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
6425
6426                 }
6427
6428
6429                 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
6430
6431                 }
6432
6433
6434                 /* Scroll button: regular button + direction arrow */
6435                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
6436                 {
6437                         DrawScrollButtonPrimitive (dc, area, state);
6438                         
6439                         bool fill_rect = true;
6440                         int offset = 0;
6441                         
6442                         if ((state & ButtonState.Pushed) != 0)
6443                                 offset = 1;
6444                         
6445                         // skip the border
6446                         Rectangle rect = new Rectangle (area.X + 2 + offset, area.Y + 2 + offset, area.Width - 4, area.Height - 4);
6447                         
6448                         Point [] arrow = new Point [3];
6449                         for (int i = 0; i < 3; i++)
6450                                 arrow [i] = new Point ();
6451                         
6452                         Pen pen = SystemPens.ControlText;
6453                         
6454                         if ((state & ButtonState.Inactive) != 0) {
6455                                 pen = SystemPens.ControlDark;
6456                         }
6457                         
6458                         switch (type) {
6459                                 default:
6460                                 case ScrollButton.Down:
6461                                         int x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
6462                                         int y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
6463                                         if (x_middle == 1)
6464                                                 x_middle = 2;
6465                                         
6466                                         int triangle_height;
6467                                         
6468                                         if (rect.Height < 8) {
6469                                                 triangle_height = 2;
6470                                                 fill_rect = false;
6471                                         } else if (rect.Height == 11) {
6472                                                 triangle_height = 3;
6473                                         } else {
6474                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
6475                                         }
6476                                         
6477                                         arrow [0].X = rect.X + x_middle;
6478                                         arrow [0].Y = rect.Y + y_middle + triangle_height / 2;
6479                                         
6480                                         arrow [1].X = arrow [0].X + triangle_height - 1;
6481                                         arrow [1].Y = arrow [0].Y - triangle_height + 1;
6482                                         arrow [2].X = arrow [0].X - triangle_height + 1;
6483                                         arrow [2].Y = arrow [1].Y;
6484                                         
6485                                         dc.DrawPolygon (pen, arrow);
6486                                         
6487                                         if ((state & ButtonState.Inactive) != 0) {
6488                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y + 1);
6489                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X, arrow [1].Y + 1, arrow [0].X + 1, arrow [0].Y);
6490                                         }
6491                                         
6492                                         if (fill_rect) {
6493                                                 for (int i = 0; i < arrow [0].Y - arrow [1].Y; i++) {
6494                                                         dc.DrawLine (pen, arrow [1].X, arrow [1].Y + i, arrow [2].X, arrow [1].Y + i);
6495                                                         arrow [1].X -= 1;
6496                                                         arrow [2].X += 1;
6497                                                 }
6498                                         }
6499                                         break;
6500                                         
6501                                 case ScrollButton.Up:
6502                                         x_middle = (int)Math.Round (rect.Width / 2.0f) - 1;
6503                                         y_middle = (int)Math.Round (rect.Height / 2.0f);
6504                                         if (x_middle == 1)
6505                                                 x_middle = 2;
6506                                         
6507                                         if (y_middle == 1)
6508                                                 y_middle = 2;
6509                                         
6510                                         if (rect.Height < 8) {
6511                                                 triangle_height = 2;
6512                                                 fill_rect = false;
6513                                         } else if (rect.Height == 11) {
6514                                                 triangle_height = 3;
6515                                         } else {
6516                                                 triangle_height = (int)Math.Round (rect.Height / 3.0f);
6517                                         }
6518                                         
6519                                         arrow [0].X = rect.X + x_middle;
6520                                         arrow [0].Y = rect.Y + y_middle - triangle_height / 2;
6521                                         
6522                                         arrow [1].X = arrow [0].X + triangle_height - 1;
6523                                         arrow [1].Y = arrow [0].Y + triangle_height - 1;
6524                                         arrow [2].X = arrow [0].X - triangle_height + 1;
6525                                         arrow [2].Y = arrow [1].Y;
6526                                         
6527                                         dc.DrawPolygon (pen, arrow);
6528                                         
6529                                         if ((state & ButtonState.Inactive) != 0) {
6530                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [1].Y + 1);
6531                                         }
6532                                         
6533                                         if (fill_rect) {
6534                                                 for (int i = 0; i < arrow [1].Y - arrow [0].Y; i++) {
6535                                                         dc.DrawLine (pen, arrow [2].X, arrow [1].Y - i, arrow [1].X, arrow [1].Y - i);
6536                                                         arrow [1].X -= 1;
6537                                                         arrow [2].X += 1;
6538                                                 }
6539                                         }
6540                                         break;
6541                                         
6542                                 case ScrollButton.Left:
6543                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
6544                                         if (y_middle == 1)
6545                                                 y_middle = 2;
6546                                         
6547                                         int triangle_width;
6548                                         
6549                                         if (rect.Width < 8) {
6550                                                 triangle_width = 2;
6551                                                 fill_rect = false;
6552                                         } else if (rect.Width == 11) {
6553                                                 triangle_width = 3;
6554                                         } else {
6555                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
6556                                         }
6557                                         
6558                                         arrow [0].X = rect.Left + triangle_width - 1;
6559                                         arrow [0].Y = rect.Y + y_middle;
6560                                         
6561                                         if (arrow [0].X - 1 == rect.X)
6562                                                 arrow [0].X += 1;
6563                                         
6564                                         arrow [1].X = arrow [0].X + triangle_width - 1;
6565                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
6566                                         arrow [2].X = arrow [1].X;
6567                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
6568                                         
6569                                         dc.DrawPolygon (pen, arrow);
6570                                         
6571                                         if ((state & ButtonState.Inactive) != 0) {
6572                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [1].X + 1, arrow [1].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
6573                                         }
6574                                         
6575                                         if (fill_rect) {
6576                                                 for (int i = 0; i < arrow [2].X - arrow [0].X; i++) {
6577                                                         dc.DrawLine (pen, arrow [2].X - i, arrow [1].Y, arrow [2].X - i, arrow [2].Y);
6578                                                         arrow [1].Y += 1;
6579                                                         arrow [2].Y -= 1;
6580                                                 }
6581                                         }
6582                                         break;
6583                                         
6584                                 case ScrollButton.Right:
6585                                         y_middle = (int)Math.Round (rect.Height / 2.0f) - 1;
6586                                         if (y_middle == 1)
6587                                                 y_middle = 2;
6588                                         
6589                                         if (rect.Width < 8) {
6590                                                 triangle_width = 2;
6591                                                 fill_rect = false;
6592                                         } else if (rect.Width == 11) {
6593                                                 triangle_width = 3;
6594                                         } else {
6595                                                 triangle_width = (int)Math.Round (rect.Width / 3.0f);
6596                                         }
6597                                         
6598                                         arrow [0].X = rect.Right - triangle_width - 1;
6599                                         arrow [0].Y = rect.Y + y_middle;
6600                                         
6601                                         if (arrow [0].X - 1 == rect.X)
6602                                                 arrow [0].X += 1;
6603                                         
6604                                         arrow [1].X = arrow [0].X - triangle_width + 1;
6605                                         arrow [1].Y = arrow [0].Y - triangle_width + 1;
6606                                         arrow [2].X = arrow [1].X;
6607                                         arrow [2].Y = arrow [0].Y + triangle_width - 1;
6608                                         
6609                                         dc.DrawPolygon (pen, arrow);
6610                                         
6611                                         if ((state & ButtonState.Inactive) != 0) {
6612                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X + 1, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y + 1);
6613                                                 dc.DrawLine (SystemPens.ControlLightLight, arrow [0].X, arrow [0].Y + 1, arrow [2].X + 1, arrow [2].Y);
6614                                         }
6615                                         
6616                                         if (fill_rect) {
6617                                                 for (int i = 0; i < arrow [0].X - arrow [1].X; i++) {
6618                                                         dc.DrawLine (pen, arrow [2].X + i, arrow [1].Y, arrow [2].X + i, arrow [2].Y);
6619                                                         arrow [1].Y += 1;
6620                                                         arrow [2].Y -= 1;
6621                                                 }
6622                                         }
6623                                         break;
6624                         }
6625                 }
6626
6627                 public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
6628                         Color backColor) {
6629
6630                 }
6631
6632
6633                 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds)
6634                 {
6635                         Pen pen_dark = ResPool.GetPen(ControlPaint.Dark(backColor));
6636                         Pen pen_light_light = ResPool.GetPen(ControlPaint.LightLight(backColor));
6637                         
6638                         for (int i = 2; i < bounds.Width - 2; i += 4) {
6639                                 dc.DrawLine (pen_light_light, bounds.X + i, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i - 1);
6640                                 dc.DrawLine (pen_dark, bounds.X + i + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i);
6641                                 dc.DrawLine (pen_dark, bounds.X + i + 2, bounds.Bottom - 2, bounds.Right - 1, bounds.Y + i + 1);
6642                         }
6643                 }
6644
6645                 private void DrawStringDisabled20 (Graphics g, string s, Font font, Rectangle layoutRectangle, Color color, TextFormatFlags flags, bool useDrawString)
6646                 {
6647                         CPColor cpcolor = ResPool.GetCPColor (color);
6648
6649                         layoutRectangle.Offset (1, 1);
6650                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.LightLight, flags, useDrawString);
6651
6652                         layoutRectangle.Offset (-1, -1);
6653                         TextRenderer.DrawTextInternal (g, s, font, layoutRectangle, cpcolor.Dark, flags, useDrawString);
6654                 }
6655
6656                 public  override void CPDrawStringDisabled (Graphics dc, string s, Font font, Color color, RectangleF layoutRectangle, StringFormat format)
6657                 {
6658                         CPColor cpcolor = ResPool.GetCPColor (color);
6659                         
6660                         dc.DrawString (s, font, ResPool.GetSolidBrush(cpcolor.LightLight), 
6661                                        new RectangleF(layoutRectangle.X + 1, layoutRectangle.Y + 1, layoutRectangle.Width, layoutRectangle.Height),
6662                                        format);
6663                         dc.DrawString (s, font, ResPool.GetSolidBrush (cpcolor.Dark), layoutRectangle, format);
6664                 }
6665
6666                 private static void DrawBorderInternal(Graphics graphics, int startX, int startY, int endX, int endY,
6667                         int width, Color color, ButtonBorderStyle style, Border3DSide side) {
6668
6669                         Pen pen = null;
6670
6671                         switch (style) {
6672                         case ButtonBorderStyle.Solid:
6673                         case ButtonBorderStyle.Inset:
6674                         case ButtonBorderStyle.Outset:
6675                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Solid);
6676                                         break;
6677                         case ButtonBorderStyle.Dashed:
6678                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dash);
6679                                         break;
6680                         case ButtonBorderStyle.Dotted:
6681                                         pen = ThemeEngine.Current.ResPool.GetDashPen (color, DashStyle.Dot);
6682                                         break;
6683                         default:
6684                         case ButtonBorderStyle.None:
6685                                         return;
6686                         }
6687
6688                         switch(style) {
6689                         case ButtonBorderStyle.Outset: {
6690                                 Color           colorGrade;
6691                                 int             hue, brightness, saturation;
6692                                 int             brightnessSteps;
6693                                 int             brightnessDownSteps;
6694
6695                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
6696
6697                                 brightnessDownSteps=brightness/width;
6698                                 if (brightness>127) {
6699                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
6700                                 } else {
6701                                         brightnessSteps=(127-brightness)/width;
6702                                 }
6703
6704                                 for (int i=0; i<width; i++) {
6705                                         switch(side) {
6706                                         case Border3DSide.Left: {
6707                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
6708                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6709                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
6710                                                 break;
6711                                         }
6712
6713                                         case Border3DSide.Right: {
6714                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
6715                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6716                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
6717                                                 break;
6718                                         }
6719
6720                                         case Border3DSide.Top: {
6721                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
6722                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6723                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
6724                                                 break;
6725                                         }
6726
6727                                         case Border3DSide.Bottom: {
6728                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
6729                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6730                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
6731                                                 break;
6732                                         }
6733                                         }
6734                                 }
6735                                 break;
6736                         }
6737
6738                         case ButtonBorderStyle.Inset: {
6739                                 Color           colorGrade;
6740                                 int             hue, brightness, saturation;
6741                                 int             brightnessSteps;
6742                                 int             brightnessDownSteps;
6743
6744                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
6745
6746                                 brightnessDownSteps=brightness/width;
6747                                 if (brightness>127) {
6748                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
6749                                 } else {
6750                                         brightnessSteps=(127-brightness)/width;
6751                                 }
6752
6753                                 for (int i=0; i<width; i++) {
6754                                         switch(side) {
6755                                         case Border3DSide.Left: {
6756                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
6757                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6758                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
6759                                                 break;
6760                                         }
6761
6762                                         case Border3DSide.Right: {
6763                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
6764                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6765                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
6766                                                 break;
6767                                         }
6768
6769                                         case Border3DSide.Top: {
6770                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
6771                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6772                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
6773                                                 break;
6774                                         }
6775
6776                                         case Border3DSide.Bottom: {
6777                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
6778                                                 pen = ThemeEngine.Current.ResPool.GetPen (colorGrade);
6779                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
6780                                                 break;
6781                                         }
6782                                         }
6783                                 }
6784                                 break;
6785                         }
6786
6787                                 /*
6788                                         I decided to have the for-loop duplicated for speed reasons;
6789                                         that way we only have to switch once (as opposed to have the
6790                                         for-loop around the switch)
6791                                 */
6792                         default: {
6793                                 switch(side) {
6794                                 case Border3DSide.Left: {
6795                                         for (int i=0; i<width; i++) {
6796                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
6797                                         }
6798                                         break;
6799                                 }
6800
6801                                 case Border3DSide.Right: {
6802                                         for (int i=0; i<width; i++) {
6803                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
6804                                         }
6805                                         break;
6806                                 }
6807
6808                                 case Border3DSide.Top: {
6809                                         for (int i=0; i<width; i++) {
6810                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
6811                                         }
6812                                         break;
6813                                 }
6814
6815                                 case Border3DSide.Bottom: {
6816                                         for (int i=0; i<width; i++) {
6817                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
6818                                         }
6819                                         break;
6820                                 }
6821                                 }
6822                                 break;
6823                         }
6824                         }
6825                 }
6826
6827                 /*
6828                         This function actually draws the various caption elements.
6829                         This way we can scale them nicely, no matter what size, and they
6830                         still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
6831                 */
6832
6833                 private void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
6834                         switch(button) {
6835                         case CaptionButton.Close: {
6836                                 if (lineWidth<2) {
6837                                         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);
6838                                         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);
6839                                 }
6840
6841                                 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
6842                                 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
6843                                 return;
6844                         }
6845
6846                         case CaptionButton.Help: {
6847                                 StringFormat    sf = new StringFormat();                                
6848                                 Font                            font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
6849
6850                                 sf.Alignment=StringAlignment.Center;
6851                                 sf.LineAlignment=StringAlignment.Center;
6852
6853
6854                                 graphics.DrawString("?", font, ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
6855
6856                                 sf.Dispose();                           
6857                                 font.Dispose();
6858
6859                                 return;
6860                         }
6861
6862                         case CaptionButton.Maximize: {
6863                                 /* Top 'caption bar' line */
6864                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
6865                                         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);
6866                                 }
6867
6868                                 /* Left side line */
6869                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6870                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
6871                                 }
6872
6873                                 /* Right side line */
6874                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6875                                         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);
6876                                 }
6877
6878                                 /* Bottom line */
6879                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6880                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
6881                                 }
6882                                 return;
6883                         }
6884
6885                         case CaptionButton.Minimize: {
6886                                 /* Bottom line */
6887                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
6888                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
6889                                 }
6890                                 return;
6891                         }
6892
6893                         case CaptionButton.Restore: {
6894                                 /** First 'window' **/
6895                                 /* Top 'caption bar' line */
6896                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
6897                                         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);
6898                                 }
6899
6900                                 /* Left side line */
6901                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6902                                         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);
6903                                 }
6904
6905                                 /* Right side line */
6906                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6907                                         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);
6908                                 }
6909
6910                                 /* Bottom line */
6911                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6912                                         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);
6913                                 }
6914
6915                                 /** Second 'window' **/
6916                                 /* Top 'caption bar' line */
6917                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
6918                                         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);
6919                                 }
6920
6921                                 /* Left side line */
6922                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6923                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
6924                                 }
6925
6926                                 /* Right side line */
6927                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6928                                         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);
6929                                 }
6930
6931                                 /* Bottom line */
6932                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
6933                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
6934                                 }
6935
6936                                 return;
6937                         }
6938
6939                         }
6940                 }
6941
6942                 /* Generic scroll button */
6943                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
6944                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
6945                                 dc.FillRectangle (SystemBrushes.Control, area.X + 1,
6946                                         area.Y + 1, area.Width - 2 , area.Height - 2);
6947
6948                                 dc.DrawRectangle (SystemPens.ControlDark, area.X,
6949                                         area.Y, area.Width, area.Height);
6950
6951                                 return;
6952                         }                       
6953         
6954                         Brush sb_control = SystemBrushes.Control;
6955                         Brush sb_lightlight = SystemBrushes.ControlLightLight;
6956                         Brush sb_dark = SystemBrushes.ControlDark;
6957                         Brush sb_darkdark = SystemBrushes.ControlDarkDark;
6958                         
6959                         dc.FillRectangle (sb_control, area.X, area.Y, area.Width, 1);
6960                         dc.FillRectangle (sb_control, area.X, area.Y, 1, area.Height);
6961
6962                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 1, area.Width - 1, 1);
6963                         dc.FillRectangle (sb_lightlight, area.X + 1, area.Y + 2, 1,
6964                                 area.Height - 4);
6965                         
6966                         dc.FillRectangle (sb_dark, area.X + 1, area.Y + area.Height - 2,
6967                                 area.Width - 2, 1);
6968
6969                         dc.FillRectangle (sb_darkdark, area.X, area.Y + area.Height -1,
6970                                 area.Width , 1);
6971
6972                         dc.FillRectangle (sb_dark, area.X + area.Width - 2,
6973                                 area.Y + 1, 1, area.Height -3);
6974
6975                         dc.FillRectangle (sb_darkdark, area.X + area.Width -1,
6976                                 area.Y, 1, area.Height - 1);
6977
6978                         dc.FillRectangle (sb_control, area.X + 2,
6979                                 area.Y + 2, area.Width - 4, area.Height - 4);
6980                         
6981                 }
6982                 
6983                 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
6984                         switch (border_style){
6985                         case BorderStyle.Fixed3D:
6986                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X +area.Width, area.Y);
6987                                 dc.DrawLine (ResPool.GetPen (ColorControlDark), area.X, area.Y, area.X, area.Y + area.Height);
6988                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X , area.Y + area.Height - 1, area.X + area.Width , 
6989                                         area.Y + area.Height - 1);
6990                                 dc.DrawLine (ResPool.GetPen (ColorControlLight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, 
6991                                         area.Y + area.Height);
6992
6993                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
6994                                 dc.DrawLine (ResPool.GetPen (ColorActiveBorder), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
6995                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
6996                                 dc.DrawLine (ResPool.GetPen (ColorControlDarkDark), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
6997                                 break;
6998                         case BorderStyle.FixedSingle:
6999                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
7000                                 break;
7001                         case BorderStyle.None:
7002                         default:
7003                                 break;
7004                         }
7005                         
7006                 }
7007                 #endregion      // ControlPaint
7008
7009
7010         } //class
7011 }