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