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