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