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