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