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