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