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